2011-08-11 20 views
3

我正在尝试将位置字段添加到用户配置文件并将其与用户关联。目前,我有这样的事情:扩展新的用户创建表单,Django

这是我的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) 

这是我的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'^[\[email protected]+-]+$', 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'^[\[email protected]+-]+$', 
     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) 

我不完全理解的Django/Python代码和我知道此代码中缺少某些内容,因为当我添加新用户时,它不会保存数据库中的位置字段。它保存用户标识。我想我缺少这样的东西:

request.user.get_profile().location = self.cleaned_data["location"] 

但我不知道该把它放在哪里。

+0

您的代码似乎有错误的缩进。如果你纠正了缺陷,对我们来说调试你的代码会容易得多。我注意到的一件事是,如果您想要电子邮件是必需的,只需传递required = true参数,而不是手动验证它。 – mohi666

回答

3

您可以使用模型继承为,它为你做类似的事情......

Model Inheritance and proxy models...

+0

我将不胜感激我的代码的实际帮助。我读过许多不同的页面,并且在其中所有人都做不同的事情。阅读更多不会帮助我更好地理解代码。 – Angie

+0

模型继承在django.contrib.auth的情况下效果不好,用户模型的扩展需要存在于UserProfile模型中。 – rewritten

2

您是否尝试过用一个简单的内联的个人资料?是的,它会显示在底部,但否则会起作用。

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) 
+0

我确实试过,但我得到这个错误,我不知道它是什么意思或错误。 '列user_id不是唯一的' – Angie

+0

这是因为您没有将UserProfile类中的'user'字段声明为* -to-one。 *编辑:哦,亲爱的,你已经被宣布为OneToOneField ... * – rewritten

+0

你想插入多个地址吗?用户最多只能有一个配置文件,因此将“max_num”选项添加到编辑后的内联。 – rewritten