django 为什么DRF的串行器不验证PositiveSmallIntegerField?

yhived7q  于 2023-02-05  发布在  Go
关注(0)|答案(3)|浏览(126)

使用Django1.11和DjangoRest框架3.7,我有一个Person模型

class Person(models.Model):

    name = models.CharField(max_length=100)
    email = models.EmailField()
    age = models.PositiveSmallIntegerField()

使用个性化序列化程序

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ('id', 'name', 'age', 'email')

和ListCreate视图

class PersonList(generics.ListCreateAPIView):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

使用HTTPie,我可以创建一个Person如下:

$ http POST http://127.0.0.1:8000/api/people/ name=Alice age=26 email=alice@example.com
HTTP/1.0 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 60
Content-Type: application/json
Date: Sun, 10 Dec 2017 15:00:28 GMT
Server: WSGIServer/0.1 Python/2.7.11
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN

{
    "age": 26,
    "email": "alice@example.com",
    "id": 1,
    "name": "Alice"
}

当我使用错误的电子邮件地址创建人员时,我收到一个错误:

$ http POST http://127.0.0.1:8000/api/people/ name=Bob age=33 email=oops
HTTP/1.0 400 Bad Request
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 42
Content-Type: application/json
Date: Sun, 10 Dec 2017 15:01:08 GMT
Server: WSGIServer/0.1 Python/2.7.11
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN

{
    "email": [
        "Enter a valid email address."
    ]
}

DRF知道这是一个EmailField,并自动应用验证,到目前为止一切顺利。
但是,当我创建一个年龄不正确(负数)的Person时,我没有得到错误:

$ http POST http://127.0.0.1:8000/api/people/ name=Charlie age=-10 email=charlie@example
.com
HTTP/1.0 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 65
Content-Type: application/json
Date: Sun, 10 Dec 2017 15:03:25 GMT
Server: WSGIServer/0.1 Python/2.7.11
Vary: Accept, Cookie
X-Frame-Options: SAMEORIGIN

{
    "age": -10,
    "email": "charlie@example.com",
    "id": 3,
    "name": "Charlie"
}

现在我的数据库已经被坏数据污染了。我做验证输入的工作没有问题,但是

  • DRF正确地验证了email字段,这让我相信它将根据模型中的字段类型验证输入。
  • 如果我是从html表单发布的,Django的ModelForm会验证email和age字段。
  • 如果我从标准Django Admin创建了一个Person,它也会验证email和age字段。

基于这些事实,我的问题是:
(A)为什么DRF的序列化器验证EmailField,而不验证PositiveSmallIntegerField?
(B)我应该在哪里验证“年龄”字段以确保它是正的?模型?序列化程序?视图?

jk9hmnmh

jk9hmnmh1#

将验证器添加到模型中的字段:

from django.core.validators import MinValueValidator
from django.core.validators import MaxValueValidator

class Person(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()
    age = models.PositiveSmallIntegerField(validators=[MinValueValidator(0), MaxValueValidator(120)])
ssm49v7z

ssm49v7z2#

在DRF中,IntegerField对应于PositiveIntegerField,因此您可以在其上设置最大值和最小值限制。
例如:

class PersonSerializer(serializers.ModelSerializer):
    age = serializers.IntegerField(max_value=100, min_value=1)
    class Meta:
        model = Person
        fields = ('id', 'name', 'age', 'email')
thigvfpy

thigvfpy3#

如果需要超过最小值/最大值

class YOURSerializer(serializers.ModelSerializer):

age= serializers.IntegerField(required=True)

    class Meta:
    model = User
    fields = '__all__'

    def validate(self, data):
      age= data.get('age', None)
    
      if age == 18:
          raise serializers.ValidationError("Age 18 people are given special discount, Congrats!")

相关问题