Django Rest框架:在djago Rest框架中传递User



我有一个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)

当我通过邮递员发送投递请求并在"授权"选项卡中发送用户名和密码时it错误:

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

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

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

每个人都能帮我吗?

您的序列化程序不知道当前登录的用户。您可以将其作为上下文从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从设置中选择默认的身份验证类。在项目settings.py中,我们主要在使用DRF时编写这些行,它们用作APIView:的默认身份验证

来自设置.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."

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

您不需要对用户数据执行任何处理,只需要保存请求用户,因此我认为您不需要序列化程序字段,最好查看当前用户。此外,如果需要更多的字段进行序列化,可以将createdby_userreadonly设置为true,并在视图中设置其值。

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

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)

最新更新