Angie
Angie

Reputation: 313

Extending new user creation form, Django

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

Answers (2)

rewritten
rewritten

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

Mp0int
Mp0int

Reputation: 18737

You may use Model Inheritance for that, which do similar things for you...

Model Inheritance and proxy models...

Upvotes: 3

Related Questions