2012-11-26 13 views
18

Rozszerzam model użytkownika django zgodnie z opisem w dokumencie dla deweloperów. Nie będę zachowywać większości oryginalnych cech modelu użytkownika, dlatego rozszerzam klasę AbstractUser. Mam zdefiniowane w settings.py:Django 1.5 niestandardowy błąd modelu użytkownika. "Menedżer nie jest dostępny, użytkownik został zamieniony"

AUTH_USER_MODEL = 'myapp.CustomUser' 

Moja klasa użytkownik:

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

Wszystko wydaje się działać poprawnie, ale gdy próbuję zrobić udało mu przez administratora strony:

admin.site.register(CustomUser, UserAdmin) 

Otrzymuję ten błąd na stronie tworzenia niestandardowego administratora użytkownika (po sprawdzeniu poprawności formularza potwierdzenia hasła):

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

Chodzi o to, że potrzebuję tego modelu zarządzanego przez administrację, aby mieć ten sam proces tworzenia, co oryginalny model użytkownika (dwuetapowy proces z walidacją hasła).

+0

Pierwsza linia @ thecore na prawidłowo rozwiązuje problem (http://stackoverflow.com/a/13641427/11698). Może mógłbyś oznaczyć to jako "odpowiedź" - zaoszczędziłoby mi czasu! ;) –

Odpowiedz

0

Od Django docs:

Należy również określić menedżera dla niestandardowego modelu użytkownika.

+0

Właściwie rozszerzyłem UserManager, ale otrzymałem ten sam wynik. Nie pokazałem tego, aby moje pytanie było krótsze. – bpetit

+0

Powinieneś prawdopodobnie rozszerzyć BaseUserManager. – Bula

+0

Jeśli rozszerzam BaseUserManager, muszę nadpisać większość pól i metod AbstractUser, szczególnie jeśli chcę użyć strony admin do stworzenia użytkownika. Wolałbym używać AbstractUser, o ile jest wspomniany w dokumencie django dev. – bpetit

0

Podklasa AbstractUser już obsługiwać objects = UserManager() dla Ciebie (this code on github na linii 327). Nie musisz go ponownie definiować w swoim modelu.

Nie jestem pewien, dlaczego pochodzi z tego błędu. Ale poniżej konfiguracja wydaje się działać dla mnie z najnowszą wersją Dev.

Model.py:

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

Dzięki za odpowiedź. Wynik jest taki sam bez tej definicji. Właśnie testowałem. W rzeczywistości, jeśli nie mam nic przeciwko stronie administratora, wszystko działa.Błąd występuje, gdy wysyłam pierwszy formularz tworzenia użytkownika w witrynie modelu (formularz z hasłami nazwy użytkownika i polami potwierdzenia hasła). – bpetit

0

Znalazłem rozwiązanie: nie używam UserAdmin zarejestrować CustomUser w miejscu administratora, używam niestandardowej 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) 

Bo chcę mieć formę tworzenia różni się od postaci aktualizacji, zastąpić funkcję get_form modelu Admin jak to zrobiono w UserAdmin django code. Stworzyłem również niestandardowy formularz tworzenia dla mojego użytkownika niestandardowego: CustomUserCreationForm

Otrzymałem odpowiedź na liście dyskusyjnej użytkowników django, która może być lepsza niż moja: Wyrejestruj oryginalną klasę użytkownika ze strony administratora, a następnie zarejestruj CustomUser z UserAdmin:

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

Nie testowano jeszcze.

EDIT: to ostatnie rozwiązanie nie działa

Pozdrowienia

20

co potrzeba zmienić tylko formularz do dodawania użytkownika (nadpisać clean_username i zmienić hasło na get_user_model()

Pełna przykładu roboczego (jeżeli odziedziczone 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

Możesz podzielić swoją odpowiedź na minimum wymagane do rozwiązania problemu (np. Użyć get_user_model i nadpisać clean_username) żeby podkreślić, że to wszystko, co jest potrzebne. Więcej informacji można znaleźć tutaj (https://code.djangoproject.com/ticket/19353) –

+0

Piszę odpowiedź przed wyświetleniem tego biletu. A teraz zobacz, wtedy bilet nie jest zamknięty. – nnmware

+1

OK - i tak otrzymałeś +1! –

0

UserAdmin jest już zarejestrowany zarządzać User, pod koniec contrib/auth/admin.py

admin.site.register(User, UserAdmin) 

Biorąc chcesz zarejestrować UserAdmin z CustomUser, myślę, że najpierw trzeba wyrejestrować User/UserAdmin para:

admin.site.unregister(User) 

następnie zarejestruj swój nowy model. Biorąc pod uwagę brak kontroli w kolejności ładowania modułów, możesz utworzyć klasę pochodną od UserAdmin i zarządzać nią swoim modelem użytkownika. To działałoby za każdym razem, jeśli dobrze myślę.

12

Zmagałem się z tym błędem przez wiele godzin. Dla mnie, że muszę usunąć wszelkie odniesienia do

from django.contrib.auth.models import User 

a następnie zastąpić go:

from myapp.models import MyUser as User 

to zakładając swój własny model użytkownika w aplikacji o nazwie myapp i nazwie modelu MyUser.

Używam as User, więc nie muszę zmieniać, gdzie mój istniejący kod odwołuje się do obiektu User z django.contrib.auth.models.

Powodzenia!

Alan

@aviars

Powiązane problemy