DRF中的request

在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等。

比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据。

在APIView中封装的request,就实现了请求数据的解析:

对于GET请求的参数我们通过request.query_params来获取。

对于POST请求、PUT请求的数据我们通过request.data来获取。

视图的使用:

1 前提之序列化

# 首先需要在setting中注册rest_framework的中间件

from rest_framework import serializers
from crm import models class PublisherModel(serializers.ModelSerializer):
class Meta:
model =models.Publisher
fields = '__all__' class AuthorModel(serializers.ModelSerializer):
class Meta:
model = models.Author
fields = '__all__' class BookSerializers(serializers.Serializer):
id = serializers.IntegerField(required=False)
name = serializers.CharField(max_length=32)
pub_date = serializers.DateField() CHOICES = ((1, 'python'), (2, 'go语言'), (3, 'linux'))
# source设置数据读取时候读取到 CHOICES里面的内容,read_only设置只在读取时有效
category = serializers.CharField(source='get_category_display',read_only=True)
post_category = serializers.IntegerField(write_only=True) # 对出版社字段进行校验 读取时,和设置是显示的格式不同
publisher = PublisherSerializers(read_only=True)
post_publisher = serializers.IntegerField(write_only=True) # 对作者字段进行校验
author = AuthorSerializers(many=True, read_only=True)
post_author = serializers.ListField(write_only=True) # create方法相当于对每个通过校验的字段进行获取在数据库中新建保存
def create(self, validated_data): # validated_data里面保存的是校验通过后的数据
book_obj = models.Book.objects.create(
name=validated_data["name"],
pub_date=validated_data["pub_date"],
category=validated_data["post_category"],
publisher_id=validated_data["post_publisher"]
)
book_obj.author.set(validated_data["post_author"]) # 多对多字段需要重新设置关系
return book_obj def update(self, instance, validated_data):
# 从validated_data中取出数据挨个字段更新
instance.name = validated_data.get('name', instance.name)
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.author.all().values_list('id') # [(1,),(2,)] ==> [1, 2] instance.author.set(validated_data.get('post_authors', [i[0] for i in author_list]))
return instance

serializers

2 初级阶段

from rest_framework.response import Response
from rest_framework.views import APIView # 图书的展示以及添加
class Book(APIView): # 继承改为restframework的封装的APIView
def get(self, request):
# 1,在后端获取数据
book_obj = models.Book.objects.all()
# 2,使用seriallizers进行数据格式化
ser_obj = BookSerializers(book_obj, many=True)
# 返回给前端 Response方法是serializers封装的方法
return Response(ser_obj.data) def post(self, request):
# 1, 在前端获取提交的数据
# 此时的request已经是被serializers封装过的request,不是简单的页面提交的那个request
# 前端提交的数据存在request.data里面 print(request.data)
# 2, 进行serializers校验
ser_obj = BookSerializers(data=request.data)
if ser_obj.is_valid(): # 如果通过了校验
print("oye")
# 数据校验通过以后,想要使用save方法保存的话,需要调用BookSerializers里面的create方法
ser_obj.save()
return Response('数据添加成功!')
else: # 没通过校验的数据,返回错误信息
print('ono')
return Response(ser_obj.errors) # 具体图书信息的展示以及修改和删除
class BookDetail(APIView): def get(self, request, pk):
book_obj = models.Book.objects.filter(pk=pk).first() if book_obj:
ser_obj = BookModel(book_obj) # 对数据进行有效性校验
return Response(ser_obj.data)
else:
return Response('无效的id') def put(self, request, pk):
book_obj = models.Book.objects.filter(pk=pk).first()
if book_obj:
ser_obj = BookSerializers(instance=book_obj, data=request.data, partial=True) # 此处得到request已经是封装过的,partial表示局部更新
if ser_obj.is_valid():
ser_obj.save()
return Response(ser_obj.data)
else:
return Response(ser_obj.errors)
else:
return Response('无效的id') def delete(self,request,pk):
book_obj = models.Book.objects.filter(pk=pk).first()
if book_obj:
book_obj.delete()
return Response("删除成功")
else:
return Response("无效的id")

3 强化版

