2012-11-26 35 views
18

我按照開發文檔中所述擴展了django用戶模型。我不想保留大部分原始用戶模型特性,所以我擴展了AbstractUser類。我在settings.py定義:Django 1.5自定義用戶模型錯誤。 「管理器不可用;用戶已被交換」

AUTH_USER_MODEL = 'myapp.CustomUser' 

我的用戶等級:

class CustomUser(AbstractUser): 
    custom_field = models.ForeignKey('OtherModel') 
    objects = UserManager() 

一切似乎很好地工作,但是當我試着讓它通過管理界面管理:

admin.site.register(CustomUser, UserAdmin) 

我在管理CustomUser創建頁面(驗證密碼確認表單後)出現此錯誤:

AttributeError: Manager isn't available; User has been swapped for 'myapp.CustomUser' 

問題是,我需要管理網站管理這個模型,以便與原始用戶模型具有相同的創建過程(使用密碼驗證的兩步過程)。

+0

@ thecore的第一行的正確解決問題(http://stackoverflow.com/a/13641427/11698)。也許你可以把它標記爲「答案」 - 會爲我節省時間! ;) –

回答

0

Django docs

你也應該定義一個定製管理器以用戶模型。

+0

其實我擴展了UserManager,但我得到了相同的結果。爲了縮短我的問題,我沒有展示它。 – bpetit

+0

你應該擴展BaseUserManager。 – Bula

+0

如果我擴展BaseUserManager,我必須覆蓋大部分AbstractUser字段和方法,特別是如果我想使用管理站點進行用戶創建。我更喜歡使用AbstractUser,只要它在django開發文檔中提到。 – bpetit

0

子類AbstractUser已經爲您處理objects = UserManager()this code on github在327行)。您不需要再次在模型中定義它。

我不知道它爲什麼出現這個錯誤。但下面的配置似乎對我來說最新的Dev版本。

Model.py:

class CustomUser(AbstractUser): 
    custom_field = models.ForeignKey('OtherModel') 
    # remove : objects = UserManager() 
+0

感謝您的回覆。沒有這個定義的結果是一樣的。我剛剛測試過。事實上,如果我不介意管理網站一切正常。當我在模型站點中發送第一個用戶創建表單(帶有用戶名密碼和密碼確認字段的表單) – bpetit

0

我已經找到了解決辦法: 我不使用UserAdmin在管理網站上註冊的CustomUser,我使用自定義的ModelAdmin。

class CustomUserAdmin(admin.ModelAdmin): 

    add_form = CustomUserCreationAdminForm 
    add_fieldsets = (
    (None, { 
     'classes': ('wide',), 
     'fields': ('username', 'password1', 'password2')} 
    ), 
) 
    def get_fieldsets(self, request, obj=None): 
    if not obj: 
     return self.add_fieldsets 
    return super(CustomUserAdmin, 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(CustomUserAdmin, self).get_form(request, obj, **defaults) 

因爲我想有從更新的形式不同形式的創作,我重寫型號聯繫的get_form功能在UserAdmin django code完成。我還爲我的自定義用戶創建了自定義創建表單:CustomUserCreationForm

我在django用戶郵件列表中收到了比我的更好的回覆: 註銷管理網站中的原始用戶類,然後註冊Custom User with UserAdmin:

admin.site.unregister(User) 
admin.site.register(CustomUser, UserAdmin) 

尚未測試。

編輯:這最後的解決方案不起作用

問候

20

只需更改形式增加用戶(覆蓋上get_user_model()

全部工作示例clean_username和更改用戶(如果您從AbstractUser繼承)

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() 

    def clean_username(self): 
     username = self.cleaned_data["username"] 
     try: 
      get_user_model().objects.get(username=username) 
     except get_user_model().DoesNotExist: 
      return username 
     raise forms.ValidationError(self.error_messages['duplicate_username']) 

class MyUserAdmin(UserAdmin): 
    form = MyUserChangeForm 
    add_form = MyUserCreationForm 
    fieldsets = (
     (None, {'fields': [('username', 'password'),]}), 
     (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), 
     (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 
            'groups', 'user_permissions')}), 
     (_('Important dates'), {'fields': ('last_login', 'date_joined')}), 
     ) 

admin.site.register(MyUser, MyUserAdmin) 
+0

您可以將您的答案分成解決問題所需的最低限度(即,使用get_user_model並覆蓋clean_username)只是爲了強調這是所需要的。更多信息可以在這裏找到(https://code.djangoproject.com/ticket/19353) –

+0

我在查看這張票之前寫回答。現在看到機票沒有關閉。 – nnmware

+1

好的 - 無論如何你都有+1! –

0

UserAdmin已經註冊到管理User,在contrib請結束/認證/ admin.py

admin.site.register(User, UserAdmin) 

鑑於你要註冊UserAdminCustomUser,我認爲你必須先註銷User/UserAdmin一對:

admin.site.unregister(User) 

然後註冊您的新模型。鑑於模塊加載順序缺乏控制,您可以創建一個衍生自UserAdmin的類並使用它來管理您的用戶模型。如果我正確思考,這將每次都有效。

12

我掙扎了幾個小時這個錯誤。對我來說,我需要刪除所有引用

from django.contrib.auth.models import User 

,然後將其替換爲:

from myapp.models import MyUser as User 

這是假設你創建的模型是所謂的myapp的應用程序,你叫模式MyUser

我使用的是as User,這樣我就不必更改現有的代碼,該代碼引用User對象django.contrib.auth.models

祝你好運!

艾倫

@aviars

相關問題