Django路由与视图
路由层
一.路由匹配规则:
第一个参数是正则表达式,匹配规则按照从上往下一次匹配,匹配到一个之后立即匹配,直接执行对应的视图函数
url(r'login', views.login),如果按上面的形式匹配的话就成模糊匹配了,login的前面没有限制条件,可以输入任意的字符串,login的后面也没有限制条件也是可以输入任意的字符串,这样的话导致只要我路径里面有login这样的关键字无论我输入什么都没有关系,都可以访问的到,怎么解决方式是在前面加^h和后面加$符号,这样的话就限制了,只要能是路径对了才能访问到,如下。
url(r'^login/$', views.login), #然后去写对应的视图函数就可以了网站首页路由配置:
url(r'^$', views.login), #然后去写对应的视图函数就可以了网页错误路由设置:
url(r'',views.error) #然后去写对应的视图函数就可以了二.有名分组和无名分组传参
无名分组(将加括号的正则表达式匹配到的内容当做位置参数自动传递给对应的视图函数)
路由层
url(r'^login/([0-9]{4})$', views.login), # ([0-9]{4})匹配4个数字然后进行分组视图函数层
def login(request,year): # 如果分了一个组的话一定要的对应的视图函数加上一个函数,如果有两个就加上两个参数print(year) # http://127.0.0.1:8000/login/2019 打印结果就是2019return render(request,'login.html')多个无名分组
路由层
url(r'^login/([0-9]{4})([0-9]{2})$', views.login), # ([0-9]{4})匹配4个数字然后进行分组 ([0-9]{2}) 匹配2个数字然后进行分组视图函数层:
def login(request,*args): # 如果分了一个组的话一定要的对应的视图函数加上一个函数,如果有两个就加上两个参数print(agrs) # http://127.0.0.1:8000/login/2019/06 打印结果就是(2019,06)return render(request,'login.html')有名分组:
有名分组(将加括号的正则表达式匹配到的内容当做关键字参数自动传递给对应的视图函数)
注意:无名分组和有名分组不能混着用!!!
路由层:
url(r'^index/(?P<year>\d+)/',views.index)视图函数层方式一:
def index(request,year):print(year)return HttpResponse('test')视图函数层方式二
def index(request,**kwargs):print(kwargs)return HttpResponse('test')反向解析
根据名字动态获取对应的路径
前端模板方式
语法 {% url '路由的别名' %}
路由层:
url(r'^index111/', views.index,name='xxx'),# 可以给每一个路由与视图函数对应关系起一个名字# 这个名字能够唯一标识出对应的路径# 注意这个名字不能重复是唯一的前端模
<p><a href="{% url 'xxx' %}">1111111111111</a></p>s后端方式
语法 reverse('路由的别名')
url(r'^index111/', views.index,name='xxx'),视图函数层
def index(request):if request.method == 'POST':url = reverse('xxx')return redirect(url)return render(request,'index.html')无名分组反向解析
后端
路由
url(r'^index/([0-9]{4})/', views.index,name='xxx'),视图函数
def index(request,*age):rl = reverse('xxx', args=(2019,))print(rl)return render(request,'index.html')前端
路由
url(r'^index/([0-9]{4})/', views.index,name='xxx'),前端html页面
<p> <a href='{ % url 'xxx' 2019 % }'><a> <p>有名分组反向解析
后端使用# 后端有名分组和无名分组都可以用这种形式print(reverse('list',args=(10,)))# 下面这个了解即可print(reverse('list',kwargs={'year':10}))前端使用# 前端有名分组和无名分组都可以用这种形式{% url 'list' 10 %}# 下面这个了解即可{% url 'list' year=10 %}总结:针对有名分组与无名分组的反向解析统一采用一种格式即可
后端
reverse('list',args=(10,)) # 这里的数字通常都是数据的主键值
前端
{% url 'list' 10 %}
反向解析的本质:就是获取到一个能够访问名字所对应的视图函数
路由分发
路由分发django每一个app下面都可以有自己的urls.py路由层,templates文件夹,static文件夹项目名下urls.py(总路由)不再做路由与视图函数的匹配关系而是做路由的分发 路由分发的两种方式:方式一:总路由:# 不需要导入任何东西url(r'^app01','app01.urls'),url(r'^app02','app02.urls')app01路由:在你创建app01的时候是app01下面是没有urls路由的需要自己手动创建,然后把项目文件夹下的总路由copy到app01的路由下urlpatterns = [url(r'^index/', views.index),]方式二:总路由:# 只需要导入include和app01与app02的urls并取别名并且去别名from django.conf.urls import url,includefrom app01 import urls as a1from app02 import urls as a2url(r'^app01',include(a1)),url(r'^app02',include(a2)),app01路由:在你创建app01的时候是app01下面是没有urls路由的需要自己手动创建,然后把项目文件夹下的总路由copy到app01的路由下urlpatterns = [url(r'^index/', views.index),]名称空间
名称空间(了解) # 名称空间是避免多个app之间视图函数名重复url(r'^app01/',include(app01_urls,namespace='app01')),url(r'^app02/',include(app02_urls,namespace='app02')) app01.urls.pyfrom django.conf.urls import urlfrom app01 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]app02.urls.pyfrom django.conf.urls import urlfrom app02 import viewsurlpatterns = [url(r'^index/',views.index,name='index')]app01.views.py reverse('app01:index')app02.views.py reverse('app02:index')伪静态网页:
伪静态网页搜索优化seourl(r'^index.html',views.index,name='app01_index')虚拟环境
虚拟环境不同的项目配置不同的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,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)自定义转换器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:路由匹配到的数据默认都是字符串形式FBV与CBV
FBV与CBV FBV:基于函数的视图 CBV:基于类的视图CBV:url(r'^mycls/',views.MyCls.as_view())class MyCls(View):def get(self,request):return render(request,'index.html')def post(self,request):return HttpResponse('post')无论是FBV还是CBV路由层都是路由对应视图函数内存地址 urlpatterns = [# url(r'^mycls/',views.view)url(r'^mycls/',views.MyCls.as_view()) ]class MyCls(View):def get(self,request):return render(request,'index.html')def post(self,request):return HttpResponse('post') 简单的文件上传 前端需要注意的点:1.method需要指定成post2.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)转载于:https://www.cnblogs.com/ZKPython/p/11000372.html
总结
以上是生活随笔为你收集整理的Django路由与视图的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: React入门看这篇就够了
- 下一篇: 数据转数字类型的方法总结