from django.contrib import admin
from django.urls import path,re_path
from crm import views
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', views.Book.as_view()),
re_path('book/(?P<pk>\d+)/$', views.BookDetail.as_view()), path('author/', views.Authorshow.as_view()),
re_path('author/(?P<pk>\d+)/$', views.AuthorDetail.as_view()), path('publisher/', views.Publishershow.as_view()),
re_path('publisher/(?P<pk>\d+)', views.PublisherDetail.as_view()), ]

路由

# 公共类,获取数据使用
class GerneridView(APIView):
queryset = None
serializer_class = None def get_queryset(self):
queryset = self.queryset.all() # 刷新数据
return queryset def get_object(self, request, pk, *args, **kwargs):
queryset = self.queryset.filter(pk=pk).first()
return queryset class ListMixin(object):
def get(self, request):
queryset = self.get_queryset()
ser_obj = self.serializer_class(queryset, many=True)
return Response(ser_obj.data) class CreateMixin(object):
def post(self, request):
ser_obj = self.serializer_class(data=request.data)
if ser_obj.is_valid():
ser_obj.save()
return Response('OK')
else:
return Response(ser_obj.errors) class ActreveMixin(object):
def get(self, request, pk, *args, **kwargs):
obj = self.get_object(request, pk, *args, **kwargs)
if obj:
ser_obj = self.serializer_class(obj)
return Response(ser_obj.data)
else:
return Response("无效的id") class UpdateMixin(object):
def put(self, request, pk, *args, **kwargs):
book_obj = self.get_object(request, pk, *args, **kwargs)
if book_obj:
ser_obj = AuthorModel(instance=book_obj, data=request.data, partial=True)
if ser_obj.is_valid():
ser_obj.save()
return Response("数据更新成功")
else:
return Response(ser_obj.errors)
else:
return Response("无效的id") class DelMixin(object):
def delete(self,request, pk, *args, **kwargs):
obj = self.get_object(request, pk, *args, **kwargs)
if obj:
obj.delete()
return Response('删除成功')
else:
return Response("无效的id") class Authorshow(GerneridView, ListMixin, CreateMixin):
queryset = models.Author.objects.all()
serializer_class = AuthorModel class AuthorDetail(GerneridView, ActreveMixin, UpdateMixin, DelMixin):
queryset =models.Author.objects.all()
serializer_class = AuthorModel

面向对象封装版

4 究极进化版

