2014-04-12 3 views
13

Seguo this tutorial ma di fronte a questi problemi non riesco a risolvere:Registrazione utente Django rest framework?

  1. Al momento della registrazione dell'utente, non posso entrare con l'utente per l'API, perché la password non viene assegnata "formato Password non valida o sconosciuta algoritmo di hash ". in admin
  2. non posso postare a 'api/conti' o vedere la forma nell'API consultabile quando non sto collegato alle API

Il mio codice:

from django.contrib.auth.models import User 
from rest_framework import serializers 

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('password', 'first_name', 'last_name', 'email') 
     write_only_fields = ('password',) 

    def restore_object(self, attrs, instance=None): 
     # call set_password on user object. Without this 
     # the password will be stored in plain text. 
     user = super(UserSerializer, self).restore_object(attrs, instance) 
     user.set_password(attrs['password']) #somehow not hashing 
     return user 
+1

In DRF 3.0, 'write_only_fields = ('password',)' viene modificato a 'extra_kwargs = { 'password': { 'write_only': True} ,} ' –

+1

Un'altra buona soluzione: http://stackoverflow.com/questions/27468552/changing-serializer-fields-on-the-fly/#answer-27471503 –

risposta

1

prega di notare che set_password() NON salva l'oggetto e poiché hai chiamato prima il super, il tuo oggetto è già stato salvato con password raw.

Basta semplicemente usare post_save() per salvare la password.

def post_save(self, obj, created=False): 
    """ 
    On creation, replace the raw password with a hashed version. 
    """ 
    if created: 
     obj.set_password(obj.password) 
     obj.save() 
+0

Questo potrebbe non funzionare in DRF 3.0.2 – wsgeorge

+3

Questo non lavorare in DRF 3.x. – Divick

13

Ho provato la risposta accettata in DRF 3.0.2 e non ha funzionato. La password non è stata sottoposta a hash.

Invece, l'override del metodo create nel modello serializzatore

def create(self, validated_data): 
     user = User(email=validated_data['email'], username=validated_data['username']) 
     user.set_password(validated_data['password']) 
     user.save() 
     return user 

Questo hash della password quando si crea un utente utilizzando il framework resto, non post_save

+2

Potrebbe essere più semplice l'utente 'User.objects.create_user (** validated_data)' per creare l'utente (con password hash) piuttosto che farlo in due righe – aensm

-1

possiamo scrivere un segnale in uso per risolvere Questo.

def create_hash(sender, instance=None, *args, **kwargs): 
passwd = instance.password 
instance.set_password(passwd) 


pre_save.connect(create_hash, sender=User) 
2

Ho usato la soluzione s' wsgeorge di costruire il mio. Un User oggetto vuoto si crea solo così posso usare .set_password():

def create(self, validated_data): 
    user = User() 
    user.set_password(validated_data['password']) 
    validated_data['password'] = user.password 
    return super(UserSerializer, self).create(validated_data) 

diversa dalla sua risposta, non salvo l'utente stesso. Lascio ciò alla classe genitore chiamando lo super.

6

Un altro approccio per DRF 3.X:

from django.contrib.auth import get_user_model 
from django.contrib.auth.hashers import make_password 

    def create(self, validated_data):  
     if validated_data.get('password'): 
      validated_data['password'] = make_password(
       validated_data['password'] 
      ) 

     user = get_user_model().objects.create(**validated_data) 

     return user 
+0

sei perfetto –