路由层:
一.路由匹配规则:
由于python是解释性语言,从上至下依次加载执行语句,由于是正则匹配规则,第一个参数是正则表达式,会出现模糊匹配的情况,解决方式是在前后加^和在最后加$。
urlpattrens=[
urls(r'testadd/',views.testadd)]
网站首页路由: r'^$',views.homepage 返回匹配错误路由: r'',views.error
urlpattrens=[
url(r'^testeadd/$',views.testadd)]
二.无名分组和有名分组传参
在Python 正则表达式中,命名正则表达式组的语法是(?P
name
是组的名称,pattern
是要匹配的模式。
无名分组:(将括号的正则表达式匹配到的内容当成形参自动传到对应的路由,再传给视图函数),可以多个使用
有名分组:(将括号的正则表达式匹配到的内容当成关键字参数自动传到对应的路由,再传给视图函数),可以多个使用
有名分组和无名分组不能一起混合使用!
三.反向解析:
在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
用反向解析进行动态获取对应的路由:反向解析对路由取得name,不同路由不同取相同的别名。
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
- 在模板中:使用url 模板标签。
- 在Python 代码中:使用
from django.urls import reverse()函数
urls.py
from django.urls import path,re_path
from app01 import views
urlpatterns = [
re_path(r'^test/(?P<year>[0-9]{2})/(?P<month>[0-9]{2})/$',views.url_test,name='test'),
]
html
<a href="{% url 'test' 10 23 %}">哈哈</a>
视图函数中:
from django.shortcuts import render, HttpResponse,redirect,reverse
def url_test(request,year,month):
print(year)
print(month)
url=reverse('test',args=(10,20))
print(url)
return HttpResponse('ok')
总结:1 在html代码里{% url "别名" 参数 参数%}
2 在视图函数中:
2.1 url=reverse('test')
2.2 url=reverse('test',args=(10,20))
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。如果你的URL 模式叫做comment
,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用myapp-comment
而不是comment
。
四.路由分发:
1 在不同的app里创建urls.py
2 在总路由
-from django.conf.urls import include
-url(r'^blog/',include('blog.urls')),
-url(r'^app01/',include('app01.urls')),
3 在不同的app的urls里配置路由关系
重点总路由,不能加结束符$
五.名称空间:
-子路由:url(r'^publish/$', views.publish,name='test'),
-反向解析:
-视图层:url = reverse('blog:test')
模板层:{% url 'app01:test'%}
一般不要用
子路由:url(r'^publish/$', views.publish,name='app01_test'),
六.伪静态:
-路由:url(r'^book/(?P
-访问:
http://127.0.0.1:8000/book/4.html
七.虚拟环境:
创建的时候选择虚拟环境创建项目
-1 pycharm里创建:
-2 用命令串讲:
django1.0与django2.0的区别:
2.0里面的path第一个参数不支持正则,精确匹配
re_path 与1.0中的urls是一样的,要导入repath模块
Django默认支持以下5个转化器:
str,匹配除了路径分隔符(
/
)之外的非空字符串,这是默认的形式int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
注册自定义转化器
对于一些复杂或者复用的需要,可以定义自己的转化器。转化器是一个类或接口,它的要求有三点:
1.‘regex` 类属性,字符串类型
2.to_python(self, value)
方法,value是由类属性
regex` 所匹配到的字符串,返回具体的Python变量值,以供3.Django传递到对应的视图函数中。to_url(self, value)
方法,和to_python
相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
class FourDigitYearConverter:
regex = '[0-9]{4}'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%04d' % value
八.FBV和CBV
CBV基于类的视图(Class base view)和FBV基于函数的视图(Function base view)
from django.views import View
class AddPublish(View):
def dispatch(self, request, *args, **kwargs):
print(request)
print(args)
print(kwargs)
# 可以写类似装饰器的东西,在前后加代码
obj=super().dispatch(request, *args, **kwargs)
return obj
def get(self,request):
return render(request,'index.html')
def post(self,request):
request
return HttpResponse('post')
无论是FBV还是CBV在路由层都是一个路由和一个视图函数一一对应。
九.文件上传
1 html页面上指定编码格式:enctype="multipart/form-data"
2 视图层:request.FILES(字典),可以根据名字,把文件取出来
-myfile=request.FILES.get('文件名字')--->得到文件对象
3 for循环文件对象,保存到本地,文件名字:myfile.name
print(request.FILES)
print(type(request.FILES.get('file_name')))
file_name=request.FILES.get('file_name').name
from django.core.files.uploadedfile import InMemoryUploadedFile
with open(file_name,'wb')as f:
for i in request.FILES.get('file_name').chunks():
f.write(i)
十.补充知识点
1 Request对象---GET,POST,method,body,FILES,META,path(只是路径),get_full_path(拿到全路径,带数据),
2 HttpResponse对象--->render,redirect,HttpResponse,JsonResponse(返回json格式)
3 反向解析--->在视图层:本质为了去除地址,重定向来用;在模板层:取出地址,为了发请求来用
4 JsonResponse:JsonResponse(dic,json_dumps_params={'ensure_ascii':False})---中文显示编码问题