Django Addform User - django

Hey in django admin there is a button "adduser". When I press it I want to show my custom Form. I tried to do the following.
at admin.py
add_form = CustomUserCreationForm
add_fieldsets = (
(None, {'fields': ('username', 'email', 'first_name', 'last_name', 'password1', 'password2',), }),
)
P.S. I think the names interfered with the standard names. Once I renamed the fields from first_name to something custom it kidna started working.
at forms.py
class CustomUserCreationForm(UserCreationForm):
first_name = forms.CharField(max_length=35, label='First name')
last_name = forms.CharField(max_length=35, label='Last name')
email = forms.EmailField(label="Email")
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'email',)
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.first_name = first_name
user.last_name = last_name
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
The only charfield that is editable that appears on teh admin-page is the "username". Others just have a label but not an edit-field which is odd. I would like to display all the CharFields I defined in the CustomForm and them to be editable. Thats how my AddUser looks like:

You need to extend the built-in UserCreationForm from django.contrib.auth.forms instead of extending ModelForm.
This way you don't have to override the save method to set the password, however you'll need to add the username, password1 and password2 fields to your form, or it won't pass validation.

Related

django.core.exceptions.FieldError: Unknown field(s) specified by user

I'm using Django 2.0
I have extended AbstractBaseUser model to create a custom User model.
In my accounts/models.py
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_staff=False, is_admin=False, is_active=False):
if not email:
raise ValueError('User must have an email address')
if not password:
raise ValueError('User must have a password')
user = self.model(
email=self.normalize_email(email)
)
user.is_staff = is_staff
user.is_admin = is_admin
user.is_active = is_active
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, email, password=None):
return self.create_user(
email,
password=password,
is_staff=True,
is_active=True
)
def create_superuser(self, email, password=None):
return self.create_user(
email,
password=password,
is_staff=True,
is_admin=True,
is_active=True
)
class User(AbstractBaseUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
email = models.EmailField(max_length=250, blank=False, unique=True)
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
groups = models.ManyToManyField(Group, blank=True)
last_login = models.DateTimeField(auto_now=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
objects = UserManager()
#property
def is_staff(self):
return self.is_staff
#property
def is_active(self):
return self.is_active
#property
def is_superuser(self):
return self.is_admin
def __str__(self):
if self.first_name is not None:
return self.get_full_name()
return self.email
def get_full_name(self):
if self.last_name is not None:
return self.first_name + ' ' + self.last_name
return self.get_short_name()
def get_short_name(self):
return self.first_name
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
and to use this User model for admin as well. I have added below code to
accounts/admin.py as given in example
from accounts.models import User
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import Group
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email', 'first_name', 'last_name')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'password', 'first_name', 'last_name', 'is_active', 'is_admin', 'is_staff')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'first_name', 'last_name', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name',)}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'first_name', 'last_name', 'password1', 'password2')}
),
)
search_fields = ('email', 'first_name', 'last_name',)
ordering = ('email', 'first_name', 'last_name',)
filter_horizontal = ()
# Now register the new UserAdmin...
admin.site.register(User, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)
But when I run
python manage.py makemigrations
It gives error as
File "/Users/anuj/code/PyCharm/notepad/src/accounts/admin.py", line 37, in <module>
class UserChangeForm(forms.ModelForm):
raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (is_staff, is_active) specified for User
removing is_staff and is_active from UserChangeForm works fine. I have even fields added to model.
Since you are using a custom user model for authentication you must say so in your settings
In settings.py write:
AUTH_USER_MODEL = 'accounts.User'
Source

Django UserCreationForm extension

can i add fields like address,city,state,country,pincode and security question and answer to the extension of UserCreationForm that currently contains username,email,password1 and password2. if yes then please illustrate how?
forms.py
class UserCreationForm(UserCreationForm):
email = EmailField(label=_("Email address"), required=True,
help_text=_("Required."))
city= forms.CharField(label= _("City"),max_length=20, required=True)
state= forms.CharField(label= _("State"),max_length=20, required=True)
class Meta:
model = User
fields = ("username", "email", "password1", "password2","city","state")
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
user.city = self.cleaned_data["city"]
user.state = self.cleaned_data["state"]
if commit:
user.save()
return user
Yes just do like you did with email:
class UserCreationForm:
a_field = WhateverField(whatever='whatever'...)
class Meta:
model = User
fields = ("username", "email", "password1", "password2")
The field is now added in your form.
currently you are extending UserCreationForm class if you have other fields in user model then you can use forms.ModelForm and just mention other fields.
for example
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username','name', 'email', 'phone',
'address','city','state', 'first_time']
if you want to use custom form then.
class UserForm(forms.Form):
name = forms.CharField(label= _("Name"))
address = forms.CharField(label=_("Address"))
etc.

Edit the admin panel using Custom user authentication

