Adding extended Profile model into custom user models admin - python

How can i add extended Profile model fields (fields which are not available in custom user model fields) into custom users admin users.admin?
what i am trying to do is that i want too see Profile model fields like photo, date_of_birth, country, phone etc.. inside the Personal Info(see in image) & i can make changes in it from here.
profile model
from django.db import models
from django.dispatch import receiver
from django.urls import reverse
from django.db.models.signals import post_save
from django.contrib.auth import get_user_model # or from users.models import User
User = get_user_model()
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
photo = models.ImageField(null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
phone = models.IntegerField(null=True, blank=True)
country = models.CharField(max_length=150, null=True, blank=True)
city = models.CharField(max_length=150, null=True, blank=True)
bio = models.TextField(max_length=150, null=True, blank=True)
def __str__(self):
return str(self.user.email)
def get_absolute_url(self):
return reverse('profiles:profile-detail', kwargs={'pk':self.pk})
def post_save_user_model_receiver(sender, instance, created, *args, **kwargs ):
# when a user is created(custom user model)like signup or through admin it will create those user's profile too
if created:
try:
Profile.objects.create(user=instance) # it create those user's profile
except:
pass
post_save.connect(post_save_user_model_receiver, sender=User)
users.admin
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 import get_user_model # or from .models import User
from .forms import UserAdminCreationForm, UserAdminChangeForm
# Register your models here.
User = get_user_model() # or from .models import User
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserAdminChangeForm
add_form = UserAdminCreationForm
# 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', 'get_phone', 'last_login', 'date_joined', 'is_admin')
list_filter = ('admin', 'staff', 'active')
list_select_related = ('profile',)
def get_phone(self, instance): # to show the Phone in list display from the Profile Model
return instance.profile.phone
get_phone.short_description = 'Phone'
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal Info', {'fields': ('first_name', 'last_name',)}),
('Permissions', {'fields': ('admin', 'staff', 'active')}),
)
# 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',)
ordering = ('email',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
# Remove Group Model from admin. We're not using it.
admin.site.unregister(Group)
form which is used to edit users in admin
from django import forms
from django.contrib.auth import get_user_model # or from .models import User
from django.contrib.auth.forms import ReadOnlyPasswordHashField
User = get_user_model() # this method will return the currently active user model
# or from .models import User
class UserAdminCreationForm(forms.ModelForm):
"""
A form for creating new users in admin panel. Includes all the required
fields, plus a repeated password.
"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Confirm Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
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("Password don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""
A form for updating users in admin panel. 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 = ('first_name', 'last_name', 'email', 'password', 'active', 'staff', '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']

I would recommend that you override the User model.
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, \
PermissionsMixin
class UserManger(BaseUserManager):
"""
Add extra calling functionalities here
"""
pass
class User(AbstractBaseUser, PermissionsMixin):
"""Custom user model"""
pass
objects = UserManger()
This is the basic format. Add the extra profile fields in the model
in setting.py add
AUTH_USER_MODEL = '{{ app_name }}.{{ model_name }}'
# eg. 'core.User'

Related

Django Admin doesn't recognise blank=True in model

When I try to edit a user (using a custom UserChangeForm) in the Django admin panel, validation insists that fields I have set blank=True in the model are required.
I don't know where to begin solving this; I had the same issue with the CustomUserCreationForm but reverted to using the default which works as expected (asks for username, password1 & password2, creates the user with blank display_name, bio and profile_picture fields).
models.py:
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
display_name = models.CharField(max_length=30, blank=True, null=True)
bio = models.TextField(blank=True, null=True)
profile_picture = models.ImageField(upload_to='images/', blank=True, null=True)
def save(self, *args, **kwargs):
if not self.display_name:
self.display_name = self.username
super().save(*args, **kwargs)
def __str__(self):
return self.username
forms.py:
from django import forms
from django.contrib.auth.forms import UserChangeForm
from .models import CustomUser
class CustomUserChangeForm(UserChangeForm):
display_name = forms.CharField(label="display_name")
bio = forms.CharField(widget=forms.Textarea)
profile_picture = forms.ImageField(label="profile_picture")
class Meta():
model = CustomUser
fields = ("username", "email", "display_name", "bio", "profile_picture")
admin.py:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserChangeForm
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
form = CustomUserChangeForm
fieldsets = (
(None,
{'fields': ('username', 'password', 'email', 'display_name', 'bio', 'profile_picture')}
),
)
model = CustomUser
list_display = ["username", "email",]
admin.site.register(CustomUser, CustomUserAdmin)
From the Django documentation:
By default, each Field class assumes the value is required, so if you
pass an empty value – either None or the empty string ("") – then
clean() will raise a ValidationError exception:
So you have to add required=False in your forms.py. For example:
display_name = forms.CharField(required=False, label="display_name")

FOREIGN KEY constraint failed with Custome Model in Django

I customed the User in Django following the code providing by the Documentation (for the models.py and the admin.py)
I have a custom User using his email to auth (and not the username)
I can create new user but I cannot delete them in the django admin panel. When I try i go this error message: FOREIGN KEY constraint failed
models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, 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),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
date_of_birth=date_of_birth,
)
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,
)
date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']
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
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
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 register.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', 'date_of_birth')
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', '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', 'is_admin')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('date_of_birth',)}),
('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 = ()
# 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)
view.py
from django.contrib.auth import login, authenticate
from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render, redirect
from django.contrib.auth import logout
from django.core.mail import send_mail
from .admin import UserCreationForm
def registration_view(request):
context = {}
if request.POST:
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
return render(request, 'register/home.html')
else:
context['registration_form'] = form
else:
form = UserCreationForm()
context['registration_form'] = form
return render(request, 'register/signup.html', context)
Mostly you get this error when the user you are trying to delete has some records associated in other tables.
Two options are:
Delete the associated records from the other tables first. And then try to delete this user.
Add on delete cascade option to the other tables' foreign keys referring to the user table. (This option will automatically remove any associated records from the other tables for the user you are trying to delete.)

Add user to permission group when creating user in Django Admin

I would to add a User to a permission group automatically when create a User. I have hear about user.groups.add(group) and group.user_set.add(user). But it doesn't work. My final purpose is to have 3 kind of users:
SuperAdmin: One superadmin to manage the site.
Administrators: User administrators. Which can manage regular users. Upload photos, add new Users to manage, etc.
Regular Users: The normal users which will use the aplicación. They don't have any permission, just login the site, but not the adminSite.
MODELS.PY
from django.db import models
from django.contrib.auth.models import AbstractUser, Group
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class MyUser(AbstractUser):
descripcion = models.TextField(blank=True)
telefono = models.PositiveSmallIntegerField(default=000)
avatar = models.ImageField(upload_to='users/avatar/', blank=True)
def __str__(self):
return self.username
class RegularUser(MyUser):
MyUser.is_staff = False
MyUser.is_superuser = False
class Meta:
verbose_name = 'Usuario Regular'
verbose_name_plural = 'Usuarios Regulares'
class AdminUser(MyUser):
usuarios = models.ManyToManyField(RegularUser, help_text="Selecciona los usuarios que administra")
MyUser.is_staff = True
class Meta:
verbose_name = 'Administrador'
verbose_name_plural = 'Adminsitradores'
ADMIN.PY
from django.contrib import admin
from django import forms
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import Group
from myApp.models import MyUser, RegularUser, AdminUser
# Register your models here.
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required fields,
plus a repeated password"""
password1 = forms.CharField(label='Contraseña', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repita Contraseña',
widget=forms.PasswordInput)
class Meta:
model = MyUser
fields = ('email',
'first_name',
'last_name',
'telefono',
'avatar',
'groups',)
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("Las contraseñas no coinciden")
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 = ('username',
'email',
'password',
'first_name',
'last_name',
'descripcion',
'telefono',
'avatar',
)
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 AdminCreationForm(forms.ModelForm):
"""A form for creating new Admin users. Including all required fields,
plus a repeated password"""
password1 = forms.CharField(label='Contraseña', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repita Contraseña', widget=forms.PasswordInput)
# usuarios = forms.CharField(label= 'Usuarios', widget=forms.SelectMultiple(choices=RegularUser.objects.all()))
class Meta:
model = AdminUser
fields = ('username',
'email',
'password',
'telefono',
'avatar',
'usuarios',
'groups',)
def clean_password2(self):
# Check that the 2 password entries match
password1 = self.cleaned_data.get('password1')
password2 = self.cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise ValueError("Las contraseñas no coinciden")
return password2
# def _save_m2m(self):
# user = super().save(commit=False)
# self.instance.user_set = self.cleaned_data['user']
def save(self, commit=True):
# Save the commit password in hashed form
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
# Set the current User as admin user
user.is_staff = True
if commit:
user.save()
group = Group.objects.get(name="Administradores")
user.groups.add(group)
# group.user_set.add(user)
# group.save()
return user
#receiver(post_save, sender=AdminUser)
def post_save_admin(sender, instance, **kwargs):
if kwargs['created'] and instance.is_staff:
grupo = Group.objects.get(name="Administradores")
grupo.user_set.add(instance)
class AdminChangeForm(forms.ModelForm):
""" A form for updating Administrators. Includes all the fields on the user
, but replaces the password field with admin's password hash display field"""
password = ReadOnlyPasswordHashField()
class Meta:
model = AdminUser
fields = ('username',
'email',
'password',
'first_name',
'last_name',
'descripcion',
'telefono',
'avatar',
'usuarios',
'groups',
)
def clean_password(self):
# Regardless of what the admin 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 AdminUserAdmin(BaseUserAdmin):
# The forms to add and change admin instances
form = AdminChangeForm
add_form = AdminCreationForm
# The fields to be used in displaying the Admin model.
# These overrides the definitions on the base AdminUserAdmin
# that reference specific fields on auth.User
list_display = ('username', 'email',)
list_filter = ('last_login',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Información Personal', {'fields': ('first_name', 'last_name', 'descripcion', 'avatar', 'telefono',)}),
('Administración', {'fields': ('is_staff', 'usuarios','groups')}),
)
# 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': ('username', 'email', 'telefono', 'password1', 'password2', 'usuarios','groups')}
),
)
search_fields = ('username',)
ordering = ('username',)
filter_horizontal = ()
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 = ('username', 'email', 'is_staff')
list_filter = ('is_staff',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name', 'descripcion', 'avatar', 'telefono',)}),
('Permissions', {'fields': ('is_staff', 'is_superuser')}),
)
# 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': ('username', 'email', 'telefono', 'password1', 'password2',)}
),
)
search_fields = ('username',)
ordering = ('username',)
filter_horizontal = ()
# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
admin.site.register(AdminUser, AdminUserAdmin)
# #admin.register(MyUser)
# class MyUserAdmin(admin.ModelAdmin):
# pass
# #admin.register(AdminUser)
# class AdminUserAdmin(admin.ModelAdmin):
# # The forms to add and change Admin instances:
# form = AdminChangeForm
#admin.register(RegularUser)
class RegularUserAdmin(admin.ModelAdmin):
pass
I think the solution must be here, but it doesn't work:
SAVE USER FUNCTION
def save(self, commit=True):
# Save the commit password in hashed form
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
# Set the current User as admin user
user.is_staff = True
if commit:
user.save()
group = Group.objects.get(name="Administradores")
user.groups.add(group)
# group.user_set.add(user)
# group.save()
return user
This is because django admin doesn't call your form's save method with commit=True.
If you really want this to be done only for users saved from the admin then you should override the save_model method on the ModelAdmin. This means that you will need to unregister the UserModelAdmin from django.contrib.admin and create your own UserModelAdmin.
If you want this to be done globally within your application look into the post_save signal.
This is the solution I have found.
#receiver(post_save, sender= AdminUser)
def add_admin_permission(sender, instance, created, **kwargs):
if created:
grupo = Group.objects.get(id=1)
grupo.user_set.add(instance)

