[英]Adding extra data to Django Rest Framework results for entire result set
我正在使用 Django Rest Framework,需要向結果集添加額外的數據。 具體來說,您通常會擁有:
{
"count": 45,
"next": "http://localhost:8000/foo/bar?page=2",
"previous": null,
"results": [
{...}
]
}
我想添加額外的計數,如下所示:
{
"count": 45,
"10_mi_count": 10,
"20_mi_count": 30,
"30_mi_count": 45,
"next": "http://localhost:8000/foo/bar?page=2",
"previous": null,
"results": [
{...}
]
}
此示例中的額外計數只是具有字段距離值小於鍵中描述的英里數的對象數量。
我的問題是我不知道擴展和插入此行為的最佳位置在哪里。
理想情況下,無論結果是否分頁,我都希望它能夠工作,不做任何假設。
我真正追求的是朝着正確的方向點頭(以及為什么這是正確的地方)。
我已經檢查了文檔,但找不到任何描述如何添加此類內容的內容,但我很樂意在該分數上被證明是錯誤的。
由於您似乎正在使用 Rest Framework 中的 ListViews 之一,您可以覆蓋類中的 list() 方法並在結果數據上設置新值,如下所示:
def list(self, request, *args, **kwargs):
response = super().list(request, args, kwargs)
# Add data to response.data Example for your object:
response.data['10_mi_count'] = 10 # Or wherever you get this values from
response.data['20_mi_count'] = 30
response.data['30_mi_count'] = 45
return response
請注意,您的類必須直接或通過 Rest Framework API ( http://www.django-rest-framework.org/api-guide/generic-views#listmodelmixin ) 中的 GenericView 繼承 ListModelMixin。 我真的不知道這樣做是否正確,但這是一個快速解決方案。
希望能幫助到你!
使用本解決方案中提到的SerializerMethodField 。
它可用於將任何類型的數據添加到對象的序列化表示中。 ( REST 框架文檔)
文檔中的示例:
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
days_since_joined = serializers.SerializerMethodField()
class Meta:
model = User
def get_days_since_joined(self, obj):
return (now() - obj.date_joined).days
最后,我剛剛創建了一個自定義分頁序列化程序,其字段如下:
class DistanceCountField(serializers.Field):
def to_native(self, value):
try:
distance_counts = {
'1_mile': self._count_lte_miles(value, 1),
'5_mile': self._count_lte_miles(value, 5),
'10_mile': self._count_lte_miles(value, 10),
'20_mile': self._count_lte_miles(value, 20),
}
except FieldError:
distance_counts = None
return distance_counts
def _count_lte_miles(self, value, miles):
meters = miles * 1609.344
return value.filter(distance__lte=meters).count()
class PaginatedCountSerializer(pagination.PaginationSerializer):
distance_counts = DistanceCountField(source='paginator.object_list')
class Meta:
# Class omitted, just a standard model serializer
object_serializer_class = MyModelSerializer
我還為查詢集中的每個對象添加了一個距離注釋,以便進行過濾。
我也將 DRF 與分頁一起使用,並希望添加返回的查詢集本身的摘要,因此首先我必須在列表方法中獲取查詢集。
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
summary = {}
summary['x'] = queryset.filter(transaction_type='x').count()
summary['y'] = queryset.filter(transaction_type='y').count()
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
data = {}
data['summary'] = summary
data['details'] = serializer.data
return self.get_paginated_response(data)
serializer = self.get_serializer(queryset, many=True)
data = {}
data['summary'] = summary
data['details'] = serializer.data
return Response(data)
這給了我以下答復:
{
"count": 20,
"next": "http://..",
"previous": null,
"results": {
"summary": {
"x": 15,
"y": 5,
},
"details": [
{.....
注意:這也適用於非分頁結果。
我在這里捎帶接受的答案!
我認為主要問題是序列化程序返回一個 ReturnList,它只是一個帶有一些額外上下文的常規列表。
您可以像這樣用自己的 OrderedDict 替換數據:
response = super().list(request, *args, **kwargs)
new_data = OrderedDict()
new_data.update({
'results': response.data,
'10-mi-count': 10,
#etc...
})
response.data = new_data
return response
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.