Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Rest框架-序列化程序中的外键筛选_Python_Django_Django Rest Framework - Fatal编程技术网

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初始化。而
请求
对象不会在上下文中传递给第一次初始化。如果我检查是否设置了请求,然后才修改查询集,那么我就可以将产品添加到其他人的冰箱中。这就是我已经尝试过的:为什么你把一个答案标记为正确,然后评论它不起作用-你找到有效的解决办法了吗?如果是这样,请分享。顺便说一句,虽然可以将冰箱和用户详细信息放入序列化程序,但我解决这个问题的方法是在保存到视图集中之前设置它们(在执行创建中)。这样,请求只是“添加产品”,只能添加到用户冰箱中。为什么您将答案标记为正确,然后评论它不起作用-你找到有效的解决办法了吗?如果是这样,请分享。顺便说一句,虽然可以将冰箱和用户详细信息放入序列化程序,但我解决这个问题的方法是在保存到视图集中之前设置它们(在执行创建中)。这样,请求只需“添加产品”,并且只能添加到用户冰箱中。