Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.9: Field clashes with the field of non-existing field in parent model

I have some simple models, Profile, Certifier and Designer, the two latter inheriting from Profile (multi table inheritance). In Designer there’s a foreign key to 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) 

In Django 1.8 this works perfectly, but in 1.9 I get;

django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS:

check.Designer.certifier: (models.E006) The field 'certifier' clashes with the field 'certifier' from model 'check.profile'.

(Profile.type is irrelevant in this case, I just need it to distinguish logged in user profile types).

check.profile obviously doesn’t have a field 'certifier'. Is this a bug or do I miss something? The same thing happens in another project.

like image 230
Jens-Erik Weber Avatar asked Dec 04 '15 10:12

Jens-Erik Weber


2 Answers

I think that you shouldn't use name certifier for that foreign key relation because class Profile actually has certifier, admin and designer fields(although by descriptor) according to docs and in that case names actually would clash.

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) 

Change to something like certifier_field = models.ForeignKey(Certifier)

As it was pointed out in comments, you could rename the models to CertifierProfile, AdminProfile etc to avoid the clash.

Or you could also silence the check by adding SILENCED_SYSTEM_CHECKS = ['models.E006'] to your settings, but this is not a good approach.

like image 163
Alex Polekha Avatar answered Sep 29 '22 18:09

Alex Polekha


You can specify Profile is an abstract class. This will stop the check from being confused with your parent fields.

class Meta:     abstract = True 
like image 26
mrcai Avatar answered Sep 29 '22 17:09

mrcai