将后端数据库中的信息用json的格式传给前端
import json from django.http import HttpResponse,JsonResponse from django.views import View from .models import Book class BookView(View): def get(self,request): book_list = Book.objects.values("id","title","pub_time") book_list = list(book_list) ret = json.dumps(book_list,ensure_ascii=False) return HttpResponse(ret)
日期格式数据会无法被json序列化后通过 HttpResponse 发送
利用 JsonResponse 可序列化费字典类型的对象
def get(self,request): book_list = Book.objects.values("id","title","pub_time") book_list = list(book_list)
return JsonResponse(book_list,safe=False,json_dumps_params={"ensure_ascii":False}) #ensure_ascii 防止乱码
最终取出所有信息
class BookView(View): # 第一版 用.values JsonResponse实现序列化 def get(self, request): book_list = Book.objects.values("id", "title", "category", "pub_time", "publisher") book_list = list(book_list) ret = [] 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})
from django.core import serializers
class BookView(View): # 第二版 用django serializers实现序列化 def get(self, request): book_list = Book.objects.all() ret = serializers.serialize("json", book_list, ensure_ascii=False) return HttpResponse(ret)
序列化数据不完整,
安装 pip install djangorestframework
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘SerDemo‘, ‘rest_framework‘, ]
编写序列化的类
from rest_framework import serializers class BookSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES,source="get_category_display") pub_time = serializers.DateField()
视图函数
from rest_framework.views import APIView from rest_framework.response import Response from .serializers import BookSerializer # 导入序列化类 class BookView(APIView): def get(self, request): book_obj = Book.objects.first() ret = BookSerializer(book_obj) # book_list = Book.objects.all() # 拿到所有的对象 # ret = BookSerializer(book_list, many=True) return Response(ret.data)
含外键数据的序列化
from rest_framework import serializers 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) class BookSerializer(serializers.Serializer): id = serializers.IntegerField() title = serializers.CharField(max_length=32) CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES, source="get_category_display") pub_time = serializers.DateField() publisher = PublisherSerializer() author = AuthorSerializer(many=True)
将前端传过来的数据进行反序列化,然后保存到数据库
read_only=True #序列化
write_only=True #反序列化数据
前端传过来的数据样式
{ "title": "Alex的使用教程", "w_category": 1, "pub_time": "2018-10-09", "publisher_id": 1, "author_list": [1, 2] }
接受Post前端传过来的数据,必须在serialise类定义create方法
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) #不需要校验 title = serializers.CharField(max_length=32, validators=[my_validate]) CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True) w_category = serializers.ChoiceField(choices=CHOICES, write_only=True) pub_time = serializers.DateField() publisher = PublisherSerializer(read_only=True) publisher_id = serializers.IntegerField(write_only=True) author = AuthorSerializer(many=True, read_only=True) author_list = serializers.ListField(write_only=True) #反序列化字段 def create(self, validated_data): # 创建数据,接受post 数据 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
定义 post 方法接受前端传过来的数据
class BookView(APIView): def get(self, request): # book_obj = Book.objects.first() # ret = BookSerializer(book_obj) book_list = Book.objects.all() ret = BookSerializer(book_list, many=True) return Response(ret.data) def post(self, request): print(request.data) serializer = BookSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) #校验成功,反回 else: return Response(serializer.errors)
post数据
反回的结果
from django.urls import path, include from .views import BookView, BookEditView urlpatterns = [ path(‘list‘, BookView.as_view()), path(‘retrieve/<int:id>‘, BookEditView.as_view()), ]
class BookEditView(APIView): def get(self, request, id): # 获取单条数据 book_obj = Book.objects.filter(id=id).first() ret = BookSerializer(book_obj) return Response(ret.data) def put(self, request, id): # 修改数据 book_obj = Book.objects.filter(id=id).first() serializer = BookSerializer(book_obj, data=request.data, partial=True) # partial=True # 支持部分验证 if serializer.is_valid(): serializer.save() return Response(serializer.data) else: return Response(serializer.errors) def delete(self, request, id): book_obj = Book.objects.filter(id=id).first() book_obj.delete() return Response("")
查看单条数据,获取id为4的数据
修改数据
前端传过来的数据
data = {
"title": "Alex的使用教程2"
}
对修改的数据进行序列化处理 update 方法
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) #不需要校验 title = serializers.CharField(max_length=32, validators=[my_validate]) CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True) w_category = serializers.ChoiceField(choices=CHOICES, write_only=True) pub_time = serializers.DateField() publisher = PublisherSerializer(read_only=True) publisher_id = serializers.IntegerField(write_only=True) author = AuthorSerializer(many=True, read_only=True) author_list = serializers.ListField(write_only=True) def update(self, instance, validated_data): # 处理 put 更新数据 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
反回的结果
class BookSerializer(serializers.Serializer): id = serializers.IntegerField(required=False) # 不需要校验 title = serializers.CharField(max_length=32, validators=[my_validate]) CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True) w_category = serializers.ChoiceField(choices=CHOICES, write_only=True) pub_time = serializers.DateField() publisher = PublisherSerializer(read_only=True) publisher_id = serializers.IntegerField(write_only=True) author = AuthorSerializer(many=True, read_only=True) author_list = serializers.ListField(write_only=True) def create(self, validated_data): # 创建数据 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 更新数据 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): # 对传过来的title进行校验 if "python" not in value.lower(): raise serializers.ValidationError("标题必须含有python") return value def validate(self, attrs): # 全局校验 if attrs["w_category"] == 1 and attrs["publisher_id"] == 1: return attrs else: raise serializers.ValidationError("分类以及标题不符合要求")
自定义验证器
当有重叠校验器时自定义的验证器权重更高
def my_validate(value): # 自定义验证器,权重更高,用在需要校验数据的地方 if "敏感信息" in value.lower(): raise serializers.ValidationError("不能含有敏感信息") else: return value
使用
title = serializers.CharField(max_length=32, validators=[my_validate])
# depth = 1
class BookSerializer(serializers.ModelSerializer): category = serializers.CharField(source="get_category_display") class Meta: model = Book # 对应的 model # fields = ["id", "title", "pub_time"] fields = "__all__" # 所有字段 depth = 1 # 外键深度为1
拿到了较多的冗余字段
通过 SerializerMethodField 只取想要的字段,然后在下面定义各自的获取方法
class BookSerializer(serializers.ModelSerializer): # 只取想要的字段, category_display = serializers.SerializerMethodField(read_only=True) publisher_info = serializers.SerializerMethodField(read_only=True) 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): # obj 是我们序列化的每个Book对象 publisher_obj = obj.publisher return {"id": publisher_obj.id, "title": publisher_obj.title}
ModelSerializer 默认已经帮我们做了反序列化(不用写 create 方法)接受post 数据
def my_validate(value): # 自定义验证器,权重更高,
if "敏感信息" in value.lower():
raise serializers.ValidationError("不能含有敏感信息")
else:
return value
class BookSerializer(serializers.ModelSerializer): # 只取想要的字段, category_display = serializers.SerializerMethodField(read_only=True) # 序列化(显示的时候)的 显示 publisher_info = serializers.SerializerMethodField(read_only=True) 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): # obj 是我们序列化的每个Book对象 publisher_obj = obj.publisher return {"id": publisher_obj.id, "title": publisher_obj.title} # category = serializers.CharField(source="get_category_display") class Meta: model = Book # 对应的 model # fields = ["id", "title", "pub_time"] fields = "__all__" # depth = 1 # 字段的额外参数, "write_only": True 反序列化的时候显示 extra_kwargs = {"category": {"write_only": True}, "publisher": {"write_only": True}, "author": {"write_only": True}}
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) # # # 传过来的书籍对象数据 # book_obj = { # "title": "Alex的使用教程", # "w_category": 1, # "pub_time": "2018-10-09", # "publisher_id": 1, # "author_list": [1, 2] # } # # data = { # "title": "Alex的使用教程2" # } def my_validate(value): # 自定义验证器,权重更高, if "敏感信息" in value.lower(): raise serializers.ValidationError("不能含有敏感信息") else: return value # class BookSerializer(serializers.Serializer): # id = serializers.IntegerField(required=False) # 不需要校验 # title = serializers.CharField(max_length=32, validators=[my_validate]) # CHOICES = ((1, "Python"), (2, "Go"), (3, "Linux")) # category = serializers.ChoiceField(choices=CHOICES, source="get_category_display", read_only=True) # w_category = serializers.ChoiceField(choices=CHOICES, write_only=True) # pub_time = serializers.DateField() # # publisher = PublisherSerializer(read_only=True) # publisher_id = serializers.IntegerField(write_only=True) # author = AuthorSerializer(many=True, read_only=True) # author_list = serializers.ListField(write_only=True) # # def create(self, validated_data): # 创建数据 # 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 更新数据 # 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): # 对传过来的title进行校验 # if "python" not in value.lower(): # raise serializers.ValidationError("标题必须含有python") # return value # # def validate(self, attrs): # if attrs["w_category"] == 1 and attrs["publisher_id"] == 1: # return attrs # else: # raise serializers.ValidationError("分类以及标题不符合要求") # 方法二 class BookSerializer(serializers.ModelSerializer): # 只取想要的字段, category_display = serializers.SerializerMethodField(read_only=True) # 序列化(显示的时候)的 显示 publisher_info = serializers.SerializerMethodField(read_only=True) 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): # obj 是我们序列化的每个Book对象 publisher_obj = obj.publisher return {"id": publisher_obj.id, "title": publisher_obj.title} # category = serializers.CharField(source="get_category_display") class Meta: model = Book # 对应的 model # fields = ["id", "title", "pub_time"] fields = "__all__" # depth = 1 # 字段的额外参数, "write_only": True 反序列化的时候显示 extra_kwargs = {"category": {"write_only": True}, "publisher": {"write_only": True}, "author": {"write_only": True}}
序列化组件小结
原文:https://www.cnblogs.com/wenyule/p/10425487.html