from django.urls import path,re_path
from bms import views
urlpatterns = [
path('admin/', admin.site.urls), # 作者相关操作
path('author/', views.AuthorShow.as_view(actions={'get': 'list', 'post': 'create'})),
re_path('author/(?P<pk>\d+)/$', views.AuthorShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), # 出版社相关操作
path('publisher/', views.PublisherShow.as_view(actions={'get': 'list', 'post': 'create'})),
re_path('publisher/(?P<pk>\d+)/$', views.PublisherShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), # 图书相关增删改查操作
path('books/', views.BooksShow.as_view(actions={'get': 'list', 'post': 'create'})),
re_path('books/(?P<pk>\d+)/$', views.BooksShow.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ]

路由

from bms import models
# Create your views here.
from rest_framework.viewsets import ModelViewSet
from bms.serializer import AuthorModel, PublisherModel, BookModel class AuthorShow(ModelViewSet):
queryset = models.Author.objects.all()
serializer_class = AuthorModel class PublisherShow(ModelViewSet):
queryset = models.Publisher.objects.all()
serializer_class = PublisherModel class BooksShow(ModelViewSet):
queryset = models.Book.objects.all()
serializers = BookModel

究极进化版

5 无比强大的路由

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(r'school', views.SchoolView)
urlpatterns += router.urls

6 一张不明觉厉的图

DjangoRESTFrameWork中的视图的更多相关文章

  1. (转) PowerDesigner中Table视图同时显示Code和Name

    PowerDesigner中Table视图同时显示Code和Name,像下图这样的效果: 实现方法:Tools-Display Preference

  2. postgres中的视图和物化视图

    视图和物化视图区别 postgres中的视图和mysql中的视图是一样的,在查询的时候进行扫描子表的操作,而物化视图则是实实在在地将数据存成一张表.说说版本,物化视图是在9.3 之后才有的逻辑. 比较 ...

  3. 代码生成工具Database2Sharp中增加视图的代码生成以及主从表界面生成功能

    在代码生成工具的各种功能规划中,我们一向以客户的需求作为驱动,因此也会根据需要增加一些特殊的功能或者处理.在实际的开发中,虽然我们一般以具体的表进行具体业务开发,但是有些客户提出有时候视图开发也是很常 ...

  4. Tips7:Unity中 Scene视图 和 Game视图 中 视角(Camera)的控制

    选中你要改变的相机,然后点击GameObject-->Align With View 选项(快捷键Ctrl+Shift+F)使相机视角和当前Sence视图中一样 通过这样可以控制在Game视图( ...

  5. Mysql中的视图

    什么是视图 通俗的讲,视图就是一条SELECT语句执行后返回的结果集.所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上. 视图的特性 视图是对若干张基本表的引用,一张虚表,查询语句执 ...

  6. .NET中的视图和过滤器 (DefaultView和RowFilter)

    NET中的视图和过滤器 (DefaultView和RowFilter) ADO.NET中有一层对象,用来创建任意数据源的抽象模型.其中包括DataSet,DataTable,DataRow,DataV ...

  7. SQLServer中在视图上使用索引(转载)

    在SQL Server中,视图是一个保存的T-SQL查询.视图定义由SQL Server保存,以便它能够用作一个虚拟表来简化查询,并给基表增加另一层安全.但是,它并不占用数据库的任何空间.实际上,在你 ...

  8. ThinkPHP中的视图二

    ThinkPHP中的视图 1.模板注释 在实际项目开发中,经常要使用注释功能,如果是ThinkPHP框架,则可以在模板文件中使用如下方式进行注释: {// 注释内容 } :单行注释 {/* 注释内容 ...

  9. ThinkPHP中的视图

    ThinkPHP中的视图View 1.什么是视图View 所谓的视图就是用户可视化操作界面. 2.视图View组成 view类(模板引擎类似Smarty) 模板文件(html模板) 3.视图的定义 默 ...

随机推荐

  1. func_get_args func_num_args 的使用

    func_get_args是获取方法中参数的数组,返回的是一个数组,与func_num_args搭配使用: func_num_args一般写在方法中,用于计数 function eeee($a='gg ...

  2. linux命令详解——tar

    tar [-cxtzjvfpPN] 文件与目录 .... [参数]: -c :建立一个压缩文件的参数指令(create 的意思): -x :解开一个压缩文件的参数指令! -t :查看 tarfile ...

  3. error: (-215) !empty() in function detectMultiScale

    tips: pip install opencv-python or https://www.lfd.uci.edu/~gohlke/pythonlibs/ 原因确实是找不到 opencv 的 xml ...

  4. Linux 学习 (一)

    最常用的7个Linux命令: cd:切换目录. pwd:查看当前所在目录. ls:查看目录下的文件. touch:没有文件则创建文件. mkdir:创建目录. mr:remove删除.         ...

  5. C#使用反射机制获取类信息

    1.用反射动态创建类实例,并调用其公有成员函数. //新建一个类库项目,增加一个GetSum方法. using System;   namespace ClassLibrary1 {    publi ...

  6. netlink对中断的支持

    http://blog.chinaunix.net/uid-24227137-id-3025783.html https://blog.csdn.net/tycoon1988/article/deta ...

  7. Java线程与Linux内核线程的映射关系(转)

    Java线程与Linux内核线程的映射关系 Java线程与Linux内核线程的映射关系Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程 ...

  8. 【洛谷P2647】最大收益

    题目大意 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品.其中第i个物品有两个属性Wi和Ri,当你选择了第i个物品后,你就可以获得Wi的收益:但是,你选择该物 ...

  9. 解决:java compiler level does not match the version of the installed java project facet错误

    java compiler level does not match the version of the installed java project facet错误的解决 因工作的关系,Eclip ...

  10. DevExpress WPF v19.1新版亮点:PDF Viewer等控件新功能

    行业领先的.NET界面控件DevExpress 日前正式发布v19.1版本,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WPF v19.1中新增的一些控件及部 ...