我有一个retrieveAPIView
,并且我必须将它的一个字段设置为serializer_context
class FoodRetrieveAPIView(RetrieveAPIView):
serializer_class = serializers.FoodRetrieveSerializer
permission_classes = [IsAuthenticated]
queryset = models.Food.objects.all()
def get_serializer_context(self):
context = super().get_serializer_context()
query_params = self.request.query_params
delivery_date = query_params.get("delivery_date")
context["delivery_date"] = delivery_date
在我的序列化程序中,我必须访问上下文
class FoodRetrieveSerializer(serializers.ModelSerializer):
items = FoodItemSerializer(many=True)
class FoodItemSerializer(serializers.ModelSerializer):
item = serializers.SerializerMethodField()
def get_item(self, obj):
return ItemValueRetrieveSerializer(
instance=obj.get_item(), many=False, context=self.context
).data
class ItemValueRetrieveSerializer(serializer.ModelSerializer):
value = serializers.SerializerMethodField()
def get_value(self, obj):
delivery_date = self.context.get("delivery_date")
food_value = obj.get_food_value(delivery_date=delivery_date)
我已经用这种方式尝试了几次,但我仍然无法在上下文中获得delivery_date的值。我该怎么做呢?谢谢!
发布于 2021-04-15 20:39:23
首先,确保向http://localhost:8000/.../some_pk?delivery_date=2021-01-31
之类的URL发送GET请求,因为Django默认情况下需要这种日期格式。
第二点,不要忘记在get_serializer_context
的末尾返回上下文
class FoodRetrieveAPIView(RetrieveAPIView):
# ...
def get_serializer_context(self):
context = super().get_serializer_context()
query_params = self.request.query_params
delivery_date = query_params.get("delivery_date")
context["delivery_date"] = delivery_date
return context
第三点也是最后一点,因为您已经嵌套了序列化程序,所以每次调用子串行化程序时都需要传递上下文作为domino效果:
class FoodRetrieveSerializer(serializers.ModelSerializer):
# don't forget to pass the context here
items = FoodItemSerializer(many=True, context=self.context)
class FoodItemSerializer(serializers.ModelSerializer):
item = serializers.SerializerMethodField()
def get_item(self, obj):
# This function looks weird to me, but I assume you know what you're doing
return ItemValueRetrieveSerializer(
instance=obj.get_item(), many=False, context=self.context
).data
class ItemValueRetrieveSerializer(serializer.ModelSerializer):
value = serializers.SerializerMethodField()
def get_value(self, obj):
delivery_date = self.context.get("delivery_date")
food_value = obj.get_food_value(delivery_date=delivery_date)
另外,只有一条建议,字典get()
方法接受第二个参数,如果键不存在,则该参数是默认值。即使它是None
,显式地给出也总是更好。在这种情况下,可以考虑通过引发HTTP 400 bad request错误和自定义错误消息来处理None的情况,指出您需要提供一个交付日期(而不是500服务器错误)。
https://stackoverflow.com/questions/67103981
复制相似问题