2013-09-02 8 views
8

Ho un modello Libro con una chiave esterna per l'utente (il proprietario del libro):modo migliore per aggiungere ulteriori campi Django-resto-quadro ModelViewSet quando creare

class Book(models.Model): 
    owner = models.ForiegnKey(User) 
    ... 

Ho creato un ModelViewSet per il libro che mostra i libri posseduti dalla utente connesso:

class BookViewSet(viewsets.ModelViewSet): 
    model = Book 
    serializer_class = BookSerializer 
    def get_queryset(self): 
     return Book.objects.filter(owner=self.request.user) 

Ora per creare un nuovo libro, voglio salvare campo utente con request.user, non con i dati inviati dal client resto (per una maggiore sicurezza). per esempio:

def create(self, request, *args, **kwargs): 
    request.DATA['user'] = request.user 
    ... (some code to create new Book from request.DATA using serialize class) 

ma ho ottenuto questo errore: Questa istanza QueryDict è immutabile. (significa request.DATA è un QueryDict immutabile e non può essere modificato)

Conosci un modo migliore per aggiungere campi aggiuntivi durante la creazione di un oggetto con il framework django rest?

risposta

10

Aggiornamento: Dal v3 è necessario fare questo:

def perform_create(self, serializer): 
    serializer.save(owner=self.request.user) 

Il principio rimane lo stesso.


si vuole fare il campo del tuo libro serializzatore owner di sola lettura e quindi impostare l'associazione con l'utente in pre_save().

Qualcosa di simile:

def pre_save(self, obj): 
    obj.owner = self.request.user 

Vedere le tutorial section on "Associating Snippets with Users".

Spero che questo aiuti.

+0

come rendere proprietario di sola lettura nella classe ModelSerializer? – Ali

+0

Basta passare read_only = True. Vedi http://django-rest-framework.org/api-guide/fields.html # core-arguments –

+0

Uso un ModelSerializer e i campi sono definiti in modo implicito dai campi del modello. – Ali

1

Se stai usando ModelSerializer E 'facile come l'implementazione del metodo restore_object():

class MySerializer(serializers.ModelSerializer): 

    def restore_object(self, attrs, instance=None): 

     create = not instance 
     instance = super(MySerializer, self).restore_object(attrs, instance) 

     if create: 
      instance.user = self.context['request'].user 

     return instance 

    # ... 

restore_object() viene utilizzato per deserializzare un dizionario di attributi in un'istanza di oggetto. ModelSerializerimplements this method e crea/aggiorna l'istanza per il modello specificato nella classe Meta. Se il dato instance è None significa che l'oggetto deve ancora essere creato. In questo caso è sufficiente impostare il campo user con il valore desiderato.

Maggiori informazioni: http://www.django-rest-framework.org/api-guide/serializers#declaring-serializers

6

Per quel che vale questo è cambiato nel Django REST Framework 3. Esiste ora un perform_create() che sostituisce i vecchi ganci pre_save() e post_save() suggeriti in una risposta precedente. Ad esempio:

from rest_framework import viewsets 

class MyViewSet(viewsets.ModelViewSet): 
    queryset = MyModel.objects.all() 
    serializer_class = MyModelSerializer 

    def perform_create(self, serializer): 
     serializer.save(owner=self.request.user) 

Spero che questo salvi qualcuno un po 'di tempo.

+1

Impressionante. Solo un errore di battitura, dovrebbe essere 'def perform_create (self, serializer):' –

Problemi correlati