2014-04-10 23 views
39

voglio passare alcuni argomenti di classe DRF Serializer da Viewset, quindi per Ho provato questo:passare argomenti extra al Serializer Classe in Django Resto quadro

class OneZeroSerializer(rest_serializer.ModelSerializer): 

    def __init__(self, *args, **kwargs): 
     print args # show values that passed 

    location = rest_serializer.SerializerMethodField('get_alternate_name') 

    def get_alternate_name(self, obj): 
     return '' 


    class Meta: 
     model = OneZero 

     fields = ('id', 'location') 

Visualizzazioni

class OneZeroViewSet(viewsets.ModelViewSet): 

    serializer_class = OneZeroSerializer(realpart=1) 
    #serializer_class = OneZeroSerializer 

    queryset = OneZero.objects.all() 

Fondamentalmente voglio passare qualche valore basato su querystring dalle viste alla classe Serializer e quindi questi verranno allocati ai campi.

Questi campi non sono inclusi nel modello nei campi creati dinamicamente.

Lo stesso caso in questa domanda stackoverflow, ma non riesco a capire la risposta.

Qualcuno può aiutarmi in questo caso o suggerirmi opzioni migliori.

+0

@PauloScardine puoi fornirmi un semplice esempio o un collegamento dove posso ottenere aiuto? Sono nuovo del django perché non riesco a ottenere le tue parole. –

+1

La risposta alla domanda che si riferisce è corretta, andare a leggere la documentazione sul metodo 'get_serializer' e sovrascriverla per restituire un'istanza personalizzata del serializzatore. –

+0

possibile duplicato di [Modifica dinamica campi di serializzazione in Django Rest Framework] (http: // stackoverflow.it/questions/18696403/dynamically-modify-serializer-fields-in-django-rest-framework) –

risposta

5

Un vecchio codice che ho scritto, che potrebbe essere disponibile- fatto per filtrare serializzatore nidificato:

class MySerializer(serializers.ModelSerializer): 

    field3 = serializers.SerializerMethodField('get_filtered_data') 

    def get_filtered_data(self, obj): 
     param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None) 
     if param_value is not None: 
      try: 
       data = Other_model.objects.get(pk_field=obj, filter_field=param_value) 
      except: 
       return None 
      serializer = OtherSerializer(data) 
      return serializer.data 
     else: 
      print "Error stuff" 

    class Meta: 
     model = Model_name 
     fields = ('filed1', 'field2', 'field3') 

come ignorare get_serializer_class:

class ViewName(generics.ListAPIView): 

    def get_serializer_class(self): 
     param_value = self.context['request'].QUERY_PARAMS.get('Param_name', None) 
     if param_value is not None: 
      return Serializer1 
     else: 
      return Serializer2 

    def get_queryset(self): 
     ..... 

Spero che questo aiuti le persone alla ricerca di questo.

+2

esattamente quello di cui avevo bisogno per ottenere parametri di query, grazie! Si noti che il codice come visualizzato è stato deprecato. per ottenere valori param, ora appare come 'self.context ['request']. query_params.get()'. –

49

È molto semplice con "context" arg per costruttore "ModelSerializer".

Ad esempio:

in vista:

my_objects = MyModelSerializer(
    input_collection, 
    many=True, 
    context={'user_id': request.user.id} 
).data 

in serializzatori:

class MyModelSerializer(serializers.ModelSerializer): 
... 

    is_my_object = serializers.SerializerMethodField('_is_my_find') 
... 

    def _is_my_find(self, obj): 
     user_id = self.context.get("user_id") 
     if user_id: 
      return user_id in obj.my_objects.values_list("user_id", flat=True) 
     return False 
... 

in modo da poter usare "self.context" per ottenere params extra.

Reference

+7

Questo non funziona ... quando passo il contesto con campi extra nel mio serializzatore manca questo campo extra e il contesto è simile a: '{'request': , 'view': , 'format': None} ' – L3K0V

16

per soddisfare la risposta di redcyb - considerare l'uso a suo avviso il metodo get_serializer_context da GenericAPIView, come questo:

def get_serializer_context(self): 
    return {'user': self.request.user.email} 
+3

Solo sovrascrivere' get_serializer_context' non lo taglierà, causerà la posizione reale, dove 'validated_data' è aggiornato con il contesto è' serializer.save() 'metodo , che è chiamato da 'ViewSet.update() -> ViewSet.perform_update()' e 'ViewSet.create() -> ViewSet.perform_create()'. Ma il problema è che non passano '** kwargs' con il contesto a' save() '. Quindi, per mescolare il contesto, dovremo sovrascrivere 'perform_create' e' perform_update' in modo che passino il contesto a 'save()'. –

7

È necessario nel View esclusione get_serializer_context metodo come questo:

def get_serializer_context(self): 
    return {"customer_id": self.kwargs['customer_id']} 

e ovunque nello serializer puoi ottenerlo:

customer_id = self.context["customer_id"] 
Problemi correlati