使用串行器将对象保存在django中有什么优势?

时间:2019-04-11 21:15:59

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

假设我有一个模型,如下:

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)

我想知道使用序列化程序创建对象的优点是什么,

serializers.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(....)

提前谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

使用DRF序列化器可能没有什么优势

1。数据验证

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

示例: 假设您要验证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(...)方法, models' save(...)方法

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方式。

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