django - каковы альтернативы использованию иностранного ключа для абстрактного класса?
Я хочу иметь абстрактную Company
модель в Django и расширять ее в зависимости от типа вовлеченной компании:
class Company(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Meta:
abstract = True
class Buyer(Company):
# Buyer fields..
pass
class Seller(Company):
# Seller fields...
pass
Каждый пользователь в системе связан с компанией, поэтому я хочу добавить следующее в профиль пользователя:
company = models.ForeignKey('Company')
Но это дает страшную ошибку:
Главная.Профиль.компания: (поля.E300) поле определяет отношение с модель 'компания', которая либо не установлена, либо является абстрактной.
Итак, я представляю, что я пытаюсь сделать. сделать ничего нельзя. Я увидел, что для этой цели может быть использована структураcontenttypes , как ответ на этот вопрос. Моя проблема с этим заключается в том, что я не хочу, чтобы поле company
указывало на любую модель, а только подклассы модели Company
.
1 ответ:
Причина, по которой
Внешние ключи-это просто целые числа, ссылающиеся на идентификатор из связанной таблицы, поэтому неоднозначность будет создана, если внешний ключ связан с абстрактной моделью. Например, может быть экземплярForeignKey
не может ссылаться непосредственно на абстрактную модель, заключается в том, что отдельные модели, наследуемые от абстрактной модели, фактически имеют свои собственные таблицы в базе данных.Buyer
иSeller
с идентификатором 1, и менеджер не будет знать, какой из них загружать.Используя a родовое отношение решает эту проблему, также вспоминая, о какой модели вы говорите в отношении.
Он не требует никаких дополнительных моделей, он просто использует один дополнительный столбец.Пример -
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey class Foo(models.Model): company_type = models.ForeignKey(ContentType) company_id = models.PositiveIntegerField() company = GenericForeignKey('company_type', 'company_id')
А затем -
>>> seller = Seller.objects.create() >>> buyer = Buyer.objects.create() >>> >>> foo1 = Foo.objects.create(company = seller) >>> foo2 = Foo.objects.create(company = buyer) >>> >>> foo1.company <Seller: Seller object> >>> foo2.company <Buyer: Buyer object>