Django 1.9:字段与父模型

时间:2015-12-04 10:56:23

标签: django name-clash multi-table-inheritance django-1.9

我有一些简单的模型,Profile,Certifier和Designer,后者继承自Profile(多表继承)。在Designer中,有一个Certifier的外键。

class Profile(models.Model):
    TYPES = (
        ('admin', _('Administrator')),
        ('certifier', _('Certifier')),
        ('designer', _('Designer'))
    )

    user = models.OneToOneField(User)
    type = models.CharField(max_length=9, choices=TYPES)

    def __str__(self):
        return self.user.username + ' (' + self.type + ')'

class Admin(Profile):
    pass
class Certifier(Profile):
    pass
class Designer(Profile):
    certifier = models.ForeignKey(Certifier)

在Django 1.8中,这种方法很完美,但在1.9中我得到了;

  

django.core.management.base.SystemCheckError:SystemCheckError:系统检查发现了一些问题:

     

错误:

     

check.Designer.certifier :( models.E006)字段'certifier'与模型'check.profile'中的字段'certifier'冲突。

(在这种情况下,Profile.type无关紧要,我只需要它来区分登录的用户配置文件类型)。

check.profile显然没有字段'certifier'。这是一个错误还是我错过了什么?同样的事情发生在另一个项目中。

2 个答案:

答案 0 :(得分:16)

我认为您不应该为该外键关系使用名称验证者,因为类Profile实际上具有certifieradmindesigner字段(尽管通过描述符)根据docs在这种情况下,名字实际上会发生冲突。

from django.contrib.auth.models import User

c = Certifier.objects.create(
    type='admin',
    user=User.objects.latest('date_joined'),
)

p = c.profile_ptr
print(p.certifier) #username (admin)

更改为certifier_field = models.ForeignKey(Certifier)

正如评论中指出的那样,您可以将模型重命名为CertifierProfile,AdminProfile等以避免冲突。

或者您也可以SILENCED_SYSTEM_CHECKS = ['models.E006']settings添加/myFile.xml,但这不是一个好方法。

答案 1 :(得分:9)

您可以指定Profileabstract class。这将阻止支票与您的父字段混淆。

class Meta:
    abstract = True