Ссылка от ребенка к родителю в модели Django - PullRequest
1 голос
/ 18 октября 2019

У меня есть модель места:

class Place(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    country = models.CharField(max_length=100, null=True, blank=True)
    postal_code = models.CharField(max_length=100, null=True, blank=True)
    region = models.CharField(max_length=1000, choices=REGION, null=True, blank=True)
    longitude = models.CharField(max_length=20, null=True, blank=True)
    latitude = models.CharField(max_length=20, null=True, blank=True)

    date_created = models.DateTimeField(_('date created'), default=timezone.now)
    date_modified = models.DateTimeField(_('date_modified'), auto_now=True)

Изначально я создаю место для сохранения информации о городе, таком как Сан-Франциско или Нью-Йорк.

Теперь я хочу создать новую модельназывается бар:

class Bar(Place):
    location = models.OneToOneField(Place, verbose_name=_('location'), related_name='bar', blank=True, on_delete=models.PROTECT, parent_link=True)
    date_inception = models.DateField(null=True, blank=True)
    date_closed = models.DateField(null=True, blank=True)

Я бы хотел связать бар с конкретным городом в модели Place. Поэтому я связываю одну строку унаследованной модели с ее родителем. Могу ли я избежать создания модели города и бара, в который должен войти Foreignkey? Это выполнимо? Если да, то как мне это сделать?

1 Ответ

0 голосов
/ 18 октября 2019

Когда вы устанавливаете parent_link=True в OneToOneField, объединенные модели обрабатываются как той же модели при работе с ORM, даже если они являются двумя отдельными таблицами базы данных.

Нет необходимости связывать Bar с конкретным Place;Вы можете использовать модель Bar для одновременного создания экземпляра Bar и экземпляра Place:

bar = Bar.objects.create(name='Blackbird', city='San Fransisco', 
          country='US', date_inception='10-17-2019', ...
      )

Судя по вашим комментариям, я думаю, вы не хотитеэто вообще. Вместо этого, вы, вероятно, хотите иметь отношение ForeignKey между Place и моделью Bar, поскольку в месте (например, в Сан-Франциско) может быть много баров, но у бара может быть только один . place .

Обновление

Исходя из моего понимания ваших комментариев, я бы предложил следующее:

class PlaceMixin(models.Model):
    name = models.CharField(max_length=200, null=True, blank=True)
    longitude = models.CharField(max_length=20, null=True, blank=True)
    latitude = models.CharField(max_length=20, null=True, blank=True)

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        latitude = self.latitude
        longitude = self.longitude
        do_stuff(latitude, longitude)
        super().save()

class Location(PlaceMixin):
    country = models.CharField(max_length=100, null=True, blank=True)
    postal_code = models.CharField(max_length=100, null=True, blank=True)
    region = models.CharField(max_length=1000, choices=REGION, null=True, blank=True)

class Bar(PlaceMixin):
    location = models.ForeignKey(Location, related_name='bars', on_delete=models.CASCADE)

class Store(PlaceMixin):
    location = models.ForeignKey(Location, related_name='stores', on_delete=models.CASCADE)

Теперь вы можете получить доступ как к широте, так и к длине. Place и Location:

>>>location = Location.objects.create(name='San Fransisco', latitude=1, longitude=1)
>>>bar = Bar.objects.create(name='Blackbird', latitude=2, longitude=2, location=location)
>>>
>>>bar.latitude
2
>>>bar.location.latitude
1

Для запроса всех баров в Сан-Франциско:

location = Location.objects.select_related('Bar').get(name='San Fransisco')
bars = location.bars.all()
...