1.1 Django
-
用
JsonResponse
实现序列化from django.views import View from django.http import jsonResponse class BookView(View): def get(self, request): """ 第一版 用.values JsonResponse实现序列化 """ book_list = Book.objects.values("id", "title", "category", "pub_time", "publisher") book_list = list(book_list) ret = [] # 只能获取到book_list中出版社的ID,详细信息需要手动拼接 for book in book_list: publisher_id = book["publisher"] publisher_obj = Publisher.objects.filter(id=publisher_id).first() book["publisher"] = { "id": publisher_id, "title": publisher_obj.title } ret.append(book) # ret = json.dumps(book_list, ensure_ascii=False) return JsonResponse(ret, safe=False, json_dumps_params={"ensure_ascii": False})
-
用
Django
的serializers
实现序列化from django.views import View from django.core import serializers class BookView(View): def get(self, request): """ 第二版 用django serializers实现序列化 """ book_list = Book.objects.all() # serializers获取book_list的信息,外键依旧是ID,详细信息需手动获取 ret = serializers.serialize("json", book_list, ensure_ascii=False) return HttpResponse(ret)
1.2 DRF
-
Serializer
from rest_framework import serializers from .models import Book class PublisherSerializer(serializers.Serializer): """ 外键 """ id = serializers.IntegerField() title = serializers.CharField(max_length=32) class AuthorSerializer(serializers.Serializer): """ 多对多 """ id = serializers.IntegerField() name = serializers.CharField(max_length=32) def my_validate(value): """ 校验规则1:外部自定义。优先级比内部钩子高 """ if "敏感信息" in value.lower(): raise serializers.ValidationError("不能含有敏感信息") else: return value class BookSerializer(serializers.Serializer): """ Serializer """ id = serializers.IntegerField(required=False) # required=False,该字段不需要校验 title = serializers.CharField(max_length=32, validators=[my_validate, ]) # validators,自定义的校验规则 CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True) # source="get_category_display",获取choices的中文 w_category = serializers.ChoiceField(choices=CHOICES, write_only=True) pub_time = serializers.DateField() publisher = PublisherSerializer(read_only=True) # read_only=True,只做展示 GET 正序列化 publisher_id = serializers.IntegerField(write_only=True) # write_only=True,只做校验 POST PUT 反序列化 author = AuthorSerializer(many=True, read_only=True) # many=True,多对多 author_list = serializers.ListField(write_only=True) # ListField(),列表字段 def create(self, validated_data): """ 对于POST请求,重写create方法 """ book = Book.objects.create(title=validated_data["title"], category=validated_data["w_category"], pub_time=validated_data["pub_time"], publisher_id=validated_data["publisher_id"]) book.author.add(*validated_data["author_list"]) # 多对多 return book def update(self, instance, validated_data): """ 对于PUT|PATCH请求,重写update方法 """ instance.title = validated_data.get("title", instance.title) instance.category = validated_data.get("category", instance.category) instance.pub_time = validated_data.get("pub_time", instance.pub_time) instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id) if validated_data.get("author_list"): instance.author.set(validated_data["author_list"]) # 多对多 instance.save() return instance def validate_title(self, value): """ 校验规则2:局部钩子 """ if "python" not in value.lower(): raise serializers.ValidationError("标题必须含有python") # 主动抛异常 return value def validate(self, attrs): """ 校验规则3:全局钩子 """ if attrs["w_category"] == 1 and attrs["publisher_id"] == 1: return attrs else: raise serializers.ValidationError("分类以及标题不符合要求")
-
ModelSerializer
from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): """ ModelSerializer """ # category = serializers.CharField(source="get_category_display") # 普通取字段 category_display = serializers.SerializerMethodField(read_only=True) # SerializerMethodField,用方法取字段 publisher_info = serializers.SerializerMethodField(read_only=True) # read_only=True,只做展示 GET 正序列化 authors = serializers.SerializerMethodField(read_only=True) def get_category_display(self, obj): """ 方法字段对应的方法 """ return obj.get_category_display() def get_authors(self, obj): """ 方法字段对应的方法 """ authors_query_set = obj.author.all() return [{"id": author_obj.id, "name": author_obj.name} for author_obj in authors_query_set] def get_publisher_info(self, obj): """ 方法字段对应的方法 """ publisher_obj = obj.publisher return {"id": publisher_obj.id, "title": publisher_obj.title} class Meta: """ 初始化 """ model = Book # 绑定的表 # fields = ["id", "title", "pub_time"] # 自定义字段 fields = "__all__" # 取所有字段 # depth = 1 # 嵌套关系找1层 # {"write_only": True}:GET请求不展示这些字段 extra_kwargs = {"category": {"write_only": True}, "publisher": {"write_only": True}, "author": {"write_only": True}}