I'm trying to create a custom User model in my Django app, the problem is I get an error saying email must be unique (fair enough!), however, I need email and company together to be unique, as I may have the same email but registered to a different company.
I get the following error:
ERRORS:
site.SiteUser: (auth.E003) 'SiteUser.email' must be unique because it is named as the 'USERNAME_FIELD'.
Here is my model:
class SiteUser(models.Model):
company = models.ForeignKey(Company)
email = models.EmailField(max_length=254)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(auto_now=False, auto_now_add=True)
objects = SiteUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
class Meta:
unique_together = ('company', 'email',)
You're missing the unique=True in your email field definition.
The filed that is used in the USERNAME_FIELD should have this argument as explained in the django doc on USERNAME_FIELD.
It should be like this:
email = models.EmailField(max_length=254, unique=True)
Add auth.E003 to the SILENCED_SYSTEM_CHECKS setting. This will allow manage.py to run. And I think you should add W004 warning to this list too:
SILENCED_SYSTEM_CHECKS = ['auth.E003', 'auth.W004']
Related
I'm being confused on where table how I insert my usertypes, I'm just a beginner on Django but surely Im been reading documentation in Django but I can't understand this one , The case is when I register new user there's must be choice what usertype should specify with this user either an admin or etc. but the problem is I think there is no relationship table from authuser even I create another table.slight similar to this problem resources link. For now I'm been thinking to create custom usertype field in authuser table, but when migrate it didn't show updated fields and also like this issue some people or user didn't touch or add any field in authuser table sample it is possible to insert usertype in auth_permission or other default table? Im just really confused of where table I can add my usertype that have a relationship to authuser. Is there any know or explain about this, thanks
Models
class AuthUser(models.Model):
password = models.CharField(max_length=128)
last_login = models.DateTimeField(blank=True, null=True)
is_superuser = models.IntegerField()
username = models.CharField(unique=True, max_length=150)
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=150)
email = models.CharField(max_length=254)
is_staff = models.IntegerField()
is_active = models.IntegerField()
date_joined = models.DateTimeField()
usertype_id = usertype = models.OneToOneField(usertypes,on_delete=models.CASCADE,primary_key=True)
() //this is what i want to add
class Meta:
managed = False
db_table = 'auth_user'
class usertypes(models.Model):
usertype = models.CharField(max_length=264)
description = models.CharField(max_length=264)
status = models.CharField(max_length=264)
There are multiple ways how to do it. The way I recommned is to extend the existing user model.
from django.contrib.auth.models import User
class UserType(models.Model):
user_type = models.CharField(max_length=264)
description = models.CharField(max_length=264)
status = models.CharField(max_length=264)
class AppUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
type = models.ForeignKey(UserType, on_delete=models.CASCADE)
This will create 2 extra tables.
user_type where you will have UserTypes that you probably want to fill and
app_user where will be stored reference on django user record and its type
However, I think you should have a good reason why you do this. Django allows you to group users into the user groups, what should be exactly what you want.
Thanks in advance, i'm learning Django and can't figure how to override all auth forms. Quick explanation first, I have a custom user model
class PersoUser(AbstractBaseUser):
email = models.EmailField(
verbose_name="Email Adress", max_length=200, unique=True)
username = models.CharField(
verbose_name="username", max_length=200, unique=True)
first_name = models.CharField(verbose_name="firstname", max_length=200)
last_name = models.CharField(verbose_name="lastname", max_length=200)
date_of_birth = models.DateField(verbose_name="birthday")
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
objects = PersoUserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["date_of_birth", "username"]
....
and I would want to add date_of_birth field to my signup page, so I followed the official doc to override the specif form used by all auth SignupView https://django-allauth.readthedocs.io/en/latest/forms.html#signup-allauth-account-forms-signupform
which leads to ( in Book_store/forms.py )
from all auth.account.forms import SignupForm from users. models import PersoUser
class PersoUserRegisterForm(SignupForm):
class Meta:
model = PersoUser
fields = ["username", "email", "first_name",
"last_name", "date_of_birth", "password1", "password2"]
def save(self, request):
# Ensure you call the parent class's save.
# .save() returns a User object.
user = super(PersoUserRegisterForm, self).save(request)
# Add your processing here.
# You must return the original result.
return user
in my settings/base.py
ACCOUNT_FORMS = {'signup': 'Book_store.forms.PersoUserRegisterForm'}
My account/signup.html template just refers to {{form.as_p}} and it doesn't display the extra fields specified in PersouserRegisterForm just the default ones
I don't see what I'm missing, Thanks for reading
EDIT: And Signing up fail because it violates not-null constraint for date_of_birth
You are overriding the save method but not saving user with the date_of_birth field .
def save(self, request):
user = super(PersoUserRegisterForm, self).save(request)
user.date_of_birth = self.cleaned_data['date_of_birth']
user.save()
return user
I have a solid level on Django, but can't find how to solve this one properly :
I created an API that will be used in multiple mobile projects. So I implemented an Application model that I pass when I log in.
I also created a custom user model :
class CustomUser(AbstractUser):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
username = None
email = models.EmailField('email address', unique=True)
application = models.ForeignKey(Application, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
class Meta:
unique_together = ('email', 'application')
I'm using djangorestframework-jwt. So I've an API call that needs an email, password and an Application (apikey as a string FYI) to get a token.
Everything is working fine, except that in this configuration, I'm not able to create another user with the same email but a different Application. Because my EmailField is my USERNAME_FIELD.
Is there any solution that would avoid me to rewrite everything ?
The best thing I have in mind is to add a field (for example a CharField) that would be unique (for example the combinaison of user.id + apikey) that would be filled automatically on creation. But then when I use ./manage.py createsuperuser, django would ask me to fill the field manually. Not a big deal but if you have a better/proper way I'd be glad !
How about use manytomany instead of foreignkey:
class CustomUser(AbstractUser):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
username = None
email = models.EmailField('email address', unique=True)
applications = models.ManyToManyField(Application, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
class Meta:
unique_together = (('email', 'application'),)
I am new to programming Django, so I'm not sure if this is possible.
I have created a new CustomUser class:
class CustomUser(AbstractBaseUser):
email = models.EmailField(verbose_name='email address', max_length=255, unique=True)
mobile = models.CharField(max_length=30, null=True)
first_name = models.CharField(max_length=50, null=True)
middle_name = models.CharField(max_length=50, null=True)
last_name = models.CharField(max_length=50, null=True)
date_of_birth = models.DateField(null=True)
Primary_address = models.CharField(max_length=50, null=True)
Primary_address_zipcode = models.CharField(max_length=5, null=True)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
A few questions:
Question 1: I have redefine some of the fields that exists in the default User class (e.g. First Name, Last name, Date Joined). However, I didn't define Last_login. But last_login still shows up as a column in the admin page. But if I don't define First Name, Last Name and Date Joined in my new CustomUser, I get an error and doesn't show up in the admin page. Why is last login special?
Question 2: The default admin page has great UI for group and permission control. Is it possible to define my CustomerUser and still use/enable the default admin page?
Thanks.
you dont need to define all these fields that are already there in django. dont reinvent the wheel. what error are you getting? traceback?
using your customuser model has nothing to do with using default admin page. you can always use django admin page no matter what models you have. Or i dont understand what you really want to achieve.
Based on Django's recommendation that information should be stored in a separate model if it's not directly related to authentication, I've created both a custom user model and a profile model in my app.
Something like:
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
location = models.ForeignKey(Location)
date_of_birth = models.DateField()
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'location', 'date_of_birth']
class Profile(models.Model):
user = models.OneToOneField(User)
picture = models.ImageField(upload_to='profile_pictures/',
default='default.jpg')
bio = models.TextField(blank=True)
sex = models.CharField(max_length=10,
choices=(('Male', 'Male'),
('Female', 'Female'),
('No Comment', 'No Comment')),
default="No Comment")
occupation = models.CharField(max_length=100, blank=True)
What's the best practice for having other models refer to a user? For example, my app has a messaging system. In the Message model, is it best to have a foreignkey relation to Profile as opposed to User? Should the User model only be used for the purpose of authentication?
I think you can relate the models to User and use related name to access profile.
This makes your models not depend directly on custom profile.