DRF Django REST framework 之 序列化(三)
Django 原生 serializer (序列化)
- 导入模块 from django.core.serializers import serialize
- 获取 queryset
- 对 queryset 进行序列化
- 将序列化之后的数据,返回给客户端
首先,设计url, 先只定义GET和POST接口
- from django.urls import path
- from DrfOne import views
- urlpatterns = [
- path('books/', views.BookView.as_view()),
- ]
再定义几个models
- from django.db import models
- class Publish(models.Model):
- nid = models.AutoField(primary_key=True)
- name = models.CharField("出版社名", max_length=32)
- address = models.CharField("出版社位置", max_length=32)
- email = models.EmailField("邮箱")
- def __str__(self):
- return self.name
- class Author(models.Model):
- nid = models.AutoField(primary_key=True)
- name = models.CharField("姓名", max_length=31)
- age = models.IntegerField("年龄")
- def __str__(self):
- return self.name
- class Book(models.Model):
- nid = models.AutoField(primary_key=True)
- title = models.CharField("书名", max_length=32)
- price = models.DecimalField("价格", max_digits=5, decimal_places=2)
- publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
- authors = models.ManyToManyField(to="Author")
- def __str__(self):
- return self.title
models.py
使用
- from django.shortcuts import render, HttpResponse
- from rest_framework.views import APIView
- # 1.导入模块
- from django.core.serializers import serialize
- class CourseView(APIView):
- def get(self, request):
- # 2.获取queryset
- course_obj = models.Course.objects.all()
- # 3.序列化
- serialized_data = serialize("json", course_obj)
- print(serialized_data)
- # 4.将序列化之后的数据返回
- return HttpResponse(serialized_data)
序列化组件serializer的使用
Serializer
GET接口设计(获取所有数据)
- 导入模块
- 建立一个序列化类
- 获取 queryset
- 开始序列化
- 获取序列化后的数据,返回给客户端
- from rest_framework.views import APIView
- # 1.导入模块
- from rest_framework import serializers
- # drf重新封装之后的Response基于TemplateResponse类型,
- # 可以将未处理的内容通过内容协商来决定返回给客户端的正确内容形式
- from rest_framework.response import Response
- from DrfOne import models
- # 2.创建一个序列化类,字段类型不一定要跟models的字段一样
- class BookSerializer(serializers.Serializer):
- # id一般情况不用写
- # nid = serializers.CharField(max_length=32)
- title = serializers.CharField(max_length=32)
- price = serializers.DecimalField(max_digits=5, decimal_places=2)
- # 外键字段,显示__str__方法的返回值
- publish = serializers.CharField()
- # 多对多字段, 执行get_字段名 方法,手动获取数据
- author_list = serializers.SerializerMethodField()
- def get_author_list(self, book_obj):
- # 第二个参数随意
- author_list = list()
- for author in book_obj.authors.all():
- author_list.append(author.name)
- return author_list
- class BookView1(APIView):
- def get(self, request):
- # 3.获取queryset
- book_objs = models.Book.objects.all()
- # 4.通过序列化类进行序列化
- serialized_obj = BookSerializer(book_objs, many=True)
- # print(serialized_obj)
- # 5.获取序列化之后的数据,返回给客户端
- return Response(serialized_obj.data)
POST接口设计
- 导入模块
- 建立一个序列化类
- 获取客户端请求数据
- 开始序列化
- 写入数据库
- 将插入的对象返回给客户端
请注意,因为多对多关系字段是我们自定义的,而且必须这样定义,返回的数据才有意义,而用户插入数据的时候,serializers.Serializer没有实现create,我们必须手动插入数据,就像这样:
- # 1.导入模块
- from rest_framework import serializers
- from rest_framework.views import APIView
- # drf重新封装之后的Response基于TemplateResponse类型,
- # 可以将未处理的内容通过内容协商来决定返回给客户端的正确内容形式
- from rest_framework.response import Response
- from DrfOne import models
- # 2.创建一个序列化类,字段名和字段类型不一定要跟models的字段一样
- class BookSerializer(serializers.Serializer):
- # id一般情况不用写
- # nid = serializers.CharField(max_length=32)
- title = serializers.CharField(max_length=32)
- price = serializers.DecimalField(max_digits=5, decimal_places=2)
- # 外键字段,显示__str__方法的返回值
- publish = serializers.CharField()
- # 仅读字段read_only=True,source是该字段显示出版社地址
- publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
- publish_email = serializers.CharField(max_length=32, read_only=True, source="publish.email")
- # 多对多字段, 执行get_字段名 方法,手动获取数据
- author_list = serializers.SerializerMethodField()
- def get_author_list(self, book_obj):
- # 第二个参数随意
- author_list = list()
- for author in book_obj.authors.all():
- author_list.append(author.name)
- return author_list
- def create(self, validated_data):
- # 创建时调用
- validated_data['publish_id'] = validated_data.pop('publish')
- book = models.Book.objects.create(**validated_data)
- return book
- def update(self, instance, validated_data):
- # 更新数据会调用该方法
- instance.title = validated_data.get('title', instance.title)
- instance.publishDate = validated_data.get('publishDate', instance.publishDate)
- instance.price = validated_data.get('price', instance.price)
- instance.publish_id = validated_data.get('publish', instance.publish.nid)
- instance.save()
- return instance
- class BookView(APIView):
- def get(self, request):
- pass
- def post(self, request):
- # 3.获取客户端的数据
- client_data = request.data
- # 4.序列化,默认many=False单条数据
- verified_data = BookSerializer(data=client_data)
- # 对数据进行验证
- if verified_data.is_valid():
- # 5.写入数据库
- book = verified_data.save()
- authors = models.Author.objects.filter(nid__in=request.data["authors"])
- book.authors.add(*authors)
- # 6.将插入的对象数据返回
- return Response(verified_data.data)
- # 验证失败返回错误信息
- return Response(verified_data.errors)
从上面可以看出:
- serializers.Serializer 无法插入数据,只能自己实现。
- 字段太多,不能自动序列化
这样就会非常复杂化程序,如果我希望序列化类自动插入数据呢?
这也就有了 ModelSerializer
ModelSerializer
ModelSerializer 类似于form组件里的 ModelForm
- from rest_framework import serializers
- from rest_framework.views import APIView
- class BookSerializer(serializers.ModelSerializer):
- class Meta:
- model = models.Book
- fields = "__all__"
- extra_kwargs = {
- # 仅写
- "publish": {'write_only': True},
- "authors": {'write_only': True},
- }
- publish_name = serializers.CharField(max_length=32, read_only=True, source="publish.name")
- publish_address = serializers.CharField(max_length=32, read_only=True, source="publish.address")
- author_name = serializers.SerializerMethodField()
- def get_author_name(self, book_obj):
- author_list = list()
- for author in book_obj.authors.all():
- # 注意列表添加字段,author.name而不是author
- author_list.append(author.name)
- return author_list
这样看起来简单多了!
get(单条数据)、put(改)、delete(删) 接口设计
设计url
- from django.urls import path, re_path
- from DrfOne import views
- urlpatterns = [
- path('books/', views.BookView.as_view()),
- re_path("books/(\d+)/", views.BookFilterView.as_view()),
- ]
视图设计
- class BookFilterView(APIView):
- def get(self, request, nid):
- # 获取queryset
- book_obj = models.Book.objects.get(pk=nid)
- # 序列化
- serialized_data = BookSerializer(book_obj)
- # 返回数据
- return Response(serialized_data.data)
- def put(self, request, nid):
- # 获取queryset
- book_obj = models.Book.objects.get(pk=nid)
- # 序列化, 根据instance是确认是否是更新, many默认为False可以不写
- verified_data = BookSerializer(data=request.data, instance=book_obj, many=False)
- if verified_data.is_valid():
- verified_data.save()
- # 返回数据
- return Response(verified_data.data)
- return Response(verified_data.errors)
- def delete(self, request, nid):
- models.Book.objects.get(pk=nid).delete()
- return Response("")
~>.<~
DRF Django REST framework 之 序列化(三)的更多相关文章
- 轻轻松松学会 DRF Django REST framework
据我了解,目前的IT行业的大部分后端开发,都是需要进行前后端分离的,而前后端分类必不可少的是rest 规范,以下是django rest framework的学习路径: DRF Django REST ...
- Django Rest framework 之 序列化
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- DRF Django REST framework APIView(一)
什么是REST? REST是一个标准,一种规范,遵循REST风格可以使开发的接口通用,便于调用者理解接口的作用. 使url更容易理解,让增删改清晰易懂,在前后端分离开发中按照这一规范能加快开发效率,减 ...
- Django REST Framework的序列化器是什么?
# 转载请留言联系 用Django开发RESTful风格的API存在着很多重复的步骤.详细可见:https://www.cnblogs.com/chichung/p/9933861.html 过程往往 ...
- DRF Django REST framework 之 解析器(二)
引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...
- Django rest framework之序列化小结
最近在DRF的序列化上踩过了不少坑,特此结合官方文档记录下,方便日后查阅. [01]前言 serializers是什么?官网是这样的”Serializers allow complex d ...
- django rest framework serializers序列化
serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用: - 将queryset与model实例等进行序列化,转化成json格式,返回给用户(a ...
- Django Rest Framework(2)-----序列化详解(serializers)
REST framework中的序列化类与Django的Form和ModelForm类非常相似.我们提供了一个Serializer类,它提供了一种强大的通用方法来控制响应的输出,以及一个ModelSe ...
- DRF (Django REST framework) 中的视图类
视图说明 1. 两个基类 1)APIView rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父 ...
随机推荐
- IoTClient开发4 - ModBusTcp协议服务端模拟
前言 上篇我们实现了ModBusTcp协议的客户端读写,可是在很多时候编写业务代码之前是没有现场环境的.总不能在客户现场去写代码,或是蒙着眼睛写然后求神拜佛不出错,又或是在办公室部署一套硬件环境.怎么 ...
- Windows终端利器Cmder
在IT这一行,大部分情况下都是推荐大家使用Linux或者类Unix操作系统去编程,Linux作为一代优秀的操作系统,已经人尽皆知,在IT行业已经成为核心.有条件的大佬都选择了使用mac编程,最优秀的莫 ...
- 在VMware环境下安装CentOS7
1. 软件准备: 推荐使用VMware,在这里我使用的是VMware15 映像:可以去官网下载,没有的话也可以在下方链接里下载 链接:https://pan.baidu.com/s/1r_7K-UI0 ...
- Servlet——用户登录案例
案例:用户登录 * 用户登录案例需求: 1.编写login.html登录页面 username & password 两个输入框 2.使用Druid数据库连接池技术,操作mysql,day14 ...
- SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - 自定义Servlet、Filter、Listener是如何注册到Tomcat容器中的?(SpringBoot实现SpringMvc的原理)
上一篇我们讲了SpringBoot中Tomcat的启动过程,本篇我们接着讲在SpringBoot中如何向Tomcat中添加Servlet.Filter.Listener 自定义Servlet.Filt ...
- RabbitMQ学习笔记之五种模式及消息确认机制
本文详细介绍简单模式Simple.工作模式Work.发布订阅模式Publish/Subscribe.Topic.Routing. Maven依赖引用 <dependencies> < ...
- rsync同步基本用法
...
- iOS开发调试概览
概述 我们都知道Xcode默认的调试器是LLDB(在此之前使用的是GDB),但是关于LLDB的debug技巧并非所有人都比较清楚,可能所有人都知道p或者po命令打印一些变量.但是实际的情况时这些还远远 ...
- 使用RNN进行imdb影评情感识别--use RNN to sentiment analysis
原创帖子,转载请说明出处 一.RNN神经网络结构 RNN隐藏层神经元的连接方式和普通神经网路的连接方式有一个非常明显的区别,就是同一层的神经元的输出也成为了这一层神经元的输入.当然同一时刻的输出是不可 ...
- linux 内核版本和发行版本区别
内核版本:我的理解是,内核是系统的心脏,是linux中最基层的代码.版本号如 Linux version 3.10.0-514.el7.x86_64 查看内核版本可使用.uname -a 或者cat ...