Reputation: 6555
Have I done this right? I have created a custom user in Django 1.5 which works. I now want to add a completely different type of user to the mix called WebUser
allowing very simple access to front-end pages/ public users who have signed-up. However, every time I try I get the following error...
Try to add this:
class WebUser(AbstractEmailUser):
company = models.CharField(max_length=100)
class Meta:
app_label = 'accounts'
I get this:
accounts.companyuser: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'. accounts.companyuser: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'. accounts.participantuser: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'. accounts.participantuser: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'.
This is my full model working version before I tried to add the new user:
class EmailUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
"""
Creates and saves an EmailUser with the given email and password.
"""
now = timezone.now()
if not email:
raise ValueError('The given email must be set')
email = EmailUserManager.normalize_email(email)
user = self.model(email=email, is_staff=False, is_active=True,
is_superuser=False, last_login=now,
date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(email, password, **extra_fields)
user.is_staff = True
user.is_active = True
user.is_superuser = True
user.save(using=self._db)
return user
class AbstractEmailUser(AbstractBaseUser, PermissionsMixin):
"""
Abstract User with the same behaviour as Django's default User but
without a username field. Uses email as the USERNAME_FIELD for
authentication.
Use this if you need to extend EmailUser.
Inherits from both the AbstractBaseUser and PermissionMixin.
The following attributes are inherited from the superclasses:
* password
* last_login
* is_superuser
"""
email = models.EmailField(_('email address'), max_length=255,
unique=True, db_index=True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=True,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = EmailUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
abstract = True
def get_full_name(self):
"""
Returns the email.
"""
return self.email
def get_short_name(self):
"""
Returns the email.
"""
return self.email
def email_user(self, subject, message, from_email=None):
"""
Sends an email to this User.
"""
send_mail(subject, message, from_email, [self.email])
class CompanyUser(AbstractEmailUser):
"""
Concrete class of AbstractEmailUser.
"""
company = models.CharField(max_length=100)
class Meta:
app_label = 'accounts'
Upvotes: 0
Views: 1264
Reputation: 6162
Look at the docs for abstract base classes
If you are using the related_name attribute on a ForeignKey or ManyToManyField, you must always specify a unique reverse name for the field. This would normally cause a problem in abstract base classes, since the fields on this class are included into each of the child classes, with exactly the same values for the attributes (including related_name) each time.
And look at PermissionMixin
code.
One way that I see is to replace PermissionMixin
with your own class but it may break a lot more because related names will change.
Upvotes: 1