当前位置:  开发笔记 > 后端 > 正文

Django 1.9:Field与父模型中不存在的字段的字段冲突

如何解决《Django1.9:Field与父模型中不存在的字段的字段冲突》经验,为你挑选了2个好方法。

我有一些简单的模型,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'.这是一个错误还是我错过了什么?同样的事情发生在另一个项目中.



1> Alex Polekha..:

我认为你不应该为那个外键关系使用name certifier,因为类Profile实际上有certifier,admin而且designer根据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


[Django docs](https://docs.djangoproject.com/en/1.9/topics/db/models/#multi-table-inheritance)说你可以从父模型`Profile`转到它的子`Certifier `用`profile.certifier`.定义另一个`certifier`字段是不明确的,因此对1.9进行了检查.如果你真的想,你可以通过添加`SILENCED_SYSTEM_CHECKS = ['models.E006'来[沉默检查](https://docs.djangoproject.com/en/1.9/ref/settings/#silenced-system-checks) ]`到你的设置,但我不推荐这个.
它解决了1.9中的问题,但是,拥有这样的字段名称并不好,特别是因为一切都使用字段名称验证者工作到1.8.
如果你不喜欢`certifier_field`,你可以将模型重命名为`CertifierProfile`,`AdminProfile`等以避免冲突.或者,您可以尝试使用`related_name`设置[父字段](https://docs.djangoproject.com/en/1.8/topics/db/models/#specifying-the-parent-link-field).

2> 小智..:

您可以指定Profile是一个抽象类.这将阻止检查与您的父字段混淆.

class Meta:
    abstract = True

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有