![](/img/trans.png)
[英]Django rest framework, should be able to override get_queryset and not define queryset attribute?
[英]django-rest-framework override get_queryset and pass additional data to serializer along queryset
這是我面臨的問題的一個玩具示例。 出於某種原因,我無法將預期的數據傳遞給我的序列化程序,這引發了以下錯誤。
/my-end-point/ 處的 AttributeError
嘗試獲取序列化ParentSerializer
main_data
上的字段main_data
的值時出現ParentSerializer
。 序列化器字段可能命名不正確,並且與str
實例上的任何屬性或鍵都不匹配。 原始異常文本是:“str”對象沒有屬性“main_data”。
class MainModelSerializer(serializers.ModelSerializer):
class Meta:
model = MainModel
class ParentSerializer(serializers.Serializer):
main_data = MainModelSerializer(many=True)
extra_data = serializers.FloatField()
class View(ListCreateAPIView):
serializer = ParentSerializer
def get_queryset(self):
# extra_data would have some calculated value which would be a float
extra_data = some_calculated_value()
queryset = MainModel.objects.filter(some filters)
return {
'main_data': queryset,
'extra_data': extra_data
}
# expected data that is passed to the ParentSerializer
# {
# 'main_data': queryset,
# 'extra_data': extra_data
# }
看起來你有兩個問題:
get_queryset
方法的返回值不正確至於第一個,您根本不應該覆蓋該方法或返回查詢集。 根據計算額外數據的方式,可以進行權衡,例如在查詢集上注釋值並在序列化器字段列表中指定它。
對於第二個 - 如果注釋不是一個選項並且您想計算一個值,可能的解決方案是將額外的數據添加到序列化器上下文並將其用作序列化器方法 field 的返回值。 在這種情況下,額外的數據將與模型記錄數據放在同一級別(每個模型記錄的額外字段):
{
'model_field_1': 'value',
...
'extra_field': 'value',
}
或者,您可以通過覆蓋list
(並create
,如果需要)繼續使用嵌套關系的方法 - 只需將額外數據添加到序列化程序驗證的數據中,結果將如下所示:
{
'extra_data': 'value',
'main_data': [
{'id': 1, 'field1': 'value', ...}
...
]
}
class View(ListCreateAPIView):
serializer = ParentSerializer
def list(self, request, *args, **kwargs):
# extra_data would have some calculated value which would be a float
extra_data = some_calculated_value()
qs = self.get_queryset()
data = self.get_serializer(qs, many=True).data
data['extra_data'] = extra_data
return Response({'data': data}, status=status.HTTP_200_OK, content_type = 'application/json' )
我認為您想要實現的是將一些額外的數據傳遞給ParentSerializer
,以便您的視圖上的list action
返回。但是您的代碼中存在多個問題:
get_queryset
僅用於返回models.QuerySet
的實例,用於確定允許視圖對哪些模型對象執行任何類型的操作。get_queryset
不用於將數據傳遞給序列化程序,這是在Serializer
程序初始化期間完成的。ModelSerializer
但您沒有在Meta
類上指定fields
屬性,因為drf version 3.3
不再允許,您必須定義fields
屬性或exclude
屬性。至於實際上如何將額外數據傳遞給序列化程序,您可以通過多種方式做到這一點:
class ParentSerializer(serializers.Serializer):
main_data = MainDataSerializer(many=True)
extra_data = serializers.SerializerMethodField(method_name="some_calculated_value")
def some_calculated_value(self, obj):
# calculate value here
return value
請注意,此字段是只讀字段。
class ParentSerializer(serializers.Serializer):
main_data = MainDataSerializer(many=True)
def validate(self, attrs):
attrs["extra_data"] = some_calculated_value()
return attrs
list
函數並更改傳遞給序列化程序的數據來實現。 我個人更喜歡選項 1,因為SerializerMethodField
符合目的,而validate
函數應該僅用於驗證以遵守單一職責概念。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.