【问题标题】:ManyToManyField is being filtered excluded when passed through DRF view and serializer通过 DRF 视图和序列化程序传递时,ManyToManyField 被过滤排除
【发布时间】:2019-03-18 07:38:18
【问题描述】:

当尝试通过 Django Rest Framework 路由通过 POST 将新记录持久保存到数据库时,我在对象上名为 shared_usersManyToManyField 被过滤掉了。这很奇怪,因为新对象仍在创建中,但是 shared_users 属性显示为一个空列表。

当我通过 Python 调试器检查时,请求对象上的所有内容最初都是可用的。

(Pdb) request.data
<QueryDict: {u'shared_users[]': [u'4', u'5', u'1'], u'model_name': [u'A name'], u'description': [u'A description']}>

但是当我使用request.data.get('shared_users[]', []) 检查字段时(不知道为什么字段名出现在名称中带有[]),我得到u'1' 的结果(已经缺少两个用户ID)。

当我评估 serializer.data 时,它会返回除 shared_users 字段之外的所有内容,如下所示。

{'last_modified_by': 3, 'description': u'A description', 'user': 3, 'shared_users': [], 'model_name': u'A name'}

我提供了我的视图和序列化程序文件以供参考。


views.py

class MyCreateView(generics.GenericAPIView):
    pass
    serializer_class = MyCreateAndUpdateSerializer

    def get_queryset(self):
        return User.objects.filter(pk=self.kwargs.get('user'))

    def post(self, request, format=None, **kwargs):
        # This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
        request_data = {
            'user': request.user.id,
            'model_name': request.data['model_name'],
            'description': request.data['description'],
            'last_modified_by': request.user.id,
            'shared_users': request.data.get('shared_users', [])
         }

    serializer = MyCreateAndUpdateSerializer(data=request_data)

    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化器.py

class MyCreateAndUpdateSerializer(serializers.ModelSerializer):
    shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)

    class Meta:
        model = Project
        fields = [
          'pk',
          'user',
          'data',
          'model_name',
          'description',
          'created_at',
          'date_modified',
          'shared_users',
          'last_modified_by'
        ]

【问题讨论】:

  • 如果你的请求参数是shared_users[]并且它传入一个列表,你应该使用request.data.get_list('shared_users[]', [])获取它。
  • 参数名称中的 [] 来自您的 HTML 表单或向您发送数据的任何人。像这样用多个值命名表单参数是一个(愚蠢的?)PHP约定。 Django 使用 QueryDict ,它每个参数接受多个值(并使用 get_list 来获取它们,这就是 request.data 的所有值都是列表的原因)。

标签: python django python-2.7 django-rest-framework


【解决方案1】:

感谢@dirkgroten 对此的回答。

原来问题出在views.py 中 request_data 字典上的'shared_users': request.data.get('shared_users', [])。因为与'shared_users[]' 关联的值是一个列表,所以我应该使用getlist 来访问该列表,例如request.data.getlist('shared_users[]', []).

Django QueryDict Docs

【讨论】:

    猜你喜欢
    • 2021-11-20
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 2017-10-22
    • 2020-06-21
    • 1970-01-01
    相关资源
    最近更新 更多