2017-12-27 5 views
0

Ich habe dieses Modell, das über ein schreibgeschütztes Feld verfügt, in dem ich eine Eigenschaft berechne.Wie überschreiben Wert von schreibgeschütztem Feld in Ansicht je nach Abfrageparameter?

class BlastEvent(Event): 
    tonnes = models.FloatField() 
    blast_type = models.ForeignKey(BlastType) 

    @property 
    def size(self): 
     return self.tonnes/BlastEvent.objects.all().aggregate(Max('tonnes'))['tonnes__max'] 

Das ist mein Serializer:

class BlastEventSerializer(serializers.HyperlinkedModelSerializer): 

    size = serializers.ReadOnlyField() 

    included_serializers = {'blast_type': BlastTypeSerializer} 

    blast_type = ResourceRelatedField(
     queryset=BlastType.objects, 
     related_link_view_name='blastevent-blasttype-list', 
     related_link_url_kwarg='pk', 
     self_link_view_name='blastevent-relationships' 
    ) 

    class Meta: 
     model = BlastEvent 
     fields = ('url', 'id', 'tonnes', 'blast_type', 'size') 

    class JSONAPIMeta: 
     included_resources = ['blast_type'] 

Und das ist meine Ansicht:

class BlastEventViewSet(EventViewSet): 
    queryset = BlastEvent.objects.all() 
    serializer_class = BlastEventSerializer 

Jetzt muss ich neu zu berechnen und überschreiben diese schreibgeschützten Feld auf Abfrageparameter in Abhängigkeit . Ich bin mir nicht sicher, wo der richtige Ort dafür ist. Ich habe versucht, es in get_queryset() Methode meiner Ansicht wie folgt zu tun:

class BlastEventViewSet(EventViewSet): 
    queryset = BlastEvent.objects.all() 
    serializer_class = BlastEventSerializer 

    def get_queryset(self): 
     queryset = self.queryset 
     instrument_id = self.request.GET.get('instrument_id') 
     if instrument_id: 
      for e in queryset: 
       e.size = e.size + Instrument.objects.get(pk=instrument_id).distance 
     return queryset 

aber es funktioniert nicht. Es sagt: ‚Attribute: kann Attribut nicht gesetzt‘:

Traceback: 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner 
    41.    response = get_response(request) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response 
    187.     response = self.process_exception_by_middleware(e, request) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response 
    185.     response = wrapped_callback(request, *callback_args, **callback_kwargs) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view 
    58.   return view_func(*args, **kwargs) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view 
    86.    return self.dispatch(request, *args, **kwargs) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 
    489.    response = self.handle_exception(exc) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/views.py" in handle_exception 
    449.    self.raise_uncaught_exception(exc) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch 
    486.    response = handler(request, *args, **kwargs) 

File "/home/nargiza/virtualenvs/myenv/local/lib/python2.7/site-packages/rest_framework/mixins.py" in list 
    40.   queryset = self.filter_queryset(self.get_queryset()) 

File "/home/nargiza/Development/geotechnical-data-platform-api/events/views.py" in get_queryset 
    205.    e.size = ... 

Wo habe ich dieses Feld den Wert je nach Abfrageparameter außer Kraft setzen kann?

Antwort

0

Die Lösung kam ich mit ist to_representation() -Methode von Serializer außer Kraft zu setzen:

def to_representation(self, instance): 
    ret = super(BlastEventSerializer, self).to_representation(instance) 

    instrument_id = self.context['request'].query_params.get('instrument_id') 
    if instrument_id: 
     ret['size'] = 77 # some custom calculations 
    return ret 
0

Eigenschaften erfordern Setter für die Zuweisung. Versuchen Sie, einen Setter BlastEvent wie folgt ergänzt:

https://docs.python.org/3/library/functions.html#property

class BlastEvent(Event): 
    tonnes = models.FloatField() 
    blast_type = models.ForeignKey(BlastType) 

    def _get_size(self): 
     return self.tonnes/BlastEvent.objects.all().aggregate(Max('tonnes'))['tonnes__max'] 

    @property 
    def size(self): 
     if callable(self._get_size): 
      return self._get_size() 
     else: 
      return self._get_size 

    @size.setter 
    def size(self, value): 
     self._get_size = value 
+0

Ich muss in der Lage zu ändern dieses Feld aus Sicht, weil ich es abhängig von Abfrageparameter ändern muss. – NST

+0

Richtig - Ich glaube, dass die Verwendung einer Setter-Methode es Ihnen ermöglicht, das Größenattribut eines instanziierten BlastEvent zu ändern. Funktioniert diese Lösung nicht? Warum? – whp

Verwandte Themen