Reputation: 33
I have only done 1 tutorial half year ago and this is my first code since that time, so please forgive me my lack of knowledge. I'm trying to make this code work by searching for information in Google but I got myself stuck with it.
from django_uuid_pk.fields import UUIDField
from django.db import models
from django.utils import timezone
from django.utils.http import urlquote
from django.utils.translation import ugettext_lazy as _
from django.core.mail import send_mail
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.contrib.auth.models import BaseUserManager
from django.core.exceptions import ObjectDoesNotExist
class Avatar(models.Model):
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30)
uuid = UUIDField(unique = True, primary_key = True)
class Meta:
unique_together = ('first_name', 'last_name',)
class CustomUserManager(BaseUserManager):
def _create_user(self, first_name, last_name, uuid, password, email,
is_staff, is_superuser, **extra_fields):
now = timezone.now()
email = self.normalize_email(email)
try:
avatar = Avatar.objects.get(pk=uuid)
except ObjectDoesNotExist:
avatar = Avatar.objects.create(uuid=uuid, first_name=first_name, last_name=last_name)
user = self.model(avatar=avatar, email=email, is_staff=is_staff, is_superuser=is_superuser, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, first_name, last_name, uuid, password=None, email=None, **extra_fields):
return self._create_user(first_name, last_name, uuid, password, email, False, False,
**extra_fields)
def create_superuser(self, first_name, last_name, uuid, password=None, email=None, **extra_fields):
return self._create_user(first_name, last_name, uuid, password, email, True, True,
**extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
avatar = models.ForeignKey('Avatar', unique=True)
email = models.EmailField(_('email address'), max_length=254, blank=True)
is_staff = models.BooleanField(_('staff status'), default=False)
is_active = models.BooleanField(_('active'), default=True)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
objects = CustomUserManager()
USERNAME_FIELD = 'avatar'
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def get_short_name(self):
return self.avatar.first_name
When I'm trying to create user in shell through a command:
CustomUser.objects.create_user('Philip', 'Philips', 'f86cff00-2076-11e4-8c21-0800200c9a66', '123456')
I'm getting an error:
IntegrityError: UNIQUE constraint failed: myproject_accounts_customuser.avatar_id
Upvotes: 1
Views: 158
Reputation: 5417
You have unique=True
on your avatar
field in CustomUser model.
But in your custom manager you have this code:
try:
avatar = Avatar.objects.get(pk=uuid)
except ObjectDoesNotExist:
avatar = Avatar.objects.create(uuid=uuid, first_name=first_name, last_name=last_name)
If avatar with that uuid exists, you will get an avatar object and django will try to create user with this object. But since avatar is unique, you will get an IntegrityError, if user with that avatar exists in database.
You should raise custom exception in this place, if avatar object already exists, if you need unique behaviour. If not, remove unique=True
.
Upvotes: 2