1.django中urls.py负责url的路由分发
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
# url的第一个参数实际为一个正则表达式,第二个参数为视图函数。浏览器访问时,会遍历该列表,匹配到则终止,不再往下匹配。
当用户访问的url不存在时,django会尝试将用户访问的url后加上“/”,返回给浏览器,浏览器负责重定向。实际上进行了2次http请求。
例如访问https://127.0.0.1:8000/admin时,由于admin和r'^admin/'并不能匹配。django会重定向。
实际上不能这么理解。如果按上述说法,将进行一个死循环,匹配不到就添加"/"重定向,岂不是无穷无尽了? 这点,我们可以通过访问一个不存在的url得到证明。
django在收到url时会自动检测有没有“/”,
如果原本就有,则直接匹配,
- 匹配不到直接返回404。
- 匹配的到则调用视图函数
如果原本没有'/',则拿添加上'/'以后的url进行匹配。
- 如果匹配不到则直接返回404
- 如果匹配得则向浏览器发送重定向的标志。
# 证明例子
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/',views.index),
url(r'^index',views.index1),
]
访问:https://127.0.0.1:8000/index时,按照第一种说法是调用index1,而事实上时调用的index。
2.有名分组和无名分组
分组就是在url匹配关系中给某一段正则表达式加了括号。当匹配成功后,会将括号内的内容作为参数传入视图函数。有名分组是以关键字传参的方式,无名分组是以位置传参的方式。
注意:在一个匹配关系中,有名分组和无名分组不能混合使用!!!!
无名分组
urls.py
---------------------------
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit_user/(d+)/',views.edit_user),
]
views.py
-----------------------------
def edit_user(request,id):
return HttpResponse(id)
有名分组
urls.py
---------------------------
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit_user/(?P<user_id>d+)/',views.edit_user),
]
views.py
----------------------------
# 此处形参名必须与urls有名分组的名字一致
def edit_user(request,user_id):
return HttpResponse(user_id)
补充,在一个正则---视图函数的匹配关系下,
1.有名分组和无名分组不能混合使用。
2.同一种分组方式可以使用多个。
3.反向解析
反向解析的需求由来:当我们在前端或者在后端时,在用户做某些操作时希望页面跳转到我们指定的url,而一旦我们的url名字发生了改变,所有指定跳转到该页面的代码都需要被修改。这时极为不便的,反向解析由此诞生。
反向解析的使用:反向解析实际上给每一组url----视图函数的对应关系增加了一个name的属性,通过这个name属性和前后端一些函数的使用,即可找到这种对应关系。
urls.py
---------------------------
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit_user/',views.edit_user,name='edit'),
]
前端使用反向解析
{% url 'edit' %} ---->即name='edit'所在的url
后端使用反向解析
from django.shortcuts import reverse
reverse('edit') ----->name='edit'所在的url
明白了反向解析的由来和使用后,我们再思考一个问题。如果反向解析的url是一个带有有名分组或者无名分组的url呢?
无名分组的反向解析
urls.py
---------------------------
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit_user/(d+)/',views.edit_user,name='edit'),
]
前端
{% url 'edit' 123 %}
# 只需要在后面直接跟参数即可
后端
reverse('edit',args=(123,))
# args中放入参数
有名分组的反向解析
有名分组的反向解析与无名分组的反向解析基本一致。
urls.py
---------------------------
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^edit_user/(?P<user_id>d+)/',views.edit_user,name='edit'),
]
前端
{% url 'edit' 1 %}
{% url 'edit' user_id=1 %}
# 以上两种都可以使用,第一种使用时注意位置。
后端
reverse('edit',args=(1,))
reverse('edit',kwargs={'user_id':1})
# 以上两种都可以使用,第一种注意位置
4.路由分发
路由分发的需求由来:我们知道一个django项目由一个个app组成。当我们开发的django项目非常庞大时,也会有许多的html文件、也会有许多views视图函数,许多的url对应关系,按照我们之前的想法,所有的对应关系都会在总的urls.py上。
这其中有两个问题
- 多个app之间不能很好的实现分离,不能很好的实现分小组开发。
- 非常多的urls对应关系,会使代码显得比较混乱
我们设想,如果每个app都有自己的路由系统,则各app之间的urls就可以相互分隔开。
为了解决上面出现的问题,路由分发由此而来。路由分发不仅允许每个app拥有自己的urls.py文件,还允许有自己的static和templates文件夹。这使得分小组开发非常便捷,代码的简洁性和可读性也增强!
而我们的总路由-----项目目录下的urls.py则只需要根据http请求的url中app的名字,将其路由分发给相应的app路由系统。
总路由
urls.py
--------------------
from django.conf.urls import url,include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
url(r'^app01/',include('app01_urls)),
url(r'^app02/',include('app02_urls'))
]
以上写法可简写为:
urls.py
from django.conf.urls import url,include
import app01
import app02
urlpatterns = [
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls'))
]
子路由
app01下的urls.py
-----------------------
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^index/',views.index)
]
# 当访问 https://127.0.0.1:8000/app01/index/便会触发响应的函数
app02下的urls.py
-----------------------
from django.conf.urls import url
from app02 import views
urlpatterns = [
url(r'^index/',views.index)
]
# 当访问 https://127.0.0.1:8000/app02/index/便会触发响应的函数
5.名称空间
心细的读者可能已经发现,路由分发导致了反向解析出现了一个问题:不同的app下可能有相同的url— name的对应关系。
当app01和app02中都有name='index'的对应关系时,我们在反向解析时到底是解析app01中的index还是app02中的index?
为了避免上述问题的出现,我们可以在总路由系统下增加一个命名空间的概念
urlpatterns = [ 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' %}
通常我们在给视图函数与url的对应关系取别名时,可以加上app的前缀,也可以防止上述问题的产生。
6.虚拟环境
虚拟环境是我们在开发不同的项目时,可以只加载针对本项目使用的模块,来加快加载资源时的速度。虚拟环境即一个全新的python解释器环境,有如刚重装的系统一样。
7.django版本的区别
路由层
1.X用的是url
2.X、3.X用的是path
url第一个参数是一个正则表达式
而path第一个参数不支持正则表达式 写什么就匹配什么
如果你觉得path不好用 2.x、3.x给你提供了一个跟url一样的功能
re_path 等价于1.x里面的url功能
虽然path不支持正则表达式 但是它给你提供了五种默认的转换器
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
path('login/<int:year>/',login)
除了默认的五种转换器之外 还支持你自定义转换器
class MonthConverter:
regex='d{2}' # 属性名必须为regex
def to_python(self, value):
return int(value)
def to_url(self, value):
return value # 匹配的regex是两个数字,返回的结果也必须是两个数字
8.伪静态
伪静态
url以.html结尾 给人的感觉好像是这个文件是写死的 内容不会轻易的改变
伪静态
为了提高你的网站被搜索引擎收藏的力度 提供网站的SEO查询效率