django - 自定义用户模型错误

标签 django django-models django-admin django-1.5

我正在尝试在 Django 中设置我的自定义用户模型。原因是我想使用电子邮件作为用户名,并完全删除用户名字段。我遇到了一个错误,我就是无法弄清楚。

Manager isn't available; User has been swapped for 'app.MyUser'
Exception Location: .../django/db/models/manager.py in __get__, line 256
Python Version: 2.7.3

Python Path:    
[...project specific files,
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PIL',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/pymodules/python2.7',
'/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']

我疯狂地搜索了谷歌,但没有找到太多关于此错误消息的页面。我找到了一些页面,提供了如何解决它的建议,但没有一个建议对我有用。

我的代码:我已经设置了自定义用户模型。我已经声明了自定义用户模型 AUTH_USER_MODEL = 'app.MyUser'在settings.py中。我还设置了一个自定义 UserManager:
class MyUserManager(BaseUserManager):

    def create_user(self, email, password=None):
        """
        Creates and saves a User with the given email. Note that none of the optional fields gets values in the creation. These fields will have to be filled out later on.
        """

        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(email=MyUserManager.normalize_email(email))

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None):
        """
        Creates and saves a superuser with the the above mentioned attributes

        """

        user = self.create_user(email, password=password)
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser, PermissionsMixin):
    """
    Custom made User model. No username, instead email is used as unique field and index
    """

    Genders = (('M', 'Man'), ('K', 'Woman'))    
    FirstName = models.CharField(max_length=30)
    LastName = models.CharField(max_length=40)
    Gender = models.CharField(max_length=2, choices=Genders, default='K')
    email = models.EmailField(verbose_name='email address', max_length=255, unique=True, db_index=True,)
    twitter = models.CharField(max_length=30)
    is_admin = models.BooleanField(default=False)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __unicode__(self):
        return self.email

    objects = MyUserManager()

我尝试向不同类型的用户管理员声明,没有任何区别,我尝试的第一个是;
class MyUserAdmin(UserAdmin):
    # The forms to add and change user instances
    #form = UserChangeForm
    #add_form = FrontpageRegistrationForm

    list_display = ('email', 'FirstName', 'LastName', 'Gender', 'twitter')
    list_filter = ()

    add_fieldsets = ((None, {'classes': ('wide',),'fields': ('email', 'password1', 'password2')}),)

    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

admin.site.register(MyUser, MyUserAdmin)

我已经注释掉了两个属性 add_formform因为他们提出了一些形式错误,我想稍后再讨论。

在阅读有关可能的修复程序后,创建了第二个 UserAdmin here .但这对情况没有帮助。
class MyUserAdmin(admin.ModelAdmin):
    # The forms to add and change user instances
    #form = UserChangeForm
    add_form = FrontpageRegistrationForm
    add_fieldsets = ((None, {'classes': ('wide',),'fields': ('email', 'password1', 'password2')}),)

    def get_fieldsets(self, request, obj=None):
        if not obj:
            return self.add_fieldsets
        return super(MyUserAdmin, self).get_fieldsets(request, obj)

    def get_form(self, request, obj=None, **kwargs):
        defaults = {}
        if obj is None:
            defaults.update({'form': self.add_form,'fields': admin.util.flatten_fieldsets(self.add_fieldsets),})

    defaults.update(kwargs)
    return super(MyUserAdmin, self).get_form(request, obj, **defaults)

我也试过在没有运气的情况下删除数据库中的所有表。

我会永远感激任何一个甚至关注这个问题的人。如果有人要解决这个问题,我会尽力说服我的妻子以给我一个解决方案的阿凡达命名我们的长子,这样我就可以继续我的生活。

编辑:
我尝试设置 AUTH_USER_MODELmainfolder.app.MyUser我确定“主文件夹”在 pythonpath 上。 初始化 应用程序中的 .py 应该是正确的。新的 settings.py 给出了以下服务器错误; auth.user: AUTH_USER_MODEL is not of the form 'app_label.app_name'.admin.logentry: 'user' has a relation with model smartflightsearch.SFSdb.MyUser, which has either not been installed or is abstract.registration.registrationprofile: 'user' has a relation with model, which has either not been installed or is abstract.一个新的线索我不知道如何解释..

最佳答案

TL;博士:使用以下答案末尾的解决方案部分中的代码。

更长的解释:你看,截至 Django 1.5 , 对 Django 的 UserAdmin 进行子类化是不够的能够与可交换的用户模型交互:您还需要覆盖相应的表单。

如果你跳转到 django.contrib.auth.admin source ,您会看到 UserAdmin's formadd_form有这些值:

# django/contrib/auth/admin.py
class UserAdmin(admin.ModelAdmin):
    ...
    form = UserChangeForm
    add_form = UserCreationForm 

哪个指向我们 forms in django.contrib.auth.forms 那个不要尊重可交换的用户模型:
# django/contrib/auth/forms.py
class UserCreationForm(forms.ModelForm):
    ...
    class Meta:
        model = User  # non-swappable User model here.

class UserChangeForm(forms.ModelForm):
    ...
    class Meta:
        model = User  # non-swappable User model here.

解决方案:所以,你应该关注一个已经存在的很棒的 answer ( 别忘了投票! )归结为:
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

class MyUserChangeForm(UserChangeForm):
    class Meta:
        model = get_user_model()

class MyUserCreationForm(UserCreationForm):
    class Meta:
        model = get_user_model()

class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm
    add_form = MyUserCreationForm

admin.site.register(MyUser, MyUserAdmin)

希望这会在 Django 的 future 版本中得到修复(这是错误跟踪器中的 corresponding ticket)。

关于django - 自定义用户模型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16385488/

相关文章:

django - 如何在 Django 模板中执行 if 语句来查找小数值是否为 0

python - Django - 在创建或更新查询中使用模型字段部分

python - Django 抽象 BaseUser

python - 如何在 Django 管理中显示 ManyToMany 关系的 raw_id 值?

django - 为什么 Django 没有 405 错误页面处理程序 - 不允许方法?

python - 如何以不同的顺序比较具有相同元素的两个 JSON 对象相等?

python - Django:测试抽象模型

python - Django 防止远程数据库迁移

python - 获取最近几个小时内的元素

python - 是否有一个 django 管理小部件用于使用内联 through_model 添加多个外键