【问题标题】:Cannot assign "...'": "TestData.user" must be a "User" instance无法分配“...”:“TestData.user”必须是“用户”实例
【发布时间】:2021-11-18 23:23:49
【问题描述】:

对于 Django Rest 框架来说非常新,因此希望能得到一些帮助。当我尝试使用适当的身份验证令牌在 Postman 中执行 POST 请求时,标题中出现错误。

我创建了一个表,我想向其发送 POST 请求,但在让用户 FK 被接受为列之一时遇到问题。请参阅下面的模型/序列化器/视图:

型号

class TestData (models.Model):
TestSDG = models.DecimalField(decimal_places=0, max_digits=2, default=0)
user = models.ForeignKey("auth.User", related_name="testdata", on_delete=models.CASCADE)

序列化器

class TestDataSerializer(serializers.ModelSerializer):

class Meta:
    model = TestData
    fields = ('id', 'TestSDG')

查看

@csrf_exempt
def testDataApi(request, id=0):
if request.method == 'GET':
    testdata = TestData.objects.all()
    testdata_serializer = TestDataSerializer(testdata,many=True)
    return JsonResponse(testdata_serializer.data,safe=False)
elif request.method == 'POST':
    testdata_data=JSONParser().parse(request)
    testdata_serializer=TestDataSerializer(data=testdata_data)
    if testdata_serializer.is_valid():
        testdata_serializer.save(user=request.user)
        return JsonResponse("Added Successfully", safe=False)

如果我不使用用户作为外键,POST 请求工作正常,我将testdata_serializer.save(user=request.user) 改回testdata_serializer.save(),但我希望表需要用户的 id。

感谢任何帮助,谢谢。

【问题讨论】:

    标签: django django-models django-rest-framework django-views django-urls


    【解决方案1】:

    您应该在您的 views.py 文件中使用 ModelViewset - 然后您可以覆盖您的序列化程序上的 update 方法:

    views.py

    from rest_framework.viewsets import ModelViewSet
    
    class TestDataViewSet(ModelViewSet):
     
        queryset = TestData.objects.all()
        serializer_class = TestDataSerializer
    

    serializers.py

    class TestDataSerializer(serializers.ModelSerializer):
    
        ...
    
        def update(self, instance, validated_data):
    
            # get user id from validated data:
            user_id = validated_data.pop('user_id')
    
            # get user:
            user = User.objects.get(id=user_id)
    
            # set user on instance:
            instance.user = user
            instance.save()
    
            # continue with update method:
            super().update(instance, validated_data)
    

    【讨论】:

    • 你概述的方式似乎与我做事的方式有点不同(据说我只是在关注一个基本视频,它没有涵盖表之间的 FK 连接,所以也许我在做错了)。我不太明白更新方法中发生了什么。我知道它正在获取 user_id 并将其保存到用户实例,但我不确定在那之后如何访问它。我试图在 testDataApi 和/或 views.py 中的等效更新方法中访问它,但我遇到了完整性问题,因为 user_id 仍然为空。
    • ModelViewSet 是一个包含预定义的get、list、post 等方法的类,因此您无需自己编写它们。它与ModelSerializer 很好地配对,但是一个限制是序列化程序在处理嵌套对象方面做得很差,因此我们仍然需要重写更新方法来执行诸如获取或创建嵌套对象之类的事情。
    • 谢谢丹尼尔,用你的方法让它工作了。在 ModelViewSet 下的视图中制作了一些 GET/POST 方法,这些方法引用了用户请求,并且没有问题。
    【解决方案2】:

    您提到您正在使用身份验证令牌。尝试在您的视图中验证 testDataApi 是否使用 auth.User 对象正确设置了 request.user。尝试使用以下内容对其进行记录,以确保它已正确设置给用户以获取所提供的令牌:

    @csrf_exempt
    def testDataApi(request, id=0):
        print(type(request.user), request.user)  # Should display the user for the provided token.
        ...
    

    如果未设置,则您必须配置它如何从提供的令牌正确映射auth.User 对象。您可能想查看以下内容:

    【讨论】:

    • 谢谢你 - 是的,它只是找到一个匿名用户,所以 auth.user 对象可能没有被映射。我会看看这些资源。
    猜你喜欢
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多