Django中指定了未知字段(用户名)用于PoUser。

9
我之所以出现这个错误,是因为我创建了一个自定义用户模型。当我完成所有设置后,查看django/contrib/auth/models.py文件,将电子邮件设置为USERNAME_FIELD,并将REQUIRED_FIELD设置为AbstractBaseUser和PermissionMixin中未定义的某个字段,我可以访问除“添加Po用户”部分之外的所有部分。我在models.py、admin.py、settings.py和urls.py中放置了我的代码,希望有人能帮助解决问题。
错误跟踪:
Unknown field(s) (username) specified for PoUser
Request Method: GET
Request URL:    http://127.0.0.1/newproject/admin/Testsite/pouser/add/
Django Version: 1.5.1
Exception Type: FieldError
Exception Value:    
Unknown field(s) (username) specified for PoUser
Exception Location: /usr/local/lib/python2.7/dist-packages/django/forms/models.py in __new__, line 221
Python Executable:  /usr/bin/python
Python Version: 2.7.3
/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py in get_response
                        response = callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py in wrapper
                return self.admin_site.admin_view(view)(*args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in _wrapped_view
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py in _wrapped_view_func
        response = view_func(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py in inner
            return view(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/views/decorators/debug.py in sensitive_post_parameters_wrapper
            return view(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in _wrapper
            return bound_func(*args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in _wrapped_view
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in bound_func
                return func(self, *args2, **kwargs2) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/db/transaction.py in inner
                return func(*args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/auth/admin.py in add_view
                                               extra_context) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in _wrapper
            return bound_func(*args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in _wrapped_view
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py in bound_func
                return func(self, *args2, **kwargs2) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/db/transaction.py in inner
                return func(*args, **kwargs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py in add_view
        ModelForm = self.get_form(request) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/auth/admin.py in get_form
        return super(UserAdmin, self).get_form(request, obj, **defaults) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py in get_form
        return modelform_factory(self.model, **defaults) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/forms/models.py in modelform_factory
    return type(form)(class_name, (form,), form_class_attrs) ...
▶ Local vars
/usr/local/lib/python2.7/dist-packages/django/forms/models.py in __new__
                raise FieldError(message) ...

models.py

from django.db import models
from django.contrib.auth.models import Group
from django.utils import timezone
from django.contrib.auth.models import BaseUserManager,AbstractBaseUser,PermissionsMixin
from django.db import models
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django import forms
from django.contrib import admin
from taggit.managers import TaggableManager
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
# Create your models here.
class poUserManager(BaseUserManager):
    def create_user(self,email,password=None,first_name=None,last_name=None,last_login=None,date_join=None):
        now=timezone.now()
        if not email:
            raise ValueError("The given email must be setted")
        user = self.model(email=self.normalize_email(email),is_staff=True, is_active=True, is_superuser=False,last_login=now, date_join=date_join,first_name=first_name,last_name=last_name)
        user.set_password(password)
        user.save(using=self._db)
        return user
    def create_superuser(self,email,password,first_name,last_name,last_login,date_join):
        now=timezone.now()
        u=self.create_user(email,password,first_name=first_name,last_name=last_name,date_join=date_join)
        u.is_staff=True
        u.active=True
        u.is_superuser=True
        u.save(using=self.db)
        return u
#@python_2_unicode_compatible
class PoUser(AbstractBaseUser,PermissionsMixin):
    email=models.EmailField(verbose_name='email address',max_length=255,unique=True,db_index=True)
    first_name=models.CharField(max_length=30)
    last_name=models.CharField(max_length=20)
    
   
    date_join=models.DateField(default=timezone.now)
    is_staff = models.BooleanField(_('staff status'), default=False,help_text=_('Designates whether the user can log into this admin ''site.'))
    is_active = models.BooleanField(_('active'), default=True,help_text=_('Designates whether this user should be treated as ''active. Unselect this instead of deleting accounts.'))
    is_admin=models.BooleanField(default=False)
    USERNAME_FIELD='email'
    #REQUIRED_FIELD=['first_name','last_name','date_join','is_active','is_admin','groups','user_permissions','is_superuser','last_login','is_staff'] 
    REQUIRED_FIELD=['last_name','first_name','date_join']
    objects=poUserManager()
    def get_full_name(self):
        return self.firstname
    def get_short_name(self):
        return self.first_name
   # def has_perm(self,perm,obj):
       
    #    if self.is_active and self.is_superuser:
     #       return True
        # return this.groups.values_list(self.email,flat=True)
      #  return _user_has_perm(self,perm.obj)
    def __unicode__(self):
        return self.email
    def get_group(self):
        return self.objects.values('groups')

admin.py:

from django.db import models
from django.contrib.auth.models import Group
from django.utils import timezone
from django.contrib.auth.models import BaseUserManager,AbstractBaseUser,PermissionsMixin
from django.db import models
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django import forms
from Testsite.models import PoUser
from django.contrib import admin
from taggit.managers import TaggableManager
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.admin import GroupAdmin
from django.contrib import admin

class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
    class Meta:
        model = PoUser
        fields = ('email','first_name','last_name','groups','user_permissions','date_join','is_staff','is_active','is_admin',)
        #fields=('email','first_name','last_name')
    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):
        user=super(UserCreationForm,self).save(commit=False)
        user.set_password(self.clean_data['password1'])
        if commit:
            user.save()
        return user
class UserChangeForm(forms.ModelForm):
    password=ReadOnlyPasswordHashField()
    class Meta:
        model = PoUser
        fields=['email','first_name','last_name','groups','user_permissions','date_join','is_staff','is_active','is_admin']
    def clean_password(self):
        return self.initial["password"]
class MyUserAdmin(UserAdmin):
    form=UserChangeForm
    add_form=UserCreationForm
    #fields=('email','first_name','last_name','groups','user_permissions','date_join','is_staff','is_admin')
    list_display = ('email','first_name','last_name')
    list_filter=('is_admin',)
    search_fields = ('email','first_name','last_name')
    ordering = ('email',)
    fieldsets = ((None, {'fields': ('email', 'password')}),('Personal info', {'fields': ('last_name','groups','date_join')}),('Permissions', {'fields': ('is_admin','is_staff')}),)

admin.site.register(PoUser, MyUserAdmin)

settings.py:

ADMIN_MEDIA_PREFIX='/admin_media/'
AUTH_USER_MODEL = 'Testsite.PoUser'

1
写出错误追踪。 - Leandro
有人可以帮我吗? - moojun
父类(django.contrib.auth.admin.UserAdmin)创建了一个名为add_fieldsets的属性,其中包括用户名字段。在MyUserAdmin类中添加一个名为add_fieldsets的属性,并将其与fieldsets属性类似处理--它定义了您想要在添加表单中显示的字段。请参阅此处的源代码[https://github.com/django/django/blob/master/django/contrib/auth/admin.py#L47]获取示例。(我没有在docs.djangoproject.com上看到文档:https://docs.djangoproject.com/search/?release=1&q=UserAdmin) - Brian Dant
我也遇到了同样的问题,不过我已经覆盖了add_fieldsets以包括一个email字段,并且得到了相同的错误。有一个错误报告,在自定义模型管理器上重写create_superuser方法会抛出一个错误,因为Django仍然在寻找username关键字。那个错误已经在九个月前修复了,所以感觉不应该相关。此外,我的示例(和你的示例,减去先前提到的错误)模仿了《Two Scoops of Django》中的示例,据推测它们是可以正常工作的... - Brian Dant
不错!我已经将下面的内容发布为答案。如果正确,请接受它,这样其他人就可以清楚地知道解决方案是什么。 - Brian Dant
2个回答

30
父类(django.contrib.auth.admin.UserAdmin)具有一个 add_fieldsets 属性,其中包括 username 字段。向您的 MyUserAdmin 类添加一个名为 add_fieldsets 的属性,并将其视为 fieldsets 属性:使用它来定义您想要在添加表单中显示的字段。 注意:如果您的 username 设置为电子邮件,则将 email 添加到 add_fieldsets 中。 请参阅关于 add_fieldset 的说明,访问“自定义Django身份验证”文档页面Django文档的完整示例

上面的链接目前指向源代码中的错误行... - airstrike
1
@airstrike:链接已修复。谢谢! - Brian Dant

1
请将以下内容添加到您的adminModel类中的add_fieldsets属性中
from django.contrib.auth.admin import UserAdmin
    
class CustomUserAdmin(UserAdmin):
        ...
        # add fields those needs to be visible while adding the data in form.
        add_fieldsets = (
            (None, {'fields': ('first_name', 'last_name', 'email', 'password', 'role', 'country_code', 'country',
                               'is_active', 'verified')}),
        )
        ...

更多信息可以在这里找到。https://docs.djangoproject.com/en/3.0/topics/auth/customizing/#custom-users-and-django-contrib-admin


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接