Django复习

1、HTTP协议

HTTP协议
    -请求协议(wsgi协议负责拆)
        -请求首行:get/http/1.1
        -请求头部:key:value的形式,有编码方式contenttype,referer,useragent
        -请求体:urlencode编码方式,是可以直接被django解析的,name=lww&name=18,django会拆到大写的POST中
                formdata编码方式:上传文件的,--sfsjf--格式,数据django会拆到POST中,文件会拆到request.FILES中
            json:原生的django处理不了,body体中取出自行处理,drf中可以request.data中可以取出
             PS:前台传过来json格式,每次都要自己取,这样很麻烦,我封装了一个方法paserRequest,将body体中的数据出来放到request.data中再返回request,之后每次需要解析json格式调一下就可以了,后来又给修改成了装饰器,装饰器里面还可以加认证,频率等功能
-响应协议
    -响应首行:HTTP/1.1 200 ok/r/n
    -响应头部:key:value的形式
    -响应体:响应体的内容才是我们看到的html页面的东西,页面渲染出来的东西
  -特性:
    -在tcp/ip协议之上
    -无状态,所以才引出了cookie,cookie不安全,发展到session,session对服务器有压力,又有了token
    -无连接,连一次后直接断开,socket是一直连着
    -请求、响应,发一个请求给一个响应,响应后就断开


服务器主动推送消息:
  1、轮询:用ajax间隔几秒就向服务器发送请求
  2、长轮询:发过请求后在那挂10秒,10秒后断开再发一次请求,10秒内有消息的话就接收并显示出来(主流网站都是用长轮询)
  3、websocket:有的浏览器不兼容

 

djang请求生命周期
1:浏览器发起请求
2:WSGI创建socket服务端,接收请求(Httprequest)
3:中间件处理请求
4:url路由,根据当前请求的URL找到视图函数
5:view视图,进行业务处理(ORM处理数据,从数据库取到数据返回给view视图;view视图将数据渲染到template模板;将数据返回)
6:中间件处理响应
7:WSGI返回响应(HttpResponse)
8:浏览器渲染

 

 

2、django路由层

1 基本路由 url('正则表达式', 函数地址, {默认值}, name=‘test')
2 有名分组/无名分组:url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
3 路由的分发:include,url('app01/', include(urls)),app01/后不要加终止符$
4 反向解析:解决路由可能改变的情况,通过url里name动态解析出路由地址,视图层url=reverse('test'),模板层{% url 'test' %}
5、名称空间:url(r'app01/',include('app01.urls',namespace='app01'),name='index'),视图层url=reverse('app01:index'),模板层{% url 'app01:test' %}
  遇到的问题:一开始不知道有名称空间,项目中用方向解析的时候,总是重定向不对,因为是多人协同开发的,后来发现是和同事命名一样了,后来上网查找有名称空间这个东西
6、django2.0的re_path和1.0的url一样,一开始用的1.几的版本,后来用的2.几

 3、视图层

-fbv
    request-post提交数据,在浏览器窗口里也可以携带数据,从GET中取
    response:render,HttpResponse,redirect,JsonResponse:JsonResponse(dic,json_dumps_params={'ensure_ascii':True})解决乱码问题
 -cbv

4、模型层

db_constraint 取消外键关联 查询不受影响
级联删除,on_delete=models.SET_CASCASE,models.SET_NULL,级联删除可以设置默认值,也可以设置为空

多表查询:
         --title__contains="python"--转成的sql  like %python%
         --基于对象的跨表查询
            -一对一:
                正向查:按字段
                反向:按表名小写
            -一对多
                正向查:按字段
                反向:按表名小写_set 
            -多对多
                正向查:按字段
                反向:按表名小写_set 
              表名小写_set  可以重命名:related_name='xxx'
         --基于双下划线查询
            正向  ----》关联字段在那个表,从哪个表往外查
            反向  ----》关联字段不在我这个表,从我这个表往外查
            手机号以151开头的作者出版过的所有书籍名称以及出版社名称
            Authordetail.objects.filter(phone__startswith='151').values('author__book__name','author__book__publish__name')
            Authordetail.objects.filter(phone__startswith='151').values('author__yyy__name','author__book__publish__name')
            反向查询—— related_query_name='yyy'
            聚合:aggregate,Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
            分组:annotate
                values在前表示:group by
                values在后:要取出来的东西
                filter在前:where条件
                filter在后:having
            统计每一本以py开头的书籍的作者个数
            Book.objects.all().filter(name__startswith='py').annotate(num_authors=Count('authors')).values('num_authors')
  -F查询:比较和运算
  -Q查询:与或非

 5 组件

分页器:paginator
forms组件:form表单提交的数据,ajax提交的json数据都可以校验,只要是字典就可以
    -渲染页面
    -渲染数据信息
    -数据校验

cookie与session组件:
    -session默认存数据库中,可以配置存到Redis中,可以缓存session(默认内存缓存,可以通过配置存到Redis或memcache)

中间件组件:对请求和相应进行拦截
  -请求process_request
  -响应process_response

Auth模块
  -使用:用anth模块,创建表的时候要继承auth的那个表AbstractUser,可以写一些新的字段,settings中需要配置AUTH_USER_MODEL ='app01.UserInfo'
  -认证
  -用户登录状态

6 DRF

restful规范:
1、建议使用HTTPS(有证书,数据传输的时候加密了,更安全一些)
2、域名使用api的方式
3、版本拼在后面或放请求体中
4、路径以名词表示
5、method,GET--获取数据,POST--创建资源,PUT--修改资源,PATCH--修改资源,DELETE-删除资源(其中PUT和PATCH是幂等的)
6、过滤,可以在url上传参的形式传递搜索条件
7、状态码,在技术文档上
8、错误处理,应返回错误信息,error当做key。
9、返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
    GET /collection:返回资源对象的列表(数组)
    GET /collection/resource:返回单个资源对象
    POST /collection:返回新生成的资源对象
    PUT /collection/resource:返回完整的资源对象
    PATCH /collection/resource:返回完整的资源对象
    DELETE /collection/resource:返回一个空文档
10、返回结果中提供链接

 基于DRF的增删改查接口写法示例

路由

url(r'Publish/', views.Publish.as_view({'get': 'get_all', 'post': 'new_publish'}))
url(r'Publish/(\d+)', views.Publish.as_view({'get': 'get_one'}))

视图

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSetMixin
from app01 import models
from rest_framework import serializers

class PublishSer(serializers.ModelSerializer):
  #序列化
class Meta: model = models.Publish fields = '__all__' class MyResponse(): def __init__(self): self.status = 100 self.msg = None @property def get_dic(self): return self.__dict__ class Publish(ViewSetMixin, APIView): def get_all(self, request): response = MyResponse() publish_list = models.Publish.objects.all() ser = PublishSer(publish_list, many=True) response.msg = '查询成功' response.data = ser.data return Response(response.get_dic) def new_publish(self, request): response = MyResponse() ser = PublishSer(data=request.data) ser.save() response.msg = '添加成功' response.data = ser.data return Response(response.get_dic)

 

posted @ 2019-03-03 11:57  liweiwei0307  阅读(121)  评论(0编辑  收藏  举报