代码之家  ›  专栏  ›  技术社区  ›  David Schumann Axnyff

为什么django是rest框架request.data 有时是不变的?

  •  0
  • David Schumann Axnyff  · 技术社区  · 7 年前

    CreateAPIView 我改变了我的想法 request.data

    偶尔我会收到一个测试没有发现的错误:

    This QueryDict instance is immutable
    

    class CreateView(CreateAPIView):
        serializer_class = ...
        queryset = ...
    
        def post(self, request, *args, **kwargs):
            request.data['user'] = request.user.pk
            return self.create(request, *args, **kwargs)
    

    request.data dict 在我的测试中。为什么有时是 QueryDict ? 这应该如何处理?应该request.data 一般不会变异?你应该如何使用 ModelSerializer 类,当您需要自己填充某些字段时?

    4 回复  |  直到 7 年前
        1
  •  11
  •   Community Mohan Dere    5 年前

    为什么会这样 偶尔的

    当我们看到 SC of Request (正如@Kenny Ackerman提到的),它返回一个 QueryDict 如果你经过一个 窗体媒体类型 ( 'application/x-www-form-urlencoded' 'multipart/form-data' )数据到视图类。
    is_form_media_type() Request 班级。

    application/json 数据到视图中 request.data 将是一个 dict

    如何再现这种行为?

    它可以通过发送不同的 ContentType form-data raw JSON 获得行为)


    当前登录用户 在序列化程序中?

    将额外参数传递给 .save() (正如@Linovia提到的)重写 perform_create()

    class CreateView(CreateAPIView):
        serializer_class = ...
        queryset = ...
    
        def post(self, request, *args, **kwargs):
            request.data['user'] = request.user.pk
            return self.create(request, *args, **kwargs)
    
        def perform_create(self, serializer):
            serializer.save(user=self.request.user)

    方法2 CurrentUserDefault() 分类如下

    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    
    class MySerializer(serializers.ModelSerializer):
        user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), default=serializers.CurrentUserDefault())
    
        class Meta:
        # your code
        2
  •  1
  •   Unicone    7 年前

    当您必须修改从请求接收的QueryDict对象时,它是一个不可变的对象,如果您想添加属性,请使用这行代码:

    myNewRequest = request.GET.copy()
    myNewRequest.data['some_attr'] = float(something)
    
        3
  •  1
  •   Ehsan Nouri    7 年前

    基于 source code 当流为空时,解析器返回数据的querydict(request.data 电话 _load_data_and_files _加载\u数据\u和\u文件 _parse

    我想你可以用 HiddenField create update 方法。例如

    class TestSerializer(serializers.ModelSerializer):
        user = serializers.HiddenField(default=serializers.CurrentUserDefault())
        class Meta:
            model = Test
            fields = ('id', 'text', 'user')
    
        def create(self, validated_data):
    
            validated_data['populate_field'] = 'value'
            return super().create(validated_data)
    
        4
  •  0
  •   Enthusiast Martin    7 年前

    DEFAULT_PARSER_CLASSES

    JSONParser的实现如下:

    return json.load(decoded_stream, parse_constant=parse_constant)
    

    FormParser如下所示:

    return QueryDict(stream.read(), encoding=encoding)