web-dev-qa-db-ja.com

Django 1.9:フィールドが、親モデルに存在しないフィールドのフィールドと衝突します

私はいくつかの単純なモデル、プロファイル、認証者、デザイナーを持っています。後者の2つはプロファイルから継承しています(複数テーブルの継承)。 Designerには、認証者への外部キーがあります。

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には明らかに「認証者」フィールドがありません。これはバグですか、それとも何かを見逃していますか?同じことが別のプロジェクトでも起こります。

24
Jens-Erik Weber

クラスプロファイルには実際には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に追加して、チェックを 沈黙 することもできますが、これは良い方法ではありません。

20
Alex Polekha

Profile抽象クラ​​ス と指定できます。これにより、チェックが親フィールドと混同されなくなります。

class Meta:
    abstract = True
11
mrcai