2015-05-30 43 views
1

我想有在Django抽象Company模型,它取决于公司所涉及的类型延伸:django - 将ForeignKey提供给抽象类有哪些选择?

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.

所以我想象我tryi无法完成。我看到contenttypes框架可以用于此目的,如在this问题中回答的那样。我与问题是,我不希望company字段设置为指向任何模式,但只是Company模型的子类。

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

回答

2

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

外键只是引用从相关表中的ID整数,所以如果一个外键关系到一个抽象的模型不确定性将被创建。例如,可能有一个BuyerSeller实例,每个实例的id为1,并且管理器不知道要加载哪个实例。

使用generic relation通过也记住你在谈论的关系哪种模式解决了这个问题。

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

示例 -

from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes import generic 

class Foo(models.Model): 
    company_type = models.ForeignKey(ContentType) 
    company_id = models.PositiveIntegerField() 
    company = generic.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> 
+0

感谢您的回答!在你的例子中,'company'可以指任何*模型,对吧?例如,我也可以让它指向用户模型?我会宁可指定的地方,它应该只指向公司的子类,这样的Django没有让我引用用户。但我想这可以作为验证步骤来完成? – user1496984

+1

当然,检查出[这个答案](http://stackoverflow.com/questions/6335986/how-can-i-restrict-djangos-genericforeignkey-to-a-list-of-models)。基本上你将'limit_choices_to'参数传入'ForeignKey'中。 – metahamza

+0

辉煌,谢谢! – user1496984