Skip to main content
 首页 » 编程设计

python之django之有什么方法可以替代抽象类的 ForeignKey

2024年10月25日40leader

我想在 Django 中有一个抽象的 Company 模型,并根据所涉及的公司类型扩展它:

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') 

但这给出了可怕的错误:

main.Profile.company: (fields.E300) Field defines a relation with model 'Company', which is either not installed, or is abstract.

所以我想我想做的事无法完成。我看到 contenttypes框架可用于此目的,如 this 中的回答问题。我的问题是,我不希望 company 字段指向任何 模型,而只是指向 Company 模型的子类。

还有什么我可以用于此目的的吗?

请您参考如下方法:

ForeignKey 不能直接引用抽象模型的原因是从抽象模型继承的各个模型实际上在数据库中有自己的表。

外键只是引用相关表中 id 的整数,因此如果外键与抽象模型相关,则会产生歧义。例如,可能有一个 Buyer 和 Seller 实例,每个实例的 id 都是 1,而经理不知道要加载哪个。

使用 generic relation通过同时记住您在关系中谈论的模型来解决这个问题。

它不需要任何额外的模型,它只是使用一个额外的列。

例子-

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>