一、django请求生命周期:
二、django orm中表与表之间建关系
例:书籍、出版社、作者表
一对多 ForeignKey(to='publish')
一对一 OneToOneField(to='AuthorDetail')
多对多 ManyToManyField(to='Author')
注意:
前面两个关键字会自动再字段后面加_id
最后一个关键字 并不会产生实际字段 只是告诉django orm自动创建第三张表
三、路由层
1、url( )方法 第一个参数,其实是一个正则表达式
django在路由匹配的时候,先拿没有敲斜杠的结果匹配,如果都匹配不上,浏览器会在末尾自动加上斜杠再发一次请求;
取消该机制:在settings配置文件,知道APPEND_SLASH = False # 该参数默认为Ture
2、分组(两者不能混合使用,但同一种分组下,可以使用多个)
2.1无名分组
url(r'^test/([0-9]{4})/', views.test) 路由匹配的时候 会将括号内正则表达式匹配到的内容 当做位置参数传递给视图函数 test(request,2019)
2.2有名分组
url(r'^test/(?P<year>\d+)/', views.test) 路由匹配的时候 会将括号内正则表达式匹配到的内容 当做关键字参数传递给视图函数 test(request,year=2019)
3、反向解析:本质即给你返回一个能够返回对应url的地址
3.1
先给url和视图函数对应关系起别名
url(r'^index/$',views.index,name='kkk')
反向解析
后端反向解析 后端可以在任意位置通过reverse反向解析出对应的url from django.shortcuts import render,HttpResponse,redirect,reverse reverse('kkk') 前端反向解析 {% url 'kkk' %}
3.2 无名分组反向解析
url(r'^index/(\d+)/$',views.index,name='kkk') 后端反向解析 reverse('kkk',args=(1,)) # 后面的数字通常都是数据的id值 前端反向解析 {% url 'kkk' 1%} # 后面的数字通常都是数据的id值
3.3 有名分组反向解析
同无名分组反向解析意义的用法 url(r'^index/(?P<year>\d+)/$',views.index,name='kkk') 后端方向解析 print(reverse('kkk',args=(1,))) # 推荐你使用上面这种 减少你的脑容量消耗 print(reverse('kkk',kwargs={'year':1})) 前端反向解析 <a href="{% url 'kkk' 1 %}">1</a> # 推荐你使用上面这种 减少你的脑容量消耗 <a href="{% url 'kkk' year=1 %}">1</a> 注意:在同一个应用下 别名千万不能重复!!!
4、路由分发
当django项目特别庞大的时候,路由与视图函数对应关系比较多,可以在应用下建views文件。
因为每一个应用都可以有自己的urls。py,static文件夹,templates文件夹。
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^app01/',include('app01.urls')), url(r'^app02/',include('app02.urls')), ]
名称空间(了解)
多个app起了相同的别名 这个时候用反向解析 并不会自动识别应用前缀 如果想避免这种问题的发生 方式1: 总路由 url(r'^app01/',include('app01.urls',namespace='app01')) url(r'^app02/',include('app02.urls',namespace='app02')) 后端解析的时候 reverse('app01:index') reverse('app02:index') 前端解析的时候 {% url 'app01:index' %} {% url 'app02:index' %} 方式2: 起别名的时候不要冲突即可 一般情况下在起别名的时候通常建议以应用名作为前缀 name = 'app01_index' name = 'app02_index'
5、伪静态:搜索优化seo,url尾部加上.html
6、虚拟环境:不同的项目配置不同的python解释器
django1.0与django2.0之间的区别:
django2.0里面的path第一个参数不支持正则,你写什么就匹配,100%精准匹配 django2.0里面的re_path对应着django1.0里面的url 虽然django2.0里面的path不支持正则表达式,但是它提供五个默认的转换器 str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式 int,匹配正整数,包含0。 slug,匹配字母、数字以及横杠、下划线组成的字符串。 uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
7、自定义转换器
1.正则表达式
2.类
3.注册
# 自定义转换器 class FourDigitYearConverter: regex = '[0-9]{4}' def to_python(self, value): return int(value) def to_url(self, value): return '%04d' % value # 占四位,不够用0填满,超了则就按超了的位数来! register_converter(FourDigitYearConverter, 'yyyy') PS:路由匹配到的数据默认都是字符串形式
四、视图层
前后端分离
JsonResponse
from django.http import JsonResponse def index(request): data = {'name':'好喜欢','password':123} l = [1,2,3,4,5,6,7,8] # res = json.dumps(data,ensure_ascii=False) # return HttpResponse(res) # return JsonResponse(data,json_dumps_params={'ensure_ascii':False}) return JsonResponse(l,safe=False) # 如果返回的不是字典 只需要修改safe参数为false即可
上传文件
简单的文件上传 前端需要注意的点: 1.method需要指定成post 2.enctype需要改为formdata格式 后端暂时需要注意的是 1.配置文件中注释掉csrfmiddleware中间件 2.通过request.FILES获取用户上传的post文件数据 file_obj = request.FILES.get('my_file') print(file_obj.name) with open(file_obj.name,'wb') as f: for line in file_obj.chunks(): f.write(line)
request.method
request.GET
request.POST
request.FILES
request.path # 只回去url后缀 不获取?后面的参数
request.get_full_path() # 后缀和参数全部获取
FBE与CBV
视图函数并不只是指函数 也可以是类
FBV(基于函数的视图) 面向函数式编程
CBV(基于类的视图) 面向对象式编程
# 问题:基于CBV的视图函数
"""get请求来就会走类里面get方法,post请求来就会走类里面post方法 为什么???"""
urls.py中 url(r'^login/',views.MyLogin.as_view()) views.py中 from django.views import View class MyLogin(View): def get(self,request): print("from MyLogin get方法") return render(request,'login.html') def post(self,request): return HttpResponse("from MyLogin post方法")