Django: Rest Framework (序列化器)

huangapple go评论77阅读模式
英文:

Django: Rest Framework (Serializer)

问题

我是初次使用Django Rest框架。

我正在尝试理解如何根据用户输入验证序列化器中的字段,例如:

序列化器:

from rest_framework import serializers

VALID_REGION = 'region'

def validate_region(value):
    
    if value != VALID_REGION:
        raise serializers.ValidationError('Invalid region, make sure region parameter is spelled correctly.')
    
    return value

class RegionSerializer(serializers.Serializer):
    region = serializers.CharField(required=False, validators=[validate_region])

在这里,我想验证地区是否拼写正确。

views.py

def get(request, *args, **kwargs):

        serializer = RegionSerializer(data=request.data)

        if serializer.is_valid():
            
            data = serializer.validated_data

            region   = data.get('region', '')

            regions = region_lib.get_regions(region)

            return Response({"regions": regions}, status=status.HTTP_200_OK)

        else:
            errors = serializer.errors

            return Response({"error": errors}, status=status.HTTP_400_BAD_REQUEST)

在这里,我有意传递了'regoin',将其拼写错误。

{
    "regoin": "Test"
}

当我运行serializer.is_valid()时,它返回true

不确定我漏掉了什么。

英文:

I'm new to using the django rest framework.

I'm trying to understand how I can validate a field with the serializer based on the input from the user, for example:

Serializer:

from rest_framework import serializers

VALID_REGION = 'region'

def validate_region(value):
    
    if value != VALID_REGION:
        raise serializers.ValidationError('Invalid region, make sure region parameter is spelled correctly.')
    
    return value

class RegionSerializer(serializers.Serializer):
    region = serializers.CharField(required=False, validators=[validate_region])

Here I want to validate that the region is spelled correctly.

views.py

 def get(request, *args, **kwargs):

        serializer = RegionSerializer(data = request.data)

        if serializer.is_valid():
            
            data = serializer.validated_data

            region   = data.get('region', '')

            regions = region_lib.get_regions(region)

            return Response({"regions" : regions}, status=status.HTTP_200_OK)

        else:
            errors = serializer.errors

            return Response({"error" : errors}, status=status.HTTP_400_BAD_REQUEST)

Here I pass 'regoin' misspelling it intentionally.

{
    "regoin": "Test"
}

When I run serializer.is_valid() it returns true.

Not sure what I'm missing.

答案1

得分: 2

你应该将你的请求方法从 GET 修改为 POST。例如,将以下代码更改为:

从:

def get(request, *args, **kwargs):

def post(request, *args, **kwargs):

通过使用 def get(request, *args, **kwargs):,你的端点只允许 GET 请求。因此,你无法发送请求正文,self.request.data 将为空对象 {}。此外,在你的 RegionSerializer 中,你已经将 region 字段设置为可选的,使用 required=False

region = serializers.CharField(required=False, validators=[validate_region])

这解释了为什么在你的视图中,serializer.is_valid() 总是返回 True

当你从 def get(request, *args, **kwargs):(GET)更改为 def post(request, *args, **kwargs):(POST),并且你将请求正文传递如下:

{"region": "region"}

这将通过 serializer.is_valid() 检查。

然而,如果你传递 {"region": "Region"},它将不会导致 serializer.is_valid() 返回 False

注意:如果你的请求正文为空,serializer.is_valid() 也将返回 True,因为 region 字段是可选的。

英文:

You should modify your request method from GET to POST. For example, change the following code:

From:

def get(request, *args, **kwargs):

To

def post(request, *args, **kwargs):

By using def get(request, *args, **kwargs):, your endpoint only allows GET requests. As a result, you cannot send a request body, and self.request.data will be {}. Additionally, in your RegionSerializer, you have set the region field to be optional with required=False:

region = serializers.CharField(required=False, validators=[validate_region])

This explains why serializer.is_valid() in your views always returns True.

When you change from def get(request, *args, **kwargs): (GET) to def post(request, *args, **kwargs): (POST), and you pass your request body as follows:

{"region": "region"}

This will pass the serializer.is_valid() check.

However, if you pass {"region": "Region"}, it will not cause serializer.is_valid() to return False.

Note: If your request body is empty, serializer.is_valid() will also return True since the region field is optional.

答案2

得分: -2

在您的代码中,拼写错误的字段 'regoin' 被视为有效字段,因为 RegionSerializer 对 'region' 字段设置了 required=False。这意味着该字段不是必需的,可以从数据中省略。当您传递 'regoin' 而不是 'region' 时,它会被忽略,因为它与任何已定义的字段都不匹配,也不会引发验证错误。

要确保拼写错误的字段引发验证错误,您可以从 RegionSerializer 的 'region' 字段中移除 required=False。这样,该字段将变为必需字段,任何拼写错误或缺少的 'region' 字段都将触发验证错误。

class RegionSerializer(serializers.Serializer):
    region = serializers.CharField(validators=[validate_region])
英文:

n your code, the misspelled field 'regoin' is being considered as a valid field because the RegionSerializer has required=False for the 'region' field. This means that the field is not required and can be omitted from the data. When you pass 'regoin' instead of 'region', it is ignored because it doesn't match any defined fields and doesn't raise a validation error.

To ensure that the misspelled field raises a validation error, you can remove required=False from the 'region' field in the RegionSerializer. This way, the field will be required, and any misspelled or missing 'region' field will trigger a validation error.

class RegionSerializer(serializers.Serializer):
    region = serializers.CharField(validators=[validate_region])

huangapple
  • 本文由 发表于 2023年7月13日 17:26:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定