1.http Request Protocol
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()
Today's details:
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 parser component
1.3 serialization component
1.4 authentication component
1.5 Permissions components
1.6 Frequency Components
1.7 url controller components
1.8 paging component
1.9 Response assembly
Today content summary:
Knowledge review summary
What is programming
Algorithms + Data Structure
What is the 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
Dynamic properties of the object to be operated
self positioning
It is always positioned themselves
Http request data protocol
Backend data request to resolve what way
From which three kinds of forms request protocol enctype
urlencoded, multi-formdata, text/plain
JavaScript object serialized to 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. parser source code process:
__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里面找到对应的方法,执行该方法,最后返回给用户
- All functions are in DRF as_view () and dispatch () inside rewritten
- The parser component dispatch method in which rewrite, Request object is repackaged in particular it is
class ParseJson():
pass
class ParseForm():
data = request.body.decode('utf-8')
data.split("&")
return data
def select_parse(request,ParseJson, ParseForm):
return
Knowledge Point Review:
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 positioning
谁调用就是谁。
5.http Request Protocol
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 the request process
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 use
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)# 有参数必须传递参数
* Dynamic on package
import importlib
moudle = input("请输入要导入的模块:")
moudle = importlib.import_module(module)
# 通过字符串方式引入模块
Knowledge Point Review:
1. ternary operator: "alex" if a else "wusir"
2. List comprehensions
3.__getattr__
4.djaong settiong file search order global_settings
5. Dynamic import
6.Django virgin
The serializer
# 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)
Knowledge Point Review:
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. Today's content:
今日内容:
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
Knowledge Point Review:
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源码剖析
to sum up:
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"
})),
]