Django Rest Framework:在 Django Rest 框架工作中传递用户

Django Rest Frame Work: passing User in djago rest frame work

我有一个 Django 项目,模型中的代码如下

class Report(models.Model):
    created_by_user=models.ForeignKey(User,on_delete=models.CASCADE)

序列化器中的以下代码

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model=Report
        fields='__all__'

以及视图中的以下代码

class ReportCreateView(APIView):
    def post(self,request, *args, **kwargs):
        received_data=ReportSerializer(data=request.data)
        if received_data.is_valid():
            received_data.save()
            return Response(received_data.data, status=status.HTTP_201_CREATED)
        return Response(received_data.errors,status.HTTP_400_BAD_REQUEST)

当我通过 postman 发送 post 请求并在授权选项卡中发送用户名和密码时 它错误:

{
    "created_by_user": [
        "This field is required."
    ]
}

但如果我输入的用户名或密码不正确,它将是

{
    "detail": "Invalid username/password."
}

大家能帮帮我吗?

您的序列化程序不知道当前登录的 user.You 将其作为来自 request. user 或请求的上下文传递。

我个人更喜欢在序列化器中使用CurrentUserDefault。为了让它工作,我们需要将请求作为上下文传递,因为 CurrentUserDefault 从上下文请求中选择用户。我们需要更新我们的视图和序列化程序代码如下

查看文件:将请求添加为上下文上下文

class ReportCreateView(APIView):


def post(self,request, *args, **kwargs):
    received_data=ReportSerializer(data=request.data, context = {"request": request})
    if received_data.is_valid():
        received_data.save()
        return Response(received_data.data, status=status.HTTP_201_CREATED)
    return Response(received_data.errors,status.HTTP_400_BAD_REQUEST)

serializer.py:更新序列化程序以自动填充 created_by_user

class ReportSerializer(serializers.ModelSerializer):
    created_by_user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    
    class Meta:
        model=Report
        fields='__all__'

它将解决您的用户字段必填问题。

"created_by_user": ["This field is required."]

现在进入与密码不正确相关的问题的下一部分。

默认情况下,APIView 从设置中选择默认身份验证 class。在项目 settings.py 中,我们主要在使用 DRF 时编写这些行,它们用作 APIView 的默认身份验证:

来自settings.py

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    # Authentication settings
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
   ...
}

在 APIView 中您可以查看默认 permission_classesauthentication_classes

从 APIView 内部:

    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES

即当您键入无效密码时:

"detail": "Invalid username/password."

从 postman 向您的 APIView 提供正确的用户名和密码,以便它获得请求的登录用户以在数据库级别自动填充。

你不对你的用户数据执行任何处理,只需要保存请求用户,因此我认为你不需要它的序列化器字段,最好让你当前的用户可见.此外,如果您需要更多字段进行序列化,您可以使 created_by_user read_only 为真并在您的视图中设置它的值。

例如,如果您的模型中有报告名称和报告描述字段:

class Report(models.Model):
    created_by_user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=256)
    desc = models.TextField()

像这样执行序列化程序:

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model = Report
        fields = '__all__'
        extra_kwargs = {
            'created_by_user': {'read_only': True},
        }

然后在您的视图中设置 created_by_user 值:

class ReportCreateView(APIView):
    def post(self, request, *args, **kwargs):
        request.data['created_by_user'] = request.user # just need add this line 
        received_data = ReportSerializer(data=request.data)
        if received_data.is_valid():
            received_data.save()
            return Response(received_data.data, status=status.HTTP_201_CREATED)
        return Response(received_data.errors, status.HTTP_400_BAD_REQUEST)