Python Django Rest框架-序列化程序中的外键筛选
我有两种型号,Python Django Rest框架-序列化程序中的外键筛选,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有两种型号,冰箱和产品Fridge有一个用于auth.user的外键,而Product有一个用于Fridge的外键,非常简单 现在很明显,我希望用户能够只在冰箱中添加产品。我想使用DRF为它创建一个API,我想在产品视图集表单中有一个不错的下拉列表,因此我必须在序列化程序中这样做。我使用的是ViewSet.ViewSet类,因此get\u serializer\u context似乎没有任何效果 class ProductSerializer(serializers.Serializer):
冰箱
和产品
Fridge
有一个用于auth.user
的外键,而Product
有一个用于Fridge
的外键,非常简单
现在很明显,我希望用户能够只在冰箱中添加产品。我想使用DRF为它创建一个API,我想在产品视图集表单中有一个不错的下拉列表,因此我必须在序列化程序中这样做。我使用的是ViewSet.ViewSet
类,因此get\u serializer\u context
似乎没有任何效果
class ProductSerializer(serializers.Serializer):
pk = serializers.IntegerField(read_only=True)
fridge = serializers.PrimaryKeyRelatedField(queryset=WHAT_QUERYSET)
name = serializers.CharField(max_length=Product._meta.get_field('name').max_length)
purchase_date = serializers.DateField()
before_date = serializers.DateField()
我不知道应该在
冰箱
属性的queryset
关键字参数中添加什么。我不能在该范围内的任何地方请求request.user
,因为此时不存在上下文或请求变量 您需要的是根据发出请求的用户动态查询设置。您可以通过如下方式重写\uuuu init\uuu
方法来实现这一点:
def __init__(self, *args, **kwargs):
super(ProductSerializer, self).__init__(*args, **kwargs)
request_user = self.context['request'].user
self.fields['fridge'].queryset = Fridge.objects.filter(user=request_user)
初始字段必须如下所示,因为您必须指定queryset,否则将获得AssertionError:
fridge = serializers.PrimaryKeyRelatedField(queryset=Fridge.objects.all())
但是这当然会被覆盖。您需要的是基于发出请求的用户动态地查询设置。您可以通过如下方式重写
\uuuu init\uuu
方法来实现这一点:
def __init__(self, *args, **kwargs):
super(ProductSerializer, self).__init__(*args, **kwargs)
request_user = self.context['request'].user
self.fields['fridge'].queryset = Fridge.objects.filter(user=request_user)
初始字段必须如下所示,因为您必须指定queryset,否则将获得AssertionError:
fridge = serializers.PrimaryKeyRelatedField(queryset=Fridge.objects.all())
但这当然会被忽略。嗨,谢谢你的回答,但不幸的是,这不起作用。首先,如果我使用
viewsets.ViewSet
作为基类,那么序列化程序类将被初始化两次——一次是由我显式初始化的,在初始化之前由ViewSet初始化。而请求
对象不会在上下文中传递给第一次初始化。如果我检查是否设置了请求,然后才修改查询集,那么我就可以将产品添加到其他人的冰箱中。这就是我已经尝试过的:嗨,谢谢你的回答,但不幸的是,这不起作用。首先,如果我使用viewsets.ViewSet
作为基类,那么序列化程序类将被初始化两次——一次是由我显式初始化的,在初始化之前由ViewSet初始化。而请求
对象不会在上下文中传递给第一次初始化。如果我检查是否设置了请求,然后才修改查询集,那么我就可以将产品添加到其他人的冰箱中。这就是我已经尝试过的:为什么你把一个答案标记为正确,然后评论它不起作用-你找到有效的解决办法了吗?如果是这样,请分享。顺便说一句,虽然可以将冰箱和用户详细信息放入序列化程序,但我解决这个问题的方法是在保存到视图集中之前设置它们(在执行创建中)。这样,请求只是“添加产品”,只能添加到用户冰箱中。为什么您将答案标记为正确,然后评论它不起作用-你找到有效的解决办法了吗?如果是这样,请分享。顺便说一句,虽然可以将冰箱和用户详细信息放入序列化程序,但我解决这个问题的方法是在保存到视图集中之前设置它们(在执行创建中)。这样,请求只需“添加产品”,并且只能添加到用户冰箱中。