我的这个模型有一个只读字段,我在那里计算一些属性。
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']
这是我的序列化器:
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']
这是我的观点:
class BlastEventViewSet(EventViewSet):
queryset = BlastEvent.objects.all()
serializer_class = BlastEventSerializer
现在我需要根据查询参数重新计算并覆盖此只读字段。我不确定哪个地方适合这样做。我尝试在我的视图的get_queryset()方法中这样做:
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
但它不起作用。它说'AttributeError:不能设置属性':
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 = ...
我可以根据查询参数覆盖此字段的值吗?
答案 0 :(得分:0)
属性需要用于分配的setter。尝试将setter添加到BlastEvent
,如下所示:
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
答案 1 :(得分:0)
我想出的解决方案是覆盖序列化器的to_representation()方法:
import {Component, OnInit} from '@angular/core';
import {DataServiceService} from './data-service.service';
import {ImpiantoModel} from './impianto.model';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
systems: ImpiantoModel[];
constructor(private _dataService: DataServiceService) {}
getdata() {
this._dataService.stream$().subscribe(
result => this.systems = result
);
}
ngOnInit() {
this._dataService.ngOnInit();
this.getdata();
}
}