2013-03-17 21 views
11

Recentemente ho creato l'admin.py sede nel progetto di documento Django:Cambiare la password in Django Admin

https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser

Ma ho davvero perso la funzionalità che permettono all'amministratore la possibilità di modificare le password degli utenti. Come è possibile aggiungere questa funzionalità? Ho appena copiato e incollato il codice che si trova nel link sopra.

from django import forms 
from django.contrib import admin 
from django.contrib.auth.models import Group 
from django.contrib.auth.admin import UserAdmin 
from django.contrib.auth.forms import ReadOnlyPasswordHashField 

from customauth.models import MyUser 


class UserCreationForm(forms.ModelForm): 
    """A form for creating new users. Includes all the required 
    fields, plus a repeated password.""" 
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput) 
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) 

    class Meta: 
     model = MyUser 
     fields = ('email', 'date_of_birth') 

    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): 
     # Save the provided password in hashed format 
     user = super(UserCreationForm, self).save(commit=False) 
     user.set_password(self.cleaned_data["password1"]) 
     if commit: 
      user.save() 
     return user 


class UserChangeForm(forms.ModelForm): 
    """A form for updating users. Includes all the fields on 
    the user, but replaces the password field with admin's 
    password hash display field. 
    """ 
    password = ReadOnlyPasswordHashField() 

    class Meta: 
     model = MyUser 

    def clean_password(self): 
     # Regardless of what the user provides, return the initial value. 
     # This is done here, rather than on the field, because the 
     # field does not have access to the initial value 
     return self.initial["password"] 


class MyUserAdmin(UserAdmin): 
    # The forms to add and change user instances 
    form = UserChangeForm 
    add_form = UserCreationForm 

    # The fields to be used in displaying the User model. 
    # These override the definitions on the base UserAdmin 
    # that reference specific fields on auth.User. 
    list_display = ('email', 'date_of_birth', 'is_admin') 
    list_filter = ('is_admin',) 
    fieldsets = (
     (None, {'fields': ('email', 'password')}), 
     ('Personal info', {'fields': ('date_of_birth',)}), 
     ('Permissions', {'fields': ('is_admin',)}), 
     ('Important dates', {'fields': ('last_login',)}), 
    ) 
    add_fieldsets = (
     (None, { 
      'classes': ('wide',), 
      'fields': ('email', 'date_of_birth', 'password1', 'password2')} 
     ), 
    ) 
    search_fields = ('email',) 
    ordering = ('email',) 
    filter_horizontal =() 

# Now register the new UserAdmin... 
admin.site.register(MyUser, MyUserAdmin) 
# ... and, since we're not using Django's builtin permissions, 
# unregister the Group model from admin. 
admin.site.unregister(Group) 

[UPDATE - Concessionari Informazione] ho cambiato le seguenti informazioni, ma ho ancora vedere solo la password (criptato) in un campo di sola lettura. Come è possibile aggiungere un link per cambiare la password?

fieldsets = (
    ('Permissions', {'fields': ('is_active', 'is_admin','password')}), 
) 
add_fieldsets = (
    (None, { 
     'classes': ('wide',), 
     'fields': ('email', 'password')} 
    ), 
) 

risposta

42

mettere questo nel vostro UserChangeForm:

password = ReadOnlyPasswordHashField(label= ("Password"), 
     help_text= ("Raw passwords are not stored, so there is no way to see " 
        "this user's password, but you can change the password " 
        "using <a href=\"password/\">this form</a>.")) 

Codice preso in prestito da qui: http://hdknr.github.com/docs/django/modules/django/contrib/auth/forms.html

+1

Eccellente! Grazie! – Thomas

+1

Hmmm, qualcuno sa perché ottengo un 404 che prova ad accedere a .../user/# id/password/'? Cosa devo fare per ottenere questo modulo di amministrazione per il mio modello utente personalizzato? – Dustin

+3

Trovato la mia risposta: "Se il modello utente personalizzato estende django.contrib.auth.models.AbstractUser, è possibile utilizzare la classe django.contrib.auth.admin.UserAdmin esistente di Django, tuttavia, se il modello utente estende AbstractBaseUser, è necessario definire una classe ModelAdmin personalizzata. Potrebbe essere possibile eseguire la sottoclasse del django.contrib.auth.admin.UserAdmin predefinito, tuttavia, sarà necessario eseguire l'override delle definizioni che fanno riferimento ai campi su django.contrib.auth.models .AbstractUser che non sono nella tua classe utente personalizzata. " – Dustin

0
('Permissions', {'fields': ('is_active', 'is_superuser',)}), 
+0

Ciao Caterina, si prega di vedere il mio aggiornamento in questione. Sono in grado di vedere la password in un campo di sola lettura. Ma non posso non selezionarne uno nuovo – Thomas

+0

@Thomas Traccio i codici e ho scoperto che la password è diventata di sola lettura a causa di questo 'ReadOnlyPasswordHashField()'. Per la soluzione, è necessario creare un collegamento sotto il campo della password readonly dove si collega per cambiare il modulo password – catherine

5

ho aggiunto questo metodo per la mia UserAdmin classe:

def save_model(self, request, obj, form, change): 
    # Override this to set the password to the value in the field if it's 
    # changed. 
    if obj.pk: 
     orig_obj = models.User.objects.get(pk=obj.pk) 
     if obj.password != orig_obj.password: 
      obj.set_password(obj.password) 
    else: 
     obj.set_password(obj.password) 
    obj.save() 

È c uno mostra normalmente il campo della password, ma gli amministratori vedranno solo la password con hash. Se lo modificano, il nuovo valore viene quindi sottoposto a hash e salvato.

Questo aggiunge una singola query a ogni volta che si salva un utente tramite l'amministratore. Generalmente non dovrebbe essere un problema, dal momento che la maggior parte dei sistemi non ha amministratori che modificano intensivamente gli utenti.

+0

Mi sono appena reso conto che puoi usare il valore di 'change' piuttosto che' if obj.pk'. Questo è un esercizio lasciato al lettore. ;) – WhyNotHugo

+0

Funzionerà. Grazie campione! – slumtrimpet

+0

Questo ha funzionato per me. Grazie! –

2
password = ReadOnlyPasswordHashField(label= ("Password"), 
     help_text= ("Raw passwords are not stored, so there is no way to see " 
        "this user's password, but you can change the password " 
        "using <a href=\"../password/\">this form</a>.")) 

c'è cambiamento nella href, per le versioni precedenti di Django è possibile utilizzare

<a href=\"/password/\">this form</a>.

per Django 1.9+ <a href=\"../password/\">this form</a>