Подтвердить что ты не робот

Django 1.9: Полевые столкновения с полем несуществующего поля в родительской модели

У меня есть несколько простых моделей: Profile, Certifier и Designer, два из которых наследуются от Profile (multi table inheritance). В 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" сталкивается с полем "certifier" из модели "check.profile".

(Profile.type не имеет значения в этом случае, мне просто нужно его отличить от зарегистрированных типов профилей пользователя).

check.profile, очевидно, не имеет поля 'certifier'. Это ошибка или мне что-то не хватает? То же самое происходит в другом проекте.

4b9b3361

Ответ 1

Я думаю, что вы не должны использовать сертификат имени для этого отношения внешнего ключа, потому что у класса 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'], но это нехорошо подход.

Ответ 2

Вы можете указать Profile абстрактный класс. Это остановит проверку путаницы с родительскими полями.

class Meta:
    abstract = True