drf之ModelSerializer

发布时间 2023-04-23 12:31:54作者: 树苗叶子

简介

与表做强关联,之后不需要再写create与update函数了
官网:https://www.django-rest-framework.org/api-guide/serializers/

语法

有多种写法,局部钩子与全局钩子是一样的

class 类名(serializers.ModelSerializer)
    # 固定写法,在类中再定义一个Meta
    class Meta:
        # 与表做强关联,左边的字段必须是model
        model = models.Book
        # 查询所有字段,但在显示外键时,会显示外键的字段id,并不是名。
        fields = '__all__'
        # 也可以使用fields指定字段,列表中进行注册
        fields = ['字段名1', '字段名2', ...]
        # 只读字段
        read_only_fields = ['字段名1', '字段名2']
        # 只写字段
        write_only_fields = ['字段名1', '字段名2']
        # 对字段定制限制,方法一:在Meta中定制
        extra_kwargs = {'字段名': {'max_length': 8, 'error_messages': {'max_length': '不能超过8个字符'}},
                        '字段名': {'read_only': True}
                        '字段名': {'write_only': True}}

    # 方法二:在Meta类外定义,且需要在Meta中的fields中进行注册,如:
    name = serializers.CharField(max_length=8, error_messages={'max_length': '不能超过8个字符'})
    price = serializers.CharField(max_length=8)
    publish = serializers.SerializerMethodField()
    def get_publish(self, obj):
        # 这里的obj其实就相当于Book.publish.name中的Book
        return {'name': obj.publish.name, 'phone': obj.publish.addr}
    # 多对多关系的字定义
    authors = serializers.SerializerMethodField()
    def get_authors(self, obj):
        author_list = []
        for author in obj.authors.all():
            author_list.append({'name': author.name, 'phone': author.phone})
        return author_list
  • 如下图,使用fields='__all__'后,前端获取到的是字段id号

示例

  • models.py
models.py
```python
from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    # 图书与出版社外键字段,一对多
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    # 图书与作者外键字段,多对多
    authors = models.ManyToManyField(to='Author')

    @property
    def publish_detail(self):
        return {'name': self.publish.name, 'addr': self.publish.addr}

    @property
    def author_detail(self):
        author_list = []
        for author in self.authors.all():
            author_list.append({'name': author.name, 'phone': author.phone})
        return author_list


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)


class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=11)

使用Meta进行定义

  • serializer.py
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['name', 'price', 'publish_detail', 'author_detail', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8, 'error_messages': {'max_length': '不能超过8个字符'}},
                        'price': {'max_length': 8},
                        'publish_detail': {'read_only': True},  # 此字段是在models.py中定义的
                        'author_detail': {'read_only': True},   # 此字段是在models.py中定义的
                        'publish': {'write_only': True},
                        'authors': {'write_only': True}}

在Meta类外进行定义

  • serializer.py
class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['name', 'price', 'publish', 'authors', 'publish_detail', 'author_detail']
        read_only_fields = ['publish_detail', 'author_detail']   # 此字段是在models.py中定义的
        write_only_fields = ['publish', 'authors']
    # 注意下面两个字段是写在Meta外的
    name = serializers.CharField(max_length=8, error_messages={'max_length': '不能超过8个字符'})
    price = serializers.CharField(max_length=8)