Django REST framework序列化
一.简介
Django REST framework是基于Django实现的一个RESTful风格API框架,能够帮助我们快速开发RESTful风格的API。
官网:https://www.django-rest-framework.org/
中文文档:https://q1mi.github.io/Django-REST-framework-documentation/
二. 安装与配置
1.安装
pip install djangorestframework
2.配置
如果想要获取一个图形化的页面,需要将 rest_framework 注册到项目的INSTALL_APPS中。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bms.apps.BmsConfig',
'rest_framework',
]
三.DRF序列化
我们写项目想返回的是json数据,使用DRF的序列化工具serializer会非常方便
url:
re_path('books/$',views.BooksView.as_view()),
re_path(r'book_pk/(?P<pk>\d+)$', views.BookDetailView.as_view()),
view:
from rest_framework.views import APIView
from app01.serializers import BookModelSerializer
class BooksView(APIView):
# 不带id的查询与新增
"""使用Django REST framework 内置的序列化"""
def get(self, request):
'''以JSON格式返回所有的书籍信息'''
# 1.查出所有的书籍信息
queryset = models.Book.objects.all()
# 2.使用serializers序列化
ser_obj = BookModelSerializer(queryset, many=True) # 多条数据many=True
return Response(ser_obj.data) def post(self, request):
'''创建资源'''
# 1.获取前端提交的数据
# 1.1 APIView
# self.request是谁? 不是Django原来的哪个request self._request才是原来的request
# print(request.data) # APIView 包装的数据
# 2.对数据做有效性校验
ser_obj = BookModelSerializer(data=request.data)
if ser_obj.is_valid():
ser_obj.save() # 调用的是BookSerializer类中的create方法,需要自己去实现
# 3. 拿到序列化的数据去数据库创建新记录
return Response("ok")
else:
return Response(ser_obj.errors) class BookDetailView(APIView):
'''查询具体的书籍,编辑书籍,删除书籍'''
def get(self, request, pk):
# 1,根据pk去查询具体的哪儿本书籍对象
book_obj = models.Book.objects.filter(pk=pk).first()
if book_obj:
# 2. 将书籍对象 序列化成 json格式的数据
ser_obj = BookModelSerializer(book_obj)
# 3. 返回响应
return Response(ser_obj.data)
else:
return Response("无效的书籍id") def put(self, request, pk):
"""修改具体某一本书"""
# 1. 根据pk去查询具体的那本书籍对象
book_obj = models.Book.objects.filter(pk=pk).first()
if book_obj:
# 2. 获取用户 发送过来的数据并且更新对象
# partial=True 允许局部更新,比如只改变部分数据(partial 局部的)
ser_obj = BookModelSerializer(instance=book_obj, data=request.data, partial=True) # form组件中也有类似的实现
if ser_obj.is_valid():
# 3. 保存并返回修改后的数据
ser_obj.save()
return Response(ser_obj.data)
else:
return Response(ser_obj.errors)
else:
return Response("无效的书籍id") def delete(self, request, pk):
'''删除具体某一本书'''
# 1. 根据pk去查询具体的那本书籍queryset对象;注意不是具体的书籍对象,书籍对象没有delete方法
book_obj = models.Book.objects.filter(pk=pk)
if book_obj:
# 删除书籍对象
book_obj.delete()
return Response("删除成功")
else:
return Response("无效的书籍id")
serializers.py
class BookSerializers(serializers.Serializer):
'''使用Serializer,序列化'''
id = serializers.IntegerField(required=False) # required=False 设置为非必须要字段
title = serializers.CharField(max_length=32)
pub_date = serializers.DateField()
CHOICES = ((1, 'Python'), (2, 'Go'), (3, 'Linux'))
# read_only=True 设置为只在查询字段时生效
category = serializers.CharField(source='get_category_display', read_only=True)
# read_only=True 设置为只在添加字段,或修改字段时生效
post_category = serializers.IntegerField(write_only=True) publisher = PublisherSerializer(read_only=True)
post_publisher = serializers.IntegerField(write_only=True) # many= True 当字段对应多条数据时使用
authors = AuthorSerializer(many=True, read_only=True)
post_authors = serializers.ListField(write_only=True) def validate_title(self, attrs):
"""类似于Form组件的局部勾子函数"""
# attrs就是需要检验的这个字段的值
print(attrs) # 红烧牛肉
print('-' * 120)
if '红烧牛肉' in attrs:
raise serializers.ValidationError('你是魔鬼吗?')
else:
return attrs def validate_post_publisher(self, attrs):
# 判断数据库里面有没有你制定的这个出版社
is_exist = models.Publisher.objects.filter(pk=attrs)
if is_exist:
return attrs
else:
raise serializers.ValidationError("你填写的出版社不存在!") # 全局钩子
# def validate(self, attrs):
# pass # 校验合格的数据,要想直接 .save()保存数据必须要重写这个方法
def create(self, validated_data):
# validated_data经过校验的有效数据
book_obj = models.Book.objects.create(
title=validated_data['title'],
pub_date=validated_data['pub_date'],
category=validated_data['post_category'],
publisher_id=validated_data['post_publisher'], #
)
book_obj.authors.set(validated_data['post_authors'])
return book_obj # 在更新数据的时候支持直接调用save()保存数据
def update(self, instance, validated_data):
# print(instance) # 查询出要改变的原数据
# print(validated_data) # 校验合格的更新数据
# 从validated_data中取出数据挨个字段更新
instance.title = validated_data.get('title', instance.title)
instance.pub_date = validated_data.get('pub_date', instance.pub_date)
instance.category = validated_data.get('post_category', instance.category)
instance.publisher_id = validated_data.get('post_publisher', instance.publisher_id)
# 永远都不要高估自己!
instance.save()
# 更新多对多字段的 authors
# 先取出当前书籍的所有作者id
author_list = instance.authors.all().values_list('id') # [(1,),(2,)] ==> [1, 2]
# 然后更新,没变就用原来的数据
instance.authors.set(validated_data.get('post_authors',[i[0] for i in author_list]))
# 返回更新后的数据
return instance # 使用modelserializers
class BookModelSerializer(serializers.ModelSerializer):
'''使用ModelSerializer,序列化'''
# SerializerMethodField 会自动去找 get_字段名 的方法执行(设置了SerializerMethodField)
category_info = serializers.SerializerMethodField(read_only=True) # 查到关联的对象
publisher_info = serializers.SerializerMethodField(read_only=True)
authors_info = serializers.SerializerMethodField(read_only=True) def get_category_info(self, book_obj):
# book_obj ==》 当前被序列化的那个书籍对象
return book_obj.get_category_display() def get_publisher_info(self, book_obj):
# book_obj.pulisher ==> 得到和我这本书关联的出版社对象 # return {
# "id": book_obj.publiser.id,
# "name": book_obj.publiser.name
# }
# ser_obj = PublisherSerializer(book_obj.publisher)
# return ser_obj.data
return PublisherSerializer(book_obj.publisher).data def get_authors_info(self, book_obj):
return AuthorSerializer(book_obj.authors.all(), many=True).data class Meta:
model = models.Book
fields = "__all__"
# depth 1 # 所有有关系的字段都变成 read_only
# exclude = [] # 排除某个字段
extra_kwargs = { # 每个字段的一些额外参数也可更改
'publisher': {'write_only': True},
'authors': {'write_only': True},
'category': {'write_only': True},
}
Django REST framework序列化的更多相关文章
- Django REST Framework序列化器
Django序列化和json模块的序列化 从数据库中取出数据后,虽然不能直接将queryset和model对象以及datetime类型序列化,但都可以将其转化成可以序列化的类型,再序列化. 功能需求都 ...
- [Django REST framework - 序列化组件、source、钩子函数]
[Django REST framework - 序列化组件.source.钩子函数] 序列化器-Serializer 什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有f ...
- Django Rest framework序列化流程
目录 一 什么是序列化 二 Django REST framework配置流程之Serializer 三 Django REST framework配置流程之ModelSerializer 一 什么是 ...
- 02 Django REST Framework 序列化
01-创建序列化类 # 方式一: publish_list = models.Publish.objects.all() # 导入序列化组件 from django.core import seria ...
- python学习-- Django REST framework 序列化数据操作
一.为什么要返回json数据? 一般来说前端要用到从后台返回的数据来渲染页面的时候,这时候后台就需要向前端返回json类型的数据,简单直观便于理解 ,就类似于 {"xxx":{[& ...
- Django REST Framework 序列化和校验 知识点
DRF序列化 Django ORM对象 --> JSON格式的数据 序列化 JSON格式的数据 --> Django ORM数据 反序列化 需要两个工具: from rest_framew ...
- django rest framework 序列化组件总结
序列化组件总结 一. 序列化组件本质上为了实现前后端分离,而进行json序列化的一个组件形式,极大方便了解析数据的作用 二. 所有序列化是基于APIView 解析器实现的,通过内部的多继承关系方便实现 ...
- 在django restful framework中设置django model的property
众所周知,在django的model中,可以某些字段设置@property和setter deleter getter,这样就可以在存入数据的时候进行一些操作,具体原理请参见廖雪峰大神的博客https ...
- django restful framework 一对多方向更新数据库
目录 django restful framework 序列化 一 . 数据模型: models 二. 序列化: serializers 三, 视图: views 四, 路由: urls 五. 测试 ...
随机推荐
- Python Twisted系列教程14:Deferred用于同步环境
作者:dave@http://krondo.com/when-a-deferred-isnt/ 译者:杨晓伟(采用意译) 你可以从这里从头开始阅读这个系列. 介绍 这部分我们要介绍Deferred的 ...
- GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏
GridView导出成Excel字符"0"丢失/数字丢失的处理方式 收藏 GridView 导出成Excel文件,这个代码在网上比较多.但是发现存在一个问题,导出的数据中如果有&q ...
- leetcode598
public class Solution { public int MaxCount(int m, int n, int[,] ops) { ); ); || col == ) { return m ...
- DataGridView根据条件给单元格绑定图片
代码区: private void Form1_Load(object sender, EventArgs e) { myClass.mySqliteAPI conn = new myClass.my ...
- python使用multiprocessing进行多进程编程(1)
multiprocessing模块实现了对多进程编程的封装,让我们可以非常方便的使用多进程进行编程.它的使用方法非常类似threading模块. 1.创建一个进程 import multiproces ...
- Objective-C入门 简介Cocoa框架
Cocoa Framework简称Cocoa,它是Mac OS X上的快速应用程序开发(RAD, Rapid Application Development)框架,一个高度面向对象的(Object O ...
- 缓存数据库redis
什么是Redis? Redis是一个TCP服务器,支持请求/响应协议. 在Redis中,请求通过以下步骤完成: 客户端向服务器发送查询,并从套接字读取,通常以阻塞的方式,用于服务器响应. 服务器处理命 ...
- JS中使用正则表达式
- Java基础知识(二)之控制语句
1.条件运算符 ⑴if...else... ⑵三目表达式——X?Y:Z 当X为真时,结果为Y:反之,为Z. ⑶switch(表达式){ case 1: 执行代码块 1; break: cas ...
- tomcat报503 或者无法启动应用
一般都是配置文件有问题,或者路径问题,或者jvm的参数路径问题.... 总之,报错实在是不清楚!这点比resin差远了!!