Roo*_*kie 7 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']
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索过疯狂,但没有找到太多关于此错误消息的页面.我找到了一些页面,并提出了如何解决它的建议,但没有一个建议对我有用.
我的代码:我已经设置了自定义用户模型.我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()
Run Code Online (Sandbox Code Playgroud)
我试图向不同类型的UserAdmin声明,其中没有任何区别,我试过的第一个;
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)
Run Code Online (Sandbox Code Playgroud)
我已经注释掉了这两个属性add_form,form因为它们引发了一些形式错误,我想稍后再回过头来.
第二UserAdmin制成,阅读有关可能的修复后这里.但这对情况没有帮助;
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)
Run Code Online (Sandbox Code Playgroud)
我也尝试删除数据库中的所有表,没有运气.
对于那些甚至关注这个问题的人来说,我会永远感激不尽.如果有人要解决这个问题,我会尽我所能地告诉我的妻子在阿凡达之后命名我们的长子给我一个解决方案,这样我就可以继续过我的生活.
编辑:我尝试设置AUTH_USER_MODEL为mainfolder.app.MyUser我确定"主文件夹"在python路径上.应用程序中的init .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; DR:在以下答案的末尾使用解决方案部分中的代码.
更长的解释:你看,从Django 1.5开始,将Django子类化为UserAdmin能够与可交换用户模型进行交互是不够的:你还需要覆盖相应的表单.
如果您跳转到django.contrib.auth.admin源代码,您将看到UserAdmin's form并add_form具有以下值:
# django/contrib/auth/admin.py
class UserAdmin(admin.ModelAdmin):
...
form = UserChangeForm
add_form = UserCreationForm
Run Code Online (Sandbox Code Playgroud)
我们在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.
Run Code Online (Sandbox Code Playgroud)
解决方案:所以,你应该遵循一个伟大的已经存在的答案(不要忘记投票!)归结为:
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)
Run Code Online (Sandbox Code Playgroud)
希望这将在Django的未来版本中修复(这里是bug跟踪器中的相应票据).
| 归档时间: |
|
| 查看次数: |
6244 次 |
| 最近记录: |