Using the documentation I am trying to create a custom authentication model in order to be able to use only Email and password to authenticate a user.
Despite I manage to do it, I am having trouble to edit the Admin panel and in particular the Edit form could you please help me to add the possible editable field.
my code is :
admin.py:
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from registration.models import MyUser
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = MyUser
fields = ('email','is_active','is_hr','is_candidate','is_employee','company','first_name','last_name')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = MyUser
fields = ('email', 'password', 'is_active', 'is_admin','is_hr','is_candidate','is_employee','company','first_name','last_name')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'is_admin','is_active', 'is_admin','is_hr','is_candidate','is_employee','company','first_name','last_name')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)
model.py:
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_Euser(self, email):
"""
Creates and saves a User with the given email,
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email)
)
user.save(using=self._db)
return user
def create_user(self, email, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email)
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name= models.CharField(max_length=150, default='')
last_name= models.CharField(max_length=150, default='')
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_hr = models.BooleanField(default=False)
is_candidate = models.BooleanField(default=False)
is_employee = models.BooleanField(default=False)
company = models.CharField(max_length=100, default='')
objects = MyUserManager()
USERNAME_FIELD = 'email'
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
def get_short_name(self):
# The user is identified by their email address
return self.email
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
You can add all you model fields.for that you should have to add field in fieldsets under UserAdmin.
change you fieldsets as below:
fieldsets = (
(None, {'fields': ('email', 'password','company','first_name','last_name')}),
('Permissions', {'fields': ('is_admin','is_active','is_hr','is_candidate','is_employee')}),
)
Above changes will add fields to django-admin.

Django Custom User Model ForeignKey Addition Not Showing in Admin

I've successfully created my own extension for the User model based on this tutorial:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom-users-and-permissions
I also need to add a ForeignKey to a Company model, so that each user is assigned to a company. But this isn't showing in the admin at all, neither in the initial admin view or the edit view.
I've added the ForeignKey reference in the MyUser class like so:
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
date_of_birth = models.DateField()
company = models.ForeignKey('Company', on_delete=models.CASCADE, default=1)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']
...
admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from myapp.models import Company, Camera, MyUser
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = MyUser
fields = ('email', 'date_of_birth', 'company')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = MyUser
fields = ('email', 'password', 'date_of_birth', 'company', 'is_active', 'is_admin')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'date_of_birth', 'company', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('date_of_birth',)}),
('Company info', {'fields': ('company',)}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'date_of_birth', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
admin.site.register(MyUser, UserAdmin)
admin.site.register(Company)
admin.site.register(Camera)
admin.site.unregister(Group)
If you add a foreign key to a custom user model, you need just to specify it on the fieldsets attribute.
For example with this custom user in models.py:
class CustomUser(AbstractUser):
company = models.ForeignKey('Company', on_delete=models.CASCADE)
You need this in the admin.py:
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm
from myapp.models import CustomUser
class MyUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = CustomUser
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
fieldsets = UserAdmin.fieldsets + (
(None, {'fields': ('company')}),
)
admin.site.register(CustomUser, MyUserAdmin)
Now you can select the user's company in the admin.

django-allauth - Overriding default signup form

I'm using this code (in forms.py) for my custom signup form for allauth:
class RegistrationForm(UserCreationForm):
birth_date = forms.DateField(widget=extras.SelectDateWidget(years=BIRTH_DATE_YEARS))
class Meta:
model = get_user_model()
fields = ('username', 'email', 'password1', 'password2', 'first_name', 'last_name', 'gender', 'birth_date', 'city', 'country')
I have of course specified ACCOUNT_SIGNUP_FORM_CLASS in settings.py to point to this form and it displays the fields which I've put in it. However, it does not work on submission, even if I put signup method it never gets invoked. I've tried with the save but still it's the same - it raises an error that one of my custom added fields is blank while creating user and saving it to the database.
So, what's the correct code for achieving this?
I've made it thanks to #rakwen who has found the correct solution here. I wrote my custom adapter and put it in adapters.py in my app:
from allauth.account.adapter import DefaultAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def save_user(self, request, user, form, commit=False):
data = form.cleaned_data
user.username = data['username']
user.email = data['email']
user.first_name = data['first_name']
user.last_name = data['last_name']
user.gender = data['gender']
user.birth_date = data['birth_date']
user.city = data['city']
user.country = data['country']
if 'password1' in data:
user.set_password(data['password1'])
else:
user.set_unusable_password()
self.populate_username(request, user)
if commit:
user.save()
return user
Then I've specified ACCOUNT_ADAPTER in settings.py to point to that adapter, and it finally started to work!
In your project setting.py try to add this line:
verify if you have added this:
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
)
ACCOUNT_SIGNUP_FORM_CLASS = "yourapp.forms.customSignupForm"
In app.models
class CustomModel(models.Model):
"""CustomModel docstring."""
city = forms.CharField(max_length=75)
country = forms.CharField(max_length=25)
other....
In app.forms:
class SignForm(forms.ModelForm):
"""SignForm docstring."""
username = forms.CharField(
max_length=30,
)
first_name = forms.CharField(
max_length=30,
)
last_name = forms.CharField(
max_length=30,
)
field...
def myclean():
def signup(self, request, user):
"""You signup function."""
# dont forget to save your model
class Meta:
model = mymodel.CustomModel
fields = [
'city',
'country',
'field...',
]
Try this method work !