-
数据库同步命令
inspectdb
-
django请求生命周期流程图
1.web服务网关接口
wsgiref
uwsgi
2.灰色地带(django中间件)
3.路由层
4.视图层
5.模板层
6.模型层 -
路由匹配
1.自动补全斜杆
APPEND_SLASH = True
2.url()方法
第一个参数是正则表达式
# 路由匹配特性:一旦正则能够匹配到内容则停止继续往下而是直接执行对应的功能 -
无名有名分组
无名分组
给正则表达式加上一个括号
url(r'^index/(d+)/',views.index)
执行视图函数的时候会将括号内匹配到的内容当做位置参数传递给视图函数
有名分组
给正则表达式加上一个括号并且起一个别名
url(r'^index/(?P<id>d+)/',views.index)
执行视图函数的时候会将括号内匹配的内容当做关键字参数传递给视图函数
ps:两者不能混合使用,但是单独可以重复使用 -
反向解析
"""通过别名得到一个可以访问该别名对应的路由规则"""
1.起别名(不能冲突)
url(r'^index/',views.index,name='index_name')
2.反向解析
前端
{% url 'index_name' %}
后端
from django.shortcuts import reverse
url = reverse('index_name') -
无名有名反向解析
"""当路由出现无名有名分组反向解析需要传递额外的参数"""
url(r'^index/(d+)/',views.index,name='index_name')
前端
{% url 'index_name' 1 %}
后端
from django.shortcuts import reverse
url = reverse('index_name',args=(1,))
ps:有名分组的反向解析也可以使用无名的方式
# 了解
url(r'^index/(?P<id>d+)/',views.index,name='index_name')
前端
{% url 'index_name' id=1 %}
后端
from django.shortcuts import reverse
url = reverse('index_name',kwargs={'id':1})
-
路由分发
-
名称空间
-
伪静态(了解)
-
本地虚拟环境
-
django版本区别
-
视图层
三板斧
JsonResponse
上传文件
FBV与CBV(重点)
CBV源码剖析(重点)
路由分发
"""
简介
django是专注于开发应用的,当一个django项目特别庞大的时候
所有的路由与视图函数映射关系全部写在总的urls.py很明显太冗余不便于管理
其实django中的每一个应用都可以有自己的urls.py,static文件夹,templates文件夹,基于上述特点,使用django做分组开发非常的简便
每个人只需要写自己的应用即可
最后由组长统一汇总到一个空的django项目中然后使用路由分发将多个应用关联到一起
"""
复杂版本
from app01 import urls as app01_urls
from app02 import urls as app02_urls
# 路由分发 复杂版本
url(r'^app01/',include(app01_urls))
url(r'^app02/',include(app02_urls))
'''总路由最后千万不能加$'''
# 进阶版本
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
名称空间
"""
当多个应用在反向解析的时候如果出现了别名冲突的情况,那么无法自动识别
"""
解决方式1>>>:名称空间
总路由
url(r'^app01/',include('app01.urls',namespace='app01'))
url(r'^app02/',include('app02.urls',namespace='app02'))
reverse('app01:index_name')
reverse('app02:index_name')
<a href="{% url 'app01:index_name' %}">app01</a>
<a href="{% url 'app02:index_name' %}">app02</a>
解决方式2>>>:别名不能冲突(加上自己应用名作为前缀)
url(r'^index/',views.index,name='app01_index_name')
url(r'^index/',views.index,name='app02_index_name')
伪静态
动静态网页
将url地址模拟成html结尾的样子,看上去像是一个静态文件
目的是为了增加搜索引擎收藏我们网站的概率以及seo查询几率
ps:再怎么优化都不如RMB玩家!!!
本地虚拟环境
"""
在时间开发过程中,我们会给不同的项目配备不同的环境
项目用到什么就装什么,用不到的一概不装
不同的项目解释器环境都不一样
"""
requirements.txt
创建虚拟环境类似于你重新下载了一个纯净的python解释器
如果反复创建类似于反复下载,会消耗一定的硬盘空间
ps:我们目前不推荐你使用虚拟环境,所有的模块统一全部下载到本地
django版本区别
django1.X与2.X、3.X
1.区别
urls.py中的路由匹配方法
1.X第一个参数正则表达式
url()
2.X和3.X第一个参数不支持正则表达式,写什么就匹配什么
path()
如果想要使用正则,那么2.X与3.X也有响应的方法
from django.urls import path,re_path
re_path 等价于 1.X里面的url方法
2.转换器
五种常用转换器
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
自定义
class MonthConverter:
regex='d{2}' # 属性名必须为regex
def to_python(self, value):
return int(value)
def to_url(self, value):
return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
from django.urls import path,register_converter
from app01.path_converts import MonthConverter
register_converter(MonthConverter,'mon')
from app01 import views
urlpatterns = [
path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),
]
三板斧本质
django视图函数必须要返回一个HttpResponse对象
class HttpResponse(HttpResponseBase):
"""
An HTTP response class with a string as content.
This content that can be read, appended to or replaced.
"""
streaming = False
def __init__(self, content=b'', *args, **kwargs):
super(HttpResponse, self).__init__(*args, **kwargs)
# Content is a bytestring. See the `content` property methods.
self.content = content
def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
redirect内部是继承了HttpRespone类
JsonResponse
需求:给前端返回json格式数据
方式1:自己序列化
res = json.dumps(d,ensure_ascii=False)
return HttpResponse(res)
方式2:JsonResponse
from django.http import JsonResponse
def func2(request):
d = {'user':'jason好帅','password':123}
return JsonResponse(d)
ps:额外参数补充
json_dumps_params={'ensure_ascii':False} # 看源码
safe=False # 看报错信息
# JsonResponse返回的也是HttpResponse对象
上传文件
form表单上传文件注意事项
1.method必须是post
2.enctype参数修改为multipart/form-data
def func3(request):
if request.method == 'POST':
print(request.POST)
file_obj = request.FILES.get('myfile')
print(file_obj.name) # 获取文件名称
with open(r'%s'%file_obj.name,'wb') as f:
for chunks in file_obj.chunks():
f.write(chunks)
return render(request,'func3.html')
FBV与CBV
FBV
基于函数的视图
CBV
基于类的视图
# 基本使用
from django.views import View
class MyView(View):
def get(self,request):
return HttpResponse("get方法")
def post(self,request):
return HttpResponse("post方法")
url(r'^func4',views.MyView.as_view())
"""为什么能够自动根据请求方法的不同执行不同的方法"""
1.突破口
as_view()
2.CBV与FBV路由匹配本质
url(r'^func4',views.MyView.as_view())
# 等价 CBV路由配置本质跟FBV一样
# url(r'^func4',views.view)
3.源码
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs) # self = MyView() 生成一个我们自己写的类的对象
return self.dispatch(request, *args, **kwargs)
return view
def dispatch(self, request, *args, **kwargs):
# 获取当前请求并判断是否属于正常的请求(8个)
if request.method.lower() in self.http_method_names:
# get请求 getattr(对象,'get') handler = 我们自己写的get方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 执行我们写的get方法并返回该方法的返回值