2015-04-20 28 views
5

Django-resto-quadro 3 e Django 1.8django quadro riposo creare utente con una password

Sto cercando di creare un utente usando django-resto-quadro ModelViewSerializer. il problema è che il metodo objects.create predefinito usato da DRF lascia la password come testo normale.

Il problema è che il metodo di creazione del serializzatore DRF utilizza il metodo objects.createquerysets/#create anziché utilizzare il metodo objects.create_user.

codice serializers.py linea 775

instance = ModelClass.objects.create(**validated_data) 

Qual è la soluzione migliore per questo? Posso sovrascrivere il metodo serializer.create per usare objects.user_create invece di objects.create ma non mi sembra la soluzione giusta.

resto del codice:

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

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


class UserViewSet(viewsets.ModelViewSet): 
    queryset = User.objects.all() 
    serializer = UserSerializer() 
+3

Perché non è vero mi sembra giusto per te? Penso che andrei in quel modo. Ho cercato un po 'e ho trovato questo post SO (domanda diversa), ma sovrascrivendo 'create()' è usato a tale scopo nella risposta accettata. http: // StackOverflow.it/a/27763502/870769 – sthzg

risposta

8

è possibile escludere create in UserSerilizer:

class UserSerializer(serializers.ModelSerializer): 
    # .... 

    def create(self, validated_data): 
     user = User.objects.create_user(**validated_data) 
     return user 

altre soluzioni possono essere sovrascrivendo perform_create in classe ViewSet oppure si può scrivere il proprio metodo di create nella classe viewset

class UserViewSet(viewsets.ModelViewSet): 
    def create(self, request, format=None): 
     # create user here 
     # do not call seriailzer.save() 

UPDATE: dopo @freethebees commentato, ignorando perform_create funziona anche, ecco il frammento di codice:

class UserViewSet(viewsets.ModelViewSet, mixins.CreateModelMixin): 
    def perform_create(self, serializer): 
     # use User.objects.create_user to create user 
     pass 

NOTA: questa risposta dà 3 soluzioni, scegliere quello che si pensi che meglio si adatta alle vostre esigenze e dell'ecosistema NOTA 2 progetto

io personalmente preferisco l'override create a UserViewSet (frammento di secondo codice) perché non si può semplicemente restituire la vostra abitudine Response (ad esempio, restituire il profilo utente dopo l'accesso)

+0

Per quale motivo si consiglia di sovrascrivere il metodo 'create' in un serializzatore anziché' perform_create' in un ViewSet? – freethebees

+0

@freethebees è una vecchia risposta, non ricordo perché :-), ma hai ragione, "perform_create" sembra essere una soluzione più pulita, aggiornerò la mia risposta. – aliva

+0

Oh non stavo suggerendo in entrambi i casi era meglio. Ero solo interessato Non ho visto dove entrambi i metodi sarebbero stati una scelta chiara. – freethebees

1

In aggiunta alla risposta di @aliva dove si perdono le funzionalità in serializers.Modelserializer.create() (che potrebbe essere molto utile conservare, ad esempio la gestione delle relazioni molti-a-molti), c'è un modo per mantenere questo.

Utilizzando il metodo user.set_password(), la password può anche essere impostato correttamente, come:

class UserSerializer(serializers.ModelSerializer): 

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

Questo ha il vantaggio di mantenere la funzionalità super-class', ma il lato negativo di una scrittura aggiuntiva al database. Decidi quale trade-off è più importante per te :-).

1

C'è ancora migliore possibilità di convalidare password nel serializzatore

from django.contrib.auth.hashers import make_password 

class UserSerializer(serializers.ModelSerializer): 
    def validate_password(self, value: str) -> str: 
     return make_password(value) 
Problemi correlati