Remove/hiding username field in django admin edit user form

The frontend user signup form doesn't have username field as I am using email to login.Now I have access to django admin.
When I edit an user I get that username field to edit but I do not want that field to be editable or view-able at all.
admin.py --
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import UserProfile
class ProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'Profile'
fk_name = 'user'
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline, )
list_display = ('email', 'first_name', 'last_name', 'is_staff')
list_select_related = ('profile', )
exclude = ('username',)
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
forms.py --
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Field
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteField
from phonenumber_field.formfields import PhoneNumberField
from . import models
from captcha.fields import ReCaptchaField
class SignUpForm(forms.Form):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
phone_number = PhoneNumberField(label=_("Phone (Please state your country code eg. +44)"))
organisation = forms.CharField(max_length=50)
email = forms.EmailField()
password1 = forms.CharField(max_length=20)
password2 = forms.CharField(max_length=20)
captcha = ReCaptchaField(attrs={'theme' : 'clean'})
models.py--
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from easy_thumbnails.fields import ThumbnailerImageField
from ciasroot.settings import THUMBNAILER_SIZES, UPLOAD_PATH
from ciasroot.constants import GENDERS, LANGUAGES
from ciasroot.util import HashedPk
from phonenumber_field.modelfields import PhoneNumberField
import math, decimal, datetime, os
class UserProfile(models.Model, HashedPk):
user = models.OneToOneField(User, unique=True, related_name ='profile')
job_title = models.CharField(max_length=128, blank=True, null=False, default="")
website = models.URLField(max_length=255, blank=True, null=True)
organisation = models.CharField(max_length=50, blank=True, null=True, default="")
phone_number = PhoneNumberField( blank=True, null=True)
The django version is 1.10 so I used exclude. But it throws an error--
KeyError: "Key 'username' not found in 'UserForm'. Choices are: date_joined, email, first_name, groups, is_active, is_staff, is_superuser, last_login, last_name, password, user_permissions."
Do I need to override the signup form because when adding a new user from admin I don't get the fields as frontend signup form(At some point I need to do that as well).
Any help is highly appreciated.
A discussion about this problem is here.
Briefly:
That's because the stock UserAdmin defines fieldsets in which 'username'
is a field, you need to modify the fieldsets, too.
For example:
class CustomUserAdmin(UserAdmin):
# ...
exclude = ('username',)
fieldsets = (
('Personal info', {'fields': ('full_name', 'email', 'password')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
)

Adding extra field to UserModel Django

So I finally managed to add a location field to my User model and this is the code I have:
model:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User)
location = models.CharField(('location'),max_length=30, blank=False)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
and admin.py:
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django import forms
from UserProfile.models import UserProfile
from django.contrib.admin.views.main import *
class MyUserCreationForm(UserCreationForm):
username = forms.RegexField(label=("Username"), max_length=30, regex=r'^[\w.#+-]+$', help_text = ("Required. 30 characters or fewer. Letters, digits and #/./+/-/_ only."),error_messages = {'invalid': ("This value may contain only letters, numbers and #/./+/-/_ characters.")})
password1 = forms.CharField(label=("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(label=("Password confirmation"), widget=forms.PasswordInput, help_text = ("Enter the same password as above, for verification."))
email = forms.EmailField(label=("Email address"))
class Meta:
model = User
fields = ("username",)
def clean_username(self):
username = self.cleaned_data["username"]
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError(("A user with that username already exists."))
def clean_email(self):
email = self.cleaned_data["email"]
if email == "":
raise forms.ValidationError((""))
return email
def clean_password2(self):
password1 = self.cleaned_data.get("password1", "")
password2 = self.cleaned_data["password2"]
if password1 != password2:
raise forms.ValidationError(("The two password fields didn't match."))
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class MyUserChangeForm(UserChangeForm):
username = forms.RegexField(label=("Username"), max_length=30, regex=r'^[\w.#+-]+$',
help_text = ("Required. 30 characters or fewer. Letters, digits and #/./+/-/_ only."),
error_messages = {'invalid': ("This value may contain only letters, numbers and #/./+/-/_ characters.")})
location = forms.CharField(label=("Location"),max_length=30)
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs)
f = self.fields.get('user_permissions', None)
if f is not None:
f.queryset = f.queryset.select_related('content_type')
class CustomUserAdmin(UserAdmin):
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'password1', 'password2')}
),
)
fieldsets = (
(None, {'fields': ('username', 'password')}),
(('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'location')}),
(('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
(('Important dates'), {'fields': ('last_login', 'date_joined')}),
(('Groups'), {'fields': ('groups',)}),
)
#list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'location')
add_form = MyUserCreationForm
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
When I tried creating a user it finally didn't error. But when I went to edit the information about the user, the location field was empty. I checked the database manually using sqlite database browser. And I assumed by creating a UserProfile would add extra tables to the database, but it didn't. What I want is for the location field to be trated just like the email field or the username or any other information stored about the user.
You don't add fields to the old model this way, you're creating a new one that's associated with it. Your data will be in app_userprofile table, and you can access that instance (to save that location or whatever) via user.get_profile(). You can't use straightforward ModelForm for that, I'm afraid, you need to handle the profile yourself.

Categories