drf高级五ModelSerializer

时间:2023-02-20 11:18:50

不同于Serializer,可以帮助我们完成。

  • 它将根据模型自动生成一组字段。
  • 它将根据模型上的参数自动生成序列化程序的验证程序。
  • 它包括 create() 和 update()简单默认实现。
from rest_framework import serializers

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'
        # exclude = ('created', ) 
        # read_only_fields = ('email', ) 指定只读字段
        # extra_kwargs = {'created': {'write_only': True}}

Meta属性

指定字段—fields

  • __all__指模型下所有字段
  • 元组或者列表指定字段

指定字段—exclude

和fields正好相反,指不需要一些字段。字段比较多它可能比较好用。

注意:无论是feilds or exclude被过滤的的字段都不能序列化或者反序列化。

指定只读字段

指定字段只做序列化,不做反序列化。功能等同字段参数read_only=True。默认就被设置为只读的不需要。

附加关键词

还可以通过使用extra_kwargs选项快捷地在字段上指定任意附加的关键字参数。在read_only_fields这种情况下,你不需要在序列化器上式的声明该字段。

Serializer

其实,在日常使用过程中。ModelSerializer比较常用,很多继承自Serializer被使用。

to_representation

重写这个选项作为序列化读取。使用ModeSerializer时为了适应反序列化。如:关联外键and choices类型and 额外附加字段等。

class CommentSerializer(BaseSerializer):
    def to_representation(self, data):

        ret = super().to_representation(data)
        if ret:
            # 逻辑
            ret['a'] = 'hello'
            pass

        return ret

create

通过验证数据将被保存

    def create(self, validated_data):
        """
        We have a bit of extra checking around this in order to provide
        descriptive messages when something goes wrong, but this method is
        essentially just:

            return ExampleModel.objects.create(**validated_data)

        If there are many to many fields present on the instance then they
        cannot be set until the model is instantiated, in which case the
        implementation is like so:

            example_relationship = validated_data.pop('example_relationship')
            instance = ExampleModel.objects.create(**validated_data)
            instance.example_relationship = example_relationship
            return instance

        The default implementation also does not handle nested relationships.
        If you want to support writable nested relationships you'll need
        to write an explicit `.create()` method.
        """
        raise_errors_on_nested_writes('create', self, validated_data)

        ModelClass = self.Meta.model

        # Remove many-to-many relationships from validated_data.
        # They are not valid arguments to the default `.create()` method,
        # as they require that the instance has already been saved.
        info = model_meta.get_field_info(ModelClass)
        many_to_many = {}
        for field_name, relation_info in info.relations.items():
            if relation_info.to_many and (field_name in validated_data):
                many_to_many[field_name] = validated_data.pop(field_name)

        try:
            instance = ModelClass._default_manager.create(**validated_data)
        except TypeError:
            tb = traceback.format_exc()
            msg = (
                'Got a `TypeError` when calling `%s.%s.create()`. '
                'This may be because you have a writable field on the '
                'serializer class that is not a valid argument to '
                '`%s.%s.create()`. You may need to make the field '
                'read-only, or override the %s.create() method to handle '
                'this correctly.\nOriginal exception was:\n %s' %
                (
                    ModelClass.__name__,
                    ModelClass._default_manager.name,
                    ModelClass.__name__,
                    ModelClass._default_manager.name,
                    self.__class__.__name__,
                    tb
                )
            )
            raise TypeError(msg)

        # Save many-to-many relationships after the instance is created.
        if many_to_many:
            for field_name, value in many_to_many.items():
                field = getattr(instance, field_name)
                field.set(value)

        return instance

update

数据将被更新

    def update(self, instance, validated_data):
        raise_errors_on_nested_writes('update', self, validated_data)
        info = model_meta.get_field_info(instance)

        # Simply set each attribute on the instance, and then save it.
        # Note that unlike `.create()` we don't need to treat many-to-many
        # relationships as being a special case. During updates we already
        # have an instance pk for the relationships to be associated with.
        m2m_fields = []
        for attr, value in validated_data.items():
            if attr in info.relations and info.relations[attr].to_many:
                m2m_fields.append((attr, value))
            else:
                setattr(instance, attr, value)

        instance.save()

        # Note that many-to-many fields are set after updating instance.
        # Setting m2m fields triggers signals which could potentially change
        # updated instance and we do not want it to collide with .update()
        for attr, value in m2m_fields:
            field = getattr(instance, attr)
            field.set(value)

        return instance

createupdate将共用验证器。所以在使用序列化器时应该考虑更加全面。序列化器默认是保存和更新是根据序列化后得到的字段。如果只是操作部分字段使用Serializer(partial=True)默认为False。