【问题标题】:What is advantage of using serializer to save object in django?使用序列化程序在 django 中保存对象有什么好处?
【发布时间】:2019-09-02 14:36:42
【问题描述】:

假设我有一个模型如下:

class SampleUser(models.Model):

    name = models.CharField(max_length=100)
    email = models.CharField(max_length=100)

class Group(models.Model):

    members = models.ManyToManyField(SampleUser)
    name = models.CharField(max_length=100)

我想知道使用序列化器创建对象有什么好处,比如说

序列化器.py

class SampleUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = SampleUser
        fields = ('name','id','email')

views.py

serializer = SampleUserSerializer(data = request.data)
if(serializer.is_valid()):
    serializer.save()

比直接创建一个示例用户对象

SampleUser.objects.create(....)

提前致谢!!!

【问题讨论】:

  • 第二个例子中的... 来自哪里?
  • @DanielRoseman 通过这些点,我的意思是我想放在那里创建对象的任何参数
  • 对。但它是如何到达那里的?序列化程序的重点是它获取 POST 数据,对其进行验证,然后创建对象。否则,您从哪里获取创建对象的数据?
  • @DanielRoseman 我将从 request.data 中单独设置参数,例如 name=request.data["name"]
  • 但这比使用序列化程序更好吗?您将如何验证数据是否有效?

标签: django django-models django-rest-framework django-serializer


【解决方案1】:

为了简单起见,我使用以下模型

class MyModel(models.Model):
    username = models.CharField(max_length=150)
    name = models.CharField(max_length=150)
    age = models.IntegerField()

在使用 DRF 序列化程序时,您可以获得一些优势

1。数据验证

与您的示例一样,在使用serializer's save() 方法之前必须调用.is_valid() 方法。也就是说,如果不验证数据,就无法将数据写入数据库。

示例: 假设你想验证age(年龄必须大于18)和username(只允许字母),你可以在序列化器中这样做,因为

from rest_framework import serializers


class MyModelSerializer(serializers.ModelSerializer):
    def validate_username(self, username: str):
        if username.isalpha():
            return username
        raise serializers.ValidationError("must be alphabetic")

    class Meta:
        model = MyModel
        fields = "__all__"
        extra_kwargs = {
            "age": {
                "min_value": 19
            }
        }
In [2]: data = {"username": "not a alpha", "age": 10, "name": "Foo"}                                                                                                                                               

In [3]: serializer = MyModelSerializer(data=data)                                                                                                                                                                  

In [4]: serializer.is_valid()                                                                                                                                                                                      
Out[4]: False

In [5]: serializer.errors                                                                                                                                                                                          
Out[5]: {'username': [ErrorDetail(string='must be alphabetic', code='invalid')], 'age': [ErrorDetail(string='Ensure this value is greater than or equal to 19.', code='min_value')]}

注意:您可以在模型的clean(...) 方法中进行这些验证,但是,它不适用于.create(...) 方法,只能使用@987654325 @方法

2。数据操作

假设,用户名在保存到数据库之前必须转换为小写,我们可以这样做

class MyModelSerializer(serializers.ModelSerializer):
    def validate_username(self, username: str):
        if username.isalpha():
            return username.lower() # case conversion
        raise serializers.ValidationError("must be alphabetic")

    class Meta:
        model = MyModel
        fields = "__all__"
        extra_kwargs = {
            "age": {
                "min_value": 19
            }
        }
In [19]: data = {"username": "aBU", "age": 20, "name": "Arakkal Abu"} 
                 ^^^^^^^^^^^^^^^^^^                                                                                                                                             

In [20]: serializer = MyModelSerializer(data=data)                                                                                                                                                                 

In [21]: serializer.is_valid()                                                                                                                                                                                     
Out[21]: True

In [22]: dict(serializer.validated_data)                                                                                                                                                                           
Out[22]: {'username': 'abu', 'name': 'Arakkal Abu', 'age': 20}

3。易于使用 DRF

如果您使用的是 DRF,则必须使用序列化程序。序列化器是高级类,通过从我们那里抽象出许多东西来提供许多特性。这有助于我们在几行代码中完成很多事情。

serializers.ModelSerializerviewsets.ModelViewSetDefaultRouter 的组合使 CRUD API 操作变得非常简单并且以 DRY 方式进行。

注意:如果我在这里遗漏了什么,请随时发表评论。

【讨论】:

    猜你喜欢
    • 2011-11-03
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多