3

Предположим, что существует абстрактная модель CarOwner: тогда как Person или Business может быть CarOwner. Кроме того, автомобиль с определенным VIN может принадлежать (относится) к Лицу или Бизнесу, но не к обоим (взаимоисключающий случай). В самом конце следующего кода я представил две возможности (см. Комментарии в коде «# 1. ДОЛЖЕН Я ИМЕЕТ ЭТО?» И «№ 2. ... ИЛИ ДОЛЖЕН ИМЕТЬ ЭТО?»). В первой возможности отношения «много-к-одному» устанавливаются в абстрактной модели, и я не уверен, что это правильный путь. Во втором случае устанавливаются две связи, и я не уверен, что это правильно, особенно неясно, как сделать их взаимоисключающими. Итак, какой из них прав, и если ни один из них, пожалуйста, не дайте правильного ответа, если сможете. Благодарю.отношение модели Django к нескольким моделям

class CarOwner(models.Model): 
    location = models.CharField(max_length=50, blank=True) 

    class Meta: 
     abstract = True 

class Person(CarOwner): 
    name = models.CharField(max_length=50, blank=True) 

class Business(CarOwner): 
    business_id = models.CharField(max_length=50, blank=True) 

class Car(models.Model): 
    vin = models.CharField(max_length=50, blank=True) 

    # 1. SHOULD I HAVE THIS??? (CarOwner is abstract) 
    carowner = models.ForeignKey(CarOwner, blank=True, null=True) 

    # 2. ...OR SHOULD I HAVE THIS??? 
    person = models.ForeignKey(Person, blank=True, null=True) 
    business = models.ForeignKey(Business, blank=True, null=True) 

ответ

5

Как jproffitt упоминалось, родовые отношения может быть хорошим решением для вас. В качестве альтернативы вы можете использовать # 2 и сделать его немного более удобным путем создания свойства и добавляя некоторую простую логику к нему:

class Car(models.Model): 
    vin = models.CharField(max_length=50, blank=True) 
    person = models.ForeignKey(Person, blank=True, null=True) 
    business = models.ForeignKey(Business, blank=True, null=True) 

    @property 
    def carowner(self): 
     return self.person or self.business 

    @carowner.setter 
    def carowner(self, obj): 
     if type(obj) == Person: 
      self.person = obj 
      self.business = None 
     elif type(obj) == Business: 
      self.business = obj 
      self.person = None 
     else: 
      raise ValueError("obj parameter must be an object of Business or Person class") 

Однако для запросов вы будете использовать человеку или бизнес.

+0

Спасибо. Таким образом, использование двух ForeignKeys в одной модели действительно разрешено? Из моих прошлых исследований на сайте Django doc я ранее понимал, что это разрешено только для некоторых случаев отношений «многие ко многим». – jazzblue

+0

Конечно, я не уверен, какая часть документации Django может предложить что-то еще. – zaan

3

С CarOwner является абстрактным, вы не можете сделать # 1. Вы могли бы сделать CarOwner конкретным (наследование таблицы db), а затем это сработает, но наследование таблиц приносит свой собственный набор осложнений. Вы можете либо сделать # 2 или использовать общий внешний ключ:

carowner_content_type = models.ForeignKey(ContentType) 
carowner_object_id = models.PositiveIntegerField() 
carowner = generic.GenericForeignKey('carowner_content_type', 'carowner_object_id') 

 Смежные вопросы

  • Нет связанных вопросов^_^