Reputation: 313
I am trying to work on adding a location field to the User Profile and associate it with a user. I currently have something like this:
This is my models.py:
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:
profile = UserProfile.objects.create(user=instance)
profile.save()
post_save.connect(create_user_profile, sender=User)
This is my 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',)}),
)
add_form = MyUserCreationForm
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
I do not fully understand Django/python code and I know something is missing from this code, because when I add a new user it doesn't save the Location field in the database. It saves the user id tho. I guess I am missing something like:
request.user.get_profile().location = self.cleaned_data["location"]
but I am not sure where to put it.
Upvotes: 3
Views: 3481
Reputation: 16435
Have you tried to use a simple inline for the profile? Yes, it will be shown at the bottom, but otherwise it would work.
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from website.users.models import UserProfile
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
max_num = 1
class UserProfileAdmin(UserAdmin):
inlines = [UserProfileInline]
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',)}),
)
admin.site.register(User, UserProfileAdmin)
Upvotes: 2
Reputation: 18737
You may use Model Inheritance for that, which do similar things for you...
Model Inheritance and proxy models...
Upvotes: 3