2011-08-11 41 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