Só queria acrescentar algo que não vi em outras respostas.
Ao contrário das classes Python, a ocultação do nome do campo não é permitida com a herança do modelo.
Por exemplo, experimentei problemas com um caso de uso como segue:
Eu tinha um modelo herdado do auth do django PermissionMixin :
class PermissionsMixin(models.Model):
"""
A mixin class that adds the fields and methods necessary to support
Django's Group and Permission model using the ModelBackend.
"""
is_superuser = models.BooleanField(_('superuser status'), default=False,
help_text=_('Designates that this user has all permissions without '
'explicitly assigning them.'))
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
blank=True, help_text=_('The groups this user belongs to. A user will '
'get all permissions granted to each of '
'his/her group.'))
user_permissions = models.ManyToManyField(Permission,
verbose_name=_('user permissions'), blank=True,
help_text='Specific permissions for this user.')
class Meta:
abstract = True
Então eu tinha meu mixin que, entre outras coisas, queria substituir o related_namedo groupscampo. Então era mais ou menos assim:
class WithManagedGroupMixin(object):
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
related_name="%(app_label)s_%(class)s",
blank=True, help_text=_('The groups this user belongs to. A user will '
'get all permissions granted to each of '
'his/her group.'))
Eu estava usando estes 2 mixins da seguinte forma:
class Member(PermissionMixin, WithManagedGroupMixin):
pass
Sim, esperava que funcionasse, mas não funcionou. Mas o problema era mais sério porque o erro que eu estava recebendo não estava apontando para os modelos, eu não tinha ideia do que estava errado.
Enquanto tentava resolver isso, decidi aleatoriamente mudar meu mixin e convertê-lo em um mixin de modelo abstrato. O erro mudou para este:
django.core.exceptions.FieldError: Local field 'groups' in class 'Member' clashes with field of similar name from base class 'PermissionMixin'
Como você pode ver, esse erro explica o que está acontecendo.
Essa foi uma grande diferença, na minha opinião :)