day17–BBS项目:
1.模型层
1 | from django.db import models |
2.前端页面字符串的替换
1 | ss=` |
3.拿到html标签里面的值
1 | 1.通过页面选择器获取里面的值 |
4.前端字符串转成int类型的方式
1 | var count= $("#digg_count").text() |
5.前端页面聚焦光标
1 | //让光标聚焦到这个控件 |
6.前端输入框内容的截断
1 | //取到 \n 索引位置的后一位 |
7.将时间对象转成字符串
1 | 1.通过json传输的时候,json不会给我们转时间对象的,而且还会报错,这就需要我们自己来转 |
8.随机产生验证码
1 | img = Image.new('RGB', (320, 35), color=get_random_color()) |
1 | 1.定义一个公共方法 |
9.多视图共用一个路由视图设计(好好理解)
1 | 1.路由 |
10.过滤html文本及标签
1 | 1.安装BeautifulSoup4 |
11.富文本编辑器使用(http://kindeditor.net/doc.php)
1 | 1.hmtl部分 |
1 | 2.视图部分 |
1 | 3.上传图片 |
12.head
1 | headers: { |
day18—Rest Framework
一.RESTful规范(共十条)
1.什么是restful规范
1 | 1.rest与技术无关,代表的是一种软件架构风格,rest是representational state transfer,中文翻译为‘表征状态转移’ |
1 | 总结: |
2.restful api设计(规范)
1 | 1.api与用户的通信协议,总是使用HTTPs协议。 |
1 | 2.域名 |
1 | 3.版本 |
1 | 4.路径:视网络上的任何东西为资源,均使用名词表示(可复数) |
1 | 5.method |
1 | 6.过滤:通国url传参的方式,传递搜索条件 |
1 | 7.状态码 |
1 | 8.错误处理 |
1 | 9.返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。 |
1 | 10.Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。 |
1 | 实例: |
*** 针对book这张表的符合resf规范的视图和路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 > 视图:
> from app01.models import Book
> from rest_framework.views import APIView
> from rest_framework.request import Request
> from django.http import JsonResponse
> from app01.MySer import BookSerializer
> from rest_framework.utils.serializer_helpers import ReturnDict
>
> class BookView(APIView):
> """
> GET /Book:返回资源对象的列表(数组)
> GET /Book/1:返回单个资源对象
> POST /Book:返回新生成的资源对象 -新增,传数据,一旦新增完成,把新的资源对象返回
> PUT /Book/1:返回完整的资源对象
> PATCH /Book/1:返回完整的资源对象
> DELETE /Book/1:返回一个空文档
>
> """
>
> def get(self, request, **kwargs):
> response = {'status': 100, 'msg': None}
> if kwargs:
> '''有值查一条'''
> book = Book.objects.filter(pk=kwargs['id']).first()
> ser = BookSerializer(book, many=False)
> data = ser.data
> print(data, type(data))
> # <class 'rest_framework.utils.serializer_helpers.ReturnDict'>-----data类型
> # response['msg'] = {'name': book.name, 'price': book.price}
> response['msg'] = data
> return JsonResponse(response, safe=False)
> else:
> '''无值查全部'''
> books = Book.objects.all()
> lis = [{'name': book.name, 'price': book.price} for book in books]
> response['msg'] = lis
> return JsonResponse(response, safe=False)
>
> def post(self, request, **kwargs):
> response = {'status': 100, 'msg': None}
> print(request.method)
> print(request.POST)
> print(request.GET)
> print(request.FILES)
> print(request.META)
> print(request.data)
> nn = request.data
> """
> POST
> <QueryDict: {'name': ['小李飞刀'], 'price': ['88']}>
> <QueryDict: {}>
> <MultiValueDict: {}>
> <QueryDict: {'name': ['小李飞刀'], 'price': ['88']}>
> """
> name = request.data.get('name')
> price = request.data.get('price')
> book = Book.objects.create(name=name, price=price)
> response['msg'] = {'name': book.name, 'price': book.price}
> return JsonResponse(response, safe=False)
>
> def put(self, request, **kwargs):
> response = {'status': 100, 'msg': None}
> name = request.data.get('name')
> price = request.data.get('price')
> book = Book.objects.filter(pk=kwargs['id']).update(name=name, price=price)
> print(book)
> response['msg'] = '更新成功'
> response['url'] = '127.0.0.1/Book/%s' % kwargs['id']
> return JsonResponse(response, safe=False)
>
> def patch(self, request, **kwargs):
> response = {'status': 100, 'msg': None}
> name = request.data.get('name')
> price = request.data.get('price')
> book = Book.objects.filter(pk=kwargs['id']).update(name=name, price=price)
> print(book)
> response['msg'] = '更新成功'
> response['url'] = '127.0.0.1/Book/%s' % kwargs['id']
> return JsonResponse(response, safe=False)
>
> def delete(self, request, **kwargs):
> response = {'status': 100, 'msg': None}
> ret = Book.objects.filter(pk=kwargs['id']).delete()
> print(ret) # (1, {'app01.Book': 1})
> response['msg'] = '删除成功'
> return JsonResponse(response)
>
>
二.restframework之APIView
1.安装djangorestframework
1 | 方式一:pip3 install djangorestframework |
2.djangorestframework的APIView分析
1 | 1.djangorestframework只是快速的构建resful规范的接口。 |
1 | 使用: |
1 | 1.执行流程分析 |
1 |
|
1 | 注意: |
1 | 1.APIView中dispatch方法 |
三.django及DRF序列化工具
1 | from django.core import serializers |
1 | 结果: |
1 | 注意: |
1.restframework序列化工具—之序列化
1 | 1.导入序列化工具 |
1.推荐写法
1 | 1.在app下写一个py文件,如myser |
2.实例-继承Serializer
1 | 1.myser文件中 |
实例-继承ModelSerializer
1 | 1..myser文件中 |
2.restframework序列化工具—之反序列化
实例-继承ModelSerializer
1 | 1.myser文件中 |
1 | 注意: |
1 | 1.有时候需要重写create和update方法,需要手动pop掉多余的字段。 |
1 | 1.*****手动创建对象,并传入第三张表中(在ModelSerializer) |
3.序列化组件中可传参数
1 | 1.read_only |
4.常用字段
1 | 1.普通字段 |
5.钩子函数
1 | 1.局部钩子,validata_字段名 |
1 | 2.全局钩子validate |
全局钩子除了验证功能以外,还可以对read_only字段进行赋值操作
1 | eg:订单号的生成,我们可以在这步生成一个订单号,然后添加到attrs这个字典中 |
6.联合唯一
1 | 1.UniqueTogetherValidator |
7.ModelSerializer需要解决的2个问题
问题一:某个字段不属于指定model,它是write_only,需要用户传进来,但我们不能对它进行save( ),因为ModelSerializer是基于Model,这个字段在Model中没有对应,这个时候,我们需要重载validate!
1 | 实例: |
问题二:某个字段不属于指定model,它是read_only,只需要将它序列化传递给用户,但是在这个model中,没有这个字段!我们需要用到SerializerMethodField。
1 | 实例: |
四.DRF认证组件
1.源码分析
1 | APIView---dispatch---initialize_request(包装request)---apiview的get_authenticators---将对象列表返回给authenticators----执行apiview的initial方法---执行apiview的perform_authentication方法-----(request.user)---Request.user方法----执行request对象的_authenticate方法------循环request对象的authenticators----执行循环出的每个对象的authenticate方法,将自己和request这个对象传入----最后返回一个元组(认证通过)或者抛出异常(认证失败)exceptions.APIException----如果认证通过self.user, self.auth = user_auth_tuple执行的结果解压赋 值,给request对象添加二个属性。 |
2.认证组件如何使用
1 | 1.新建一个认证组件的py文件 |
1.局部使用
1 | 1.在视图中导入认证组件 |
2.全局使用
1 | 1.在settings里面配置 |
3.认证组件执行顺序
1 | 认证类使用顺序:先用视图类中的验证类,再用settings里配置的验证类,最后用默认的验证类 |
五.DRF权限组件
1 | 只用超级用户才能访问指定的数据,普通用户不能访问,所以就要有权限组件对其限制 |
1.源码分析
1 | APIView---dispatch----执行initial方法----执行apiview对象的check_permissions方法(循环对象列表)----执行apiview的get_permissions方法(对象列表)---执行对象列表里面的has_permission方法,返回结果为True/False,传入三个参数,第一个参数是对象本身,第二个参数request,第三个参数是view对象。 |
2.权限组件如何使用
1.局部使用
1 | 1.创建一个py文件 |
2.全局使用
1 | 1.在settings里面配置 |
3.权限组件执行顺序
1 | 权限类使用顺序:先用视图类中的权限类,再用settings里配置的权限类,最后用默认的权限类 |
六.importlib使用分析
1.动态导入
1 | import importlib |
七.UUID模块
1.什么是uuid
1 | uuid是128位的全局唯一标识符(univeral unique identifier),通常用32位的一个字符串的形式来表现。有时也称guid(global unique identifier),C#语言中使用。python中自带了uuid模块来进行uuid的生成和管理工作 |
2.uuid有什么用
1 | 1.需要id要唯一,但不需要具体的意义 |
3.python中uuid模块
1 | import uuid |
4.总结
1 | 1 Python中没有基于 DCE 的,所以uuid2可以忽略 |
八.DRF频率控制组件
1.什么是频控组件
1 | 1.为了控制用户对某个url请求的频率,比如,一分钟以内,只能访问三次 |
2.怎么使用组件
1 | 1.自定义频控 |
1 | 2.用rest频控组件 |
1 | 3.输出错误信息中文方式一:修改源码 |
3.全局使用
1 | 1.在Mythro模块中定义这个类,继承SimpleRateThrottle |
1 | 2.在settings里面做配置 |
4.局部使用少用几个
1 | throttle_classes = [MyThrottle,] |
5.局部使用,全局不使用
1 | throttle_classes = [MyThrottle,] |
九.DRF解析器
1.什么是解析器
1 | 根据请求头 content-type 选择对应的解析器对请求体内容进行处理。 |
2.drf内置的解析器
1 | 'DEFAULT_PARSER_CLASSES': ( |
3.全局使用解析器
1 | 在settings里面配置 |
4.局部使用解析器
1 | 在视图函数中,或者视图函数所继承的父类中 |
十.DRF视图组件
1.什么是视图组件
1 | 可以控制多个路由响应的视图 |
2.视图组件的用法一
路由
1 | url(r'^publish/$', views.PublishView.as_view()), |
视图
1 | from rest_framework.mixins import ListModelMixin, \ # 可以返回get多个对象 |
3.视图组件的用法二
路由
1 | url(r'^publish/$', views.PublishView.as_view()), |
视图
1 | from rest_framework.generics import ListCreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView |
3.视图组件的用法三
路由
1 | url(r'^publish', views.PublishView.as_view({'get': 'list', 'post': 'create'})), |
视图
1 | from rest_framework.viewsets import ModelViewSet |
4.注意:以上三种用法都不建议使用
5.魔法类ViewSetMixin
导入
1 | from rest_framework.viewsets import ViewSetMixin |
使用
1 | 1.路由 |
作用
1 | 可以让不同的路由,响应到同一个视图类中的不同的视图方法。 |
源码分析
1 | class ViewSetMixin(object): |
1 | 1.无论以后执行的是什么路由,全部响应到这个ViewSetMixin这个里面的as_view的魔法方法中 |
十一.DRF之响应器
1.什么是响应器
1 | 根据用户请求的url或用户可接受的类型,筛选出合适渲染组建 |
2.内置渲染器
1 | 1.显示json格式:JSONRenderer |
3.局部使用
1 | from rest_framework.renderers import HTMLFormRenderer,BrowsableAPIRenderer |
4.全局使用
1 | 在settings里面配置 |
5.自定义显示模板
1 | from rest_framework.renderers import TemplateHTMLRenderer |
6.注意
1 | 注意:如果同时多个存在时,自动根据URL后缀来选择渲染器。 |
十二.DRF之url控制
1.原始的路由
1 | from django.conf.urls import url |
2.半自动路由(视图类继承ModelViewSet)
1 | from django.conf.urls import url |
3.全自动路由(不推荐使用)
1 | 1.路由 |
1 | 2.视图 |
十三.DRF之分页器
1.简单分页
1 | 1.四个核心参数 |
如何使用
1 | # 普通分页 |
1 | 2.可以在setting里面配置全局的page_size |
2.偏移分页
1 | #默认每页显示几条 |
使用
1 | # 偏移分页 |
3.加密分页(查询速度快,但是只能查上一页和下一页,cursor加密)
1 | #查询的关键字,后谜案是随机生成的字符串 |
十四.反向解析
1.get_all
1 | url(r'^(?P<version>[v1|v2|v3]+)/books/$', views.Book.as_view({'get': 'get_all'}), name='ttt'), |
2.get_one
1 | url(r'^(?P<version>[v1|v2|v3]+)/books/(?P<pk>\d+)', views.Book.as_view({'get': 'get_one'}), name='mmm'), |
十五.DRF之版本控制
1.如何使用
1 | 1.setting里面配置 |
1 | 2.视图 |
1 | 3.url |
1 | 如何访问 |
十六.ContentType组件
1.model层
1 | from django.db import models |
2.视图层
1 | from django.shortcuts import render, HttpResponse |
十七.Django的缓存机制
1.缓存介绍
1 | 1.在动态网站中,用户所有的请求,服务器都会取数据库中进行相应的增,删,改,查,渲染模板,执行业务逻辑,最后生成用户能看到的页面。 |
2.django中的6种缓存的配置
方式一:开发调试(此模式为开发调试使用,实际上不执行任何操作)
1 | CACHES = { |
方式二:内存缓存(将缓存内容保存至内存区域中)
1 | CACHES = { |
方式三:文件缓存(把缓存数据存储在文件中)
1 | CACHES = { |
方式四:数据库缓存(把缓存数据存在数据库中)
1 | CACHES = { |
1 | 1.注意,创建缓存的数据库表使用的语句 |
方式五
1 |
方式六
1 |
3.django中缓存的应用
1.全站使用缓存
1 | 1.settings里面中间键配置 |
2.单个页面使用缓存
1 | 1.视图中 |
3.页面中局部标签使用缓存
1 |
|
4.如果需要把缓存的数据放到文件中,怎么做
1 | CACHES = { |
十八.django解决跨域问题
1.跨域产生的原因
1 | 浏览器同源策略 |
2.简单请求
1 | 发一次请求: |
3.复杂请求
1 | 1.非同源 |
4.解决跨域
1 | from django.utils.deprecation import MiddlewareMixin |
十九.通过命令导出python项目依赖
1 | pip3 freeze > requirement.txt |
1 | asn1crypto==0.24.0 |
day19–路飞项目
一.设置token超时时间
1.如何将datatime类型转换层时间戳
1 | import time |
2.时间戳和datatime相互转换
1 | python datetime 与时间戳相互转换 |
3.实例—实例之数据库版本
1 | 1.settings |
1 | 2.myauth:登录验证 |
1 | 3.mycommon |
4.实例—redis数据库版本
1 | 1.myredis |
1 | 2.myauth |
1 | 3.视图中 |
二.封装response
1 | from rest_framework.response import Response |
三.购物车存redis,redis中数据结构设计
1 | # shopping_1用户的id |