1.http请求协议
1.cbv
django.vuews import View
classs LoginView(View):
def get(self,requset):
pass
2.classmethod $ classonlymethod
3.getattr hasattr setattr
4.self定位
- 始终代表调用者本身
5.http请求协议:就是约定成俗的规范,解析数据的规范
6.form enctype
解析参数的格式
7. javascript object {name: "alex"} ===>json转换的方式
7.1 data:Json.stringify({name: "alex", age: 18}) ==>json.dumps(data)
JSON.parse(data) ===> json.loads()
今日详情:
1. djaong-restframework
1.1 ApiVIew
urlpatterns = [
re_path('^course/$', views.CourseView.as_view()),
]
url_mapping = {
"login": "LoginView"
}
第一步:从as_view向里看
rest-framework如何对django的view进行扩展的呢
1.2 解析器组件
1.3 序列化组件
1.4 认证组件
1.5 权限组件
1.6 频率组件
1.7 url控制器组件
1.8 分页组件
1.9 响应器组件
今日内容总结:
知识点复习总结
什么是编程
数据结构+算法
什么是rest
https://www.jd.com #通过url拿到数据 2.1原始url 127.0.0.1:8001/books/id/ 127.0.0.1:8001/books/?name="" 127.0.0.1:8001/books/delet/id/ 这种url方式使得接口看起来多而且杂,维护不方便 url用来唯一定位资源,用http请求方式来区分用户对数据的操作方式 2.2rest url 1.url设置规范 GET:127.0.0.1:8001/books/ # 获取所有数据 GET:127.0.0.1:8001/books/id/ # 获取单挑数据 POST:127.0.0.1:8001/books/ # 增加数据 DELETE:127.0.0.1:8001/books/id/ # 删除数据 UPDATE:127.0.0.1:8001/books/id/ # 更改数据 2.数据响应规范 GET:127.0.0.1:8001/books/ # 获取所有数据 返回[{}, ,] GET:127.0.0.1:8001/books/id/ # 获取单挑数据 返回{}单条数据 POST:127.0.0.1:8001/books/ # 增加数据 返回{}添加成功 DELETE:127.0.0.1:8001/books/id/ # 删除数据 返回‘’返回空 put/UPDATE:127.0.0.1:8001/books/id/ # 更改数据 返回更新后的完整数据 3.错误处理 {"error":"message"}
cbv
classmethod & classonly method
getattr hasattr setattr
动态对对象的属性进行操作
self定位
始终定位的是自己
http请求数据的协议
后端用什么方式来解析请求的数据
from表单的enctype里面的三种请求协议
urlencoded, multi-formdata, text/plain
JavaScript object 序列化成json
object ===>json(json.stringify) json====>object(JSON.parse())
class LoginView(ApiView):
def post(self,request):
data = request.data #新的request对象
return
class ApiVIew(View):
@classmethod
def as_view(self, request):
pass
super(ApiView,self).as_view(**initkwargs)
def dispatch():
request = self.initialize_request(request, *args, **kwargs)
self.request = request
parser_context = self.get_parser_context(request)
return Request(
request, # 原生reqeust
parsers=self.get_parsers(), # get_parsers()
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
ApiView.py中的
def get_parsers(self):
"""
Instantiates and returns the list of parsers that this view can use.
"""
return [parser() for parser in self.parser_classes]
from rest_framework.request import Request
data = request.data #新的request对象
从reqeust中.出来的,所以其Request中找这个属性
3.解析器源码流程:
__getattr__在属性未找到的时候
第一步:执行as_view()
第二步:自己写的里面没有as_view()函数去父类中找
第三部:执行view中的as_view()方法,返回view函数
第四步:url和驶入函数之间的绑定关系建立完毕{“login”: view}等待用户请求
第五步:接收到用户请求:login,到建立好的关系里面执行对应的视图函数:view(request)
第六步:视图函数的执行结果是什么就返回给客户,self.dispatch(),self.dispatch()的执行结果
第七步:此时的self代表的是LoginView的实例对象
第八步:开始找dispatch方法,self里面没有,LoginVIew里面也咩有,在ApiView中
第九步:开始执行apiview中的dispatch方法
第十步:在最后找到http方法(get,post,put,delete),根据请求的类型查找(reqeust.method.lower())
第十一步:执行第十步找到的方法,开始执行找到的方法self.get()代表的是LoginView的实例化对象
11.1 假设接受到的时候POST请求,执行reuqest。data
11.2 分析结果,所有的解析工作都是在request。data里面实现的,且data是一个方法(被属性化之后的)
11.3 拿取data
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
11.4 执行_load_data_and_files()
11.5 parser = self.negotiator.select_parser(self, self.parsers)
11.5.1parsed = parser.parse(stream, media_type, self.parser_context)
11.5.2 self.get_parses()
return [parser() for parser in self.parser_classes]
11.5.3 parser_classes = api_settings.DEFAULT_PARSER_CLASSES
11.5.4 api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
11.5.6 APISettings是一个类
11.5.7 找不到parser_classes = api_settings.DEFAULT_PARSER_CLASSES
的时候就去__getattr__里面找
11.5.8 __getattr__里面有这么一句话 val = self.user_settings[attr]
@property
def user_settings(self):
if not hasattr(self, '_user_settings'):
self._user_settings = getattr(settings, 'REST_FRAMEWORK', {})
return self._user_settings
11.5.9 首先找自己的settiongs,之后找rest_framework的settings
11.6 得到self._data = parsed.data
11.7 DRF将self.date = self._data
11.8 reqeust.data
第十二部:在loginView里面找到对应的方法,执行该方法,最后返回给用户
- DRF的所有功能都是在as_view()和dispatch()里面重写的
- 而解析器组件在dispatch方法里面重写了,具体实在重新封装的Request对象中
class ParseJson():
pass
class ParseForm():
data = request.body.decode('utf-8')
data.split("&")
return data
def select_parse(request,ParseJson, ParseForm):
return
知识点回顾:
1.cbv
2.classmethod & classonlymethod
from django.utils.decorators import classonlymethod
class JinJa(object):
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def sleeping(cls):
print("sleeping")
@classonlymethod
def shui(cls):
print("shui_jiao")
装饰器在类加载的时候执行。
3.getattr,hasattr,setattr
4.self定位
谁调用就是谁。
5.http请求协议
6.form enctype
7.JavaScriot object {name: "pizza"} =====>json转换
# 可以建立一个apps文件夹,将每个app放入其中
APPS_DIR= os.path.join(BASE_DIR, "apps")
sys.path.append(APPS_DIR)
2.view的请求流程
1.通过as_view
def view(request, *args, **kwargs):
# 实例化一个对象,对象名称为self,self是cls的对象,谁调用cls
# cls就是谁(当前调用cls的是BookVIew)
# 所以,此时的self就是BookView的实例化对象
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.setup(request, *args, **kwargs)
返回函数 return self.dispatch(request, *args, **kwargs)
2.执行dispatch方法
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 此时的request对象指向原始的request对象
# 给self这个实例化对象赋值:原始的request(下面这行代码对request进行加工)
request = self.initialize_request(request, *args, **kwargs)
# 重新对request进行赋值
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
# 通过请求的方式进行路由匹配,如果早安全的方式里就尝试获取执行的函数
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
# 获取不到就报错
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
# 通过异常处理,对异常结果进行返回
response = self.handle_exception(exc)
# 对返回结果进行处理
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
4.rest使用方式
1.from rest_framework.views import APIVIew
2.继承VPIView
class HomeView(APIVIew):
def get(self):
pass
3.url.py
from django.urls import path,include,re_path
urlpatterns = [
re_path('^course/$', views.CourseView.as_view()),
]
4.def post(self,request):
origin_data = request.data
......
return HttpResonse({})
源码剖析:request.data是从哪里来的?
1.dispatch方式中对request进行重新构造
request = self.initialize_request(request, *args, **kwargs)
def initialize_request(self, request, *args, **kwargs):
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
)
# 1.1自己里面没有定义
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
self._request = request
self.parsers = parsers or () # self.get_parsers()的结构
# 1.2还是在Requet里面找
@property
def data(self):
if not _hasattr(self, '_full_data'):
self._load_data_and_files()
return self._full_data
# 1.3_load_data_and_files()
def _load_data_and_files(self):
if not _hasattr(self, '_data'):
self._data, self._files = self._parse() # 执行执行这个方法
if self._files:
self._full_data = self._data.copy()
self._full_data.update(self._files)
else:
if is_form_media_type(self.content_type):
self._request._post = self.POST
self._request._files = self.FILES
# 1.4 self._parse()
def _parse(self):
parser = self.negotiator.select_parser(self, self.parsers) # 解析器对象
parsed = parser.parse(stream, media_type, self.parser_context) # 解析之后的结果
return (parsed.data, parsed.files)
# 1.5 self.parsers # 获取解析器
def get_parsers(self):
return [parser() for parser in self.parser_classes]
# 1.6 self.parser_classes 一个属性
class APIView(View):
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
api_settings = APISettings(None, DEFAULTS, IMPORT_STRINGS)
# 因为找不到所以执行__getattr__方法
def __getattr__(self, attr):
try:
val = self.user_settings[attr] # 我们项目的settings文件中的默认参数
except KeyError:
# 没找到就去找rest的settings获取默认的参数
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr) # 这里的到的解析器类对象列表
# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val # 这里返回的就是解析器列表
# 1.7 perform_import(val, "DEFAULT_PARSER_CLASSES")
# val是这个:
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
],
def perform_import(val, setting_name)
if val is None:
return None
elif isinstance(val, str):
return import_from_string(val, setting_name)
elif isinstance(val, (list, tuple)):
return [import_from_string(item, setting_name) for item in val]
return val
# 1.8
def import_from_string(dotted_path):
try:
module_path, class_name = dotted_path.rsplit('.', 1)
except ValueError as err:
raise ImportError("%s doesn't look like a module path" % dotted_path) from err
module = import_module(module_path) # 动态导包进行包的获取
try:
return getattr(module, class_name)
super方法的解释
1.不使用super我们可以通过以下方式
class JinJa:
def __init__(self):
print("jinja is a parse")
class To:
def __init__(self):
To.__init__(self,)
2. 使用super方式
2.1 python2
class JinJa:
def __init__(self):
print("jinja is a parse")
class To:
def __init__(self):
super(TO,self).__init__(*args, **kwargs)# super(参数必须传递,self)有参数必须传递参数
2.2 python3
class JinJa:
def __init__(self):
print("jinja is a parse")
class To:
def __init__(self):
super().__init__(*args, **kwargs)# 有参数必须传递参数
*动态导包
import importlib
moudle = input("请输入要导入的模块:")
moudle = importlib.import_module(module)
# 通过字符串方式引入模块
知识点回顾:
1.三元运算:“alex” if a else "wusir"
2.列表推导式
3.__getattr__
4.djaong settiong文件查找顺序global_settings
5.动态import
6.Django原生的
5.序列化器
# django原生的serializer
from django.core.serializers import serialize
class CourseView(APIView):
# 这是局部的解析器,自定制的地方
parser_classes = [FormParser, JSONParser]
def get(self, request):
course_list = list()
cour = Course.objects.all()
for course in cour:
course_dict = {
"course_name": course.course_name,
"description": course.description,
}
course_list.append(course_dict)
ser_data = serialize("json", cour)
print(ser_data)
# ensure_ascii显示中文
return HttpResponse(json.dumps(course_list, ensure_ascii=False))
# 1.开始使用序列化类
- 导入模块
- 建立一个序列化类
- 获取queryset
- 开始序列化
- 获取序列化后的数据,返回给客户端
class BookSerializer(serializers.Serializer):
# nid = serializers.IntegerField()
title = serializers.CharField(max_length=32)
price = serializers.DecimalField(max_digits=10, decimal_places=2)
# 可以使用source字段覆盖当前的字段的显示,read_only只读字段
publish = serializers.CharField(max_length=32)
publish_name = serializers.CharField(read_only=True, max_length=32, source="publish.name")
city_name = serializers.CharField(read_only=True, max_length=32, source="publish.city")
# authors = serializers.CharField(max_length=32)
authors = serializers.SerializerMethodField()
# instance是这次循环的书籍对象(额外字段都可以)
def get_authors(self, instance):
author_list = []
for author in instance.authors.all():
author_list.append(author.name)
return author_list
# 如果用的是Serializer,这里需要你自己写create方法
def create(self, validated_data):
validated_data["publish_id"] = validated_data.pop('publish')
book_obj = Book.objects.create(**validated_data)
return book_obj
class BookView(APIView):
def get(self, request):
# 获取queryset
origin_data = Book.objects.all()
# 将获取到的数据传入序列化类,数据多条是many=True
ser_data = BookSerializer(origin_data, many=True)
return Response(ser_data.data)
def post(self, request):
client_data = request.data
ser_data = BookSerializer(data=client_data)
if ser_data.is_valid():
book = ser_data.save()
authors = Author.objects.filter(nid__in=request.data["authors"])
book.authors.add(*authors)
return Response(ser_data.data)
else:
return Response(ser_data.errors)
知识点回顾:
1.解析器组件
- 解析器组件是用来解析用户请求的数据的(application/json), content-type
- 必须继承APIView
- request.data触发解析
2.序列化组件
2.1 Django自带的serializer
2.1.1 from django.serializer import serialize
2.1.2 Origin_data = Book.object.all()
2.1.3 serializer_data = serialzie("json", origin_data)
2.2 DRF的序列组件
- get 接口设计
2.2.1 from rest_framwork import serializers
2.2.2 创建一个序列化类
class BookSerialzier(serializer.Serializer):
publish_name = serializer(read_obly=True, source="publish.name")
authors_list = serialzier.SerializerMethodField()
def get_authors_list(self, instance):
pass
2.2.3 开始序列化
origin_data = Book.objects.all()
ser_data = BookSerializer(data=origin_data, many=true)
return Response(ser_data.data)
- post接口设计
总结:
1.serializers.Serialzier无法插入数据,需要自己实现create
2.字段太多,不能自动序列化
- get 单条数据接口设计
1.定义url
2.获取数据对象
3.开始序列化:ser_data = BookSerializer(instance=book_obj)
4.返回数据: return Response(ser_data.data)
- delete
- put
1.定义url
2.获取数据对象
2.1 book_obj = Book.objects.get(pk=1)
3.开始序列化(验证数据,save(0))
3.1ser_data = BookSerializer(instance=book_obj, many=False)
4.返回数据: return Response(ser_data.data)
serializers.py
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
extra_kwargs = {
# "publish": {"write_only": True},
# "authors": {"write_only": True},
}
publish_name = serializers.CharField(read_only=True, max_length=32, source="publish.name")
city_name = serializers.CharField(read_only=True, max_length=32, source="publish.city")
# authors = serializers.SerializerMethodField()
# def get_authors(self, instance):
# author_list = []
# for author in instance.authors.all():
# author_list.append(author.name)
# return author_list
6.今日内容:
今日内容:
1.接口设计
2.视图组件
- 试图组件是用来优化接口逻辑的
前提提要:
- 多继承
今日详细:
- 使用试图组件进行接口优化
- 使用试图组件mixin进行接口逻辑优化
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin
from rest_framework.generics import GenericAPIView
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
注意:单条数据操作的url是这样的re_path('^book/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class BookFilterView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
- 使用试图组件的view进行接口逻辑优化
- 导入模块
from rest_framework import generic
- 写视图类
class BookView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
class BookFilterView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
- 使用viewset优化接口逻辑
- 编写url
urlpatterns = [
re_path('^book/$', views.BookView.as_view(actions={
"get": "list",
"post": "create"
})),
re_path('^book/(?P<pk>\d+)/$', views.BookView.as_view({
"get": "retrieve",
"put": "update",
"delete": "destroy"
})),
]
- 导入模块
from rest_framework.viewset import ModelViewSet
- 设计视图类
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
知识点回顾:
1.继续设计接口
1.1 post接口设计
- 如果使用serializer.Serialiezer会有如下问题:
1.需要手动插入数据(必须自定义create方法)
2.手动序列化需要的字段
- 为了解决上面的问题,我们建议使用serializer.ModelSerializer
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = "__all__"
extra_kwargs = {
# "publish": {"write_only": True},
# "authors": {"write_only": True},
}
publish_name = serializers.CharField(read_only=True, max_length=32, source="publish.name")
city_name = serializers.CharField(read_only=True, max_length=32, source="publish.city")
authors = serializers.SerializerMethodField()
def get_authors(self, instance):
author_list = []
for author in instance.authors.all():
author_list.append(author.name)
return author_list
1.2 delete接口设计
class BookView(ApiView):
def delete(self, request, id):
obj = Book.objects.get(pk=id).delete()
reutrn Response()
1.3 put接口设计
class BooKFilterView(APIVIew):
def put(self,reqeust,id):
data = request.data
book_obj = Book.objects.get(pk=id)
ser_data = BookSerializer(data=request.data, instance=book_obj,many=Flase)
if ser_data.is_valid():
ser_data.save()
return Response(res_data.data)
else:
return Response(res_data.errors)
1.4 get获取单条
class BooKFilterView(APIVIew):
def get(self,reqeust,id):
book_obj = Book.objects.get(pk=id)
ser_data = BookSerializer(instance=book_obj,many=Flase)
return Response(ser_data.data)
2.视图组件(mixin, genericview, viewset)
视图组件是用来优化接口逻辑的
2.1 使用mixin的使用
- 导入
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestoryModelMixin,RetireveModelMixin
from rest_framework.genericview import GenericAPIView
- 设计视图类
class BooKView(ListModelMixin, CreateModelMixin, GenericAPIView):
serializer_classes = BooKSerialzier
queryset = Book.objects.all()
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
2.2 mixin源码剖析
总结:
day:1
- 1.什么是编程
- 2.什么是rest
- 3.BS架构中,客户端通过url来访问客户端的资源(数据)
- 4.传统的url中设计里面包含动词(理论上来说,可以实现业务需求)
- 5.rest
url是唯一定位资源,http请求方式描述用户行为
GET:127.0.0.1:8001/books/ # 获取所有数据
GET:127.0.0.1:8001/books/id/ # 获取单挑数据
POST:127.0.0.1:8001/books/ # 增加数据
DELETE:127.0.0.1:8001/books/id/ # 删除数据
UPDATE:127.0.0.1:8001/books/id/ # 更改数据
返回规范:
GET:127.0.0.1:8001/books/ # 获取所有数据 返回[{}, ,]
GET:127.0.0.1:8001/books/id/ # 获取单挑数据 返回{}单条数据
POST:127.0.0.1:8001/books/ # 增加数据 返回{}添加成功
DELETE:127.0.0.1:8001/books/id/ # 删除数据 返回‘’返回空
put/UPDATE:127.0.0.1:8001/books/id/ # 更改数据 返回更新后的完整数据
错误处理
{"error":"error_message"}
- 6.CBV
- 定义view.py
from django.views import View
class BookView(View):
def get(self. request):
pass
def post(self, request):
pass
- 定义url.py
from django.urls import re_path
urlpatterns = [
re_path("`book/$", views.BookVIew.as_view()),
]
@classonlymethod
def as_view(cls, *arg, **kwargs):
def view(request):
self = cls(**args)
return self.dispath()
return view
def dispatch(self,request):
if hasattr(self, self.method.lower(),):
handler = getattr(self, self.method.lower())
else:
raise
return handler(reqeust, *args, **kwargs)
- 7.django restframework
- 本质上是一个django app 用来帮助我们更快的开发出符合rest规范的web app
- pip install django
- pip install djangorestframework
- 定义views.py
from rest_framework.views import APIVIew
class ApiView(view);
@classonlymethod
def as_view(cls, request, *args, *8kwargs);
view = super(APIView, cls).as_view()
return view
def dispatch(self,request):
if hasattr(self, self.method.lower(),):
handler = getattr(self, self.method.lower())
else:
raise
return handler(reqeust, *args, **kwargs)
class BookView(APIView):
def get(self, reqeust):
pass
- 定义url.py
from django.urls import re_path
url_parttrens = [
re_path("books/`$", BookView.as_view()),
]
- 8.drf解析器
- 定义views.py
from django.https import JsonResponse
from rest_framework.views import APIView
from rest_framework.reqeust import Request
class Request(request):
def __init__(self, parsers=get_parser()):pass
def _parse(self):
parser = self.negotiator.select_parser(self, self.parsers)
parsed = parser.parse(stream, media_type, self.parser_context)
return parsed.data, parsed
.files
def _laod_data_and_file(self)
self.data, self.files = self._parse()
self._full_data = self.data
@proparty
def data(self):
if not hasattr(self, "full_data"):
self._laod_data_and_files()
return self._full_data
class APIVIew(View):
parser_classes = apisettings.DEFAULT_PARSERS_CLASSES
def get_parsers(self):
return [parser() for parsr in self.parser_classes]
def initialize_request(self,request):
return Request(request,
parser = self.get_parsers())
def dispatch(self, request):
request = self.initialize_request(request, *args, **kwargs)
self.request = request
return response()
class BookView(APIVIew):
def get(self. request):
pass
def post(self, request):
request.data
return JsonResponse()
day2:
1.解析器组件
2.序列化组件
2.1 django原生的序列化
- 导入
from django.core serialziers import serialize
class BooVIew(APIVIew):
def get(self, request):
books = Book.object.all()
ser_data = serialzie("json", books)
return HttpResponse(ser_data)
2.2 drf序列化组件
- 导入
from rest_framework import serialzers
- 定义序列化类
class BooKSerializer(serializers.Serializer):
title = serializers.Charfield(max_length=32)
price = serializers.DecimalField()
publish = serialziers.CahrField(max_Lenght=32)
publish_name = serializers.CharField(max_lenght=32, source="publish.name", read_only=True)
authors_list = serializers.SerializerMethodField()
def get_authors_lsit(self, instance):
authors = list()
for author in instance.authors():
authors.append(author.name)
return authors
def create(self, verified_data):
pass
def updata(self, verified_data):
pass
- 定义view.py
class BoosView(APIView):
def get(self, request):
books = Book.object.all()
ser_data = BooKserialzier(books, many=True)
reutnr Response(ser_data.data)
2.3 通过drf的序列化组件进行接口设计
2.4 通过drf的序列化组件进行POST接口设计
- 定义view。py
class BoosVIew(APIVIew);
def post(self, request):
data = request.data
ser_data = BooKSerialzier(data=data, many=False)
if ser_data.is_valid():
# BooKSerialzier没有实现写入操作即就是create方法
ser_data.save()
reutnr Response(ser_data.data)
else:
reutnr Response(ser_data.errors)
def put(self, request, id):
data = request.data
book_obj = Book.objects.get(pk=id)
ser_data = BooKSerialzier(instance=book_obj,data=data, many=False)
if ser_data.is_valid():
ser_data.save()
reutnr Response(ser_data.data)
else:
reutnr Response(ser_data.errors)
day3:
1.通过drf的序列化组件进行put接口设计
def put(self, request, id):
data = request.data
book_obj = Book.objects.get(pk=id)
ser_data = BooKSerialzier(instance=book_obj,data=data, many=False)
if ser_data.is_valid():
ser_data.save()
reutnr Response(ser_data.data)
else:
reutnr Response(ser_data.errors)
2.通过drf的序列化组件进行delete接口设计
3.通过drf的序列化组件进行get接口设计
4.试图组件
- 视图组件是用来优化接口逻辑的
4.1 mixins
- 导入
from rest_framework.mixins import (ListModelMixin,
CreateModelMixin,
UpdateModelMixin,
RetrieveModelMixin,
DestoryModelMixin)
from rest_framework.generics import GenericAPIView
- 定义序列化类
- urls.py
re_path('^book/$', views.BookView.as_view()),
re_path('^book/(?P<pk>\d+)/$', views.BookFilterView.as_view()),
- 定义view.py
class BookView(ListModelMixin, CreateModleMixin, GenericAPIVIiew):
queryset = Book.objects.all()
serialzier_class = BookSerializer
def get(self, request):
pass
def psot(self, request):
pass
class BookView(UpdateModelMixin,
RetrieveModelMixin,
DestoryModelMixin,
GenericAPiVIew):
queryset = Book.objects.all()
serialzier_class = BookSerializer
def get(self, request, pk):
return self.retrieve(request)
def put(self, request, pk):
return self.update(request)
def delete(self, request, pk):
return self.destory(request)
4.2 genericview
- 导入
from rest_framework import generics
class BookView(generics.ListCreateAPIView):
queryset = Book.objects.all()
serialzier_class = BookSerializer
class BookView(generics.RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serialzier_class = BookSerializer
4.3 viewset
- 导入
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = Book.objects.all()
serialzier_class = BookSerializer
- url.py
urlpatterns = [
re_path('^book/$', views.BookView.as_view(actions={
"get": "list",
"post": "create"
})),
re_path('^book/(?P<pk>\d+)/$', views.BookView.as_view({
"get": "retrieve",
"put": "update",
"delete": "destroy"
})),
]