# 示例
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login_func),
url(r'^register/$', views.register_func),
]
url( )
方法的第一个参数其实是正则表达式, 一旦第一个参数匹配到了内容直接结束匹配, 并调用对应的视图函数"/"
, 因为每个 url 自带"r"
"/"
, 在第一次正则匹配机制没有匹配到想要的内容时, 会在匹配字符后加一个"/"
, 然后Django内部重定向在匹配一次"/"
"/"
一共匹配了两次# setting.py 文件
APPEND_SLASH = False # 默认 True 自动添加斜杠
建议自动添加
url( ) 方法中第一个参数正则表达式分组 : 给正则表达式前后加一个小括号
会将括号内正则表达式匹配到的内容当做位置参数传递给后边的视图函数
url(r'^login/$', views.login_func)
# 无名分组
url(r'^login/(\d+)/$', views.login_func)
# 视图函数
def login_func(request,*args):
print(args)
return Httpresponse(args)
url(r'^login/$', views.login_func)
# 有名分组
url(r'^login/(?P\d+)/$' , views.login_func)
# 视图函数
def login_func(request,**kwargs):
print(kwargs)
return Httpresponse(args)
url(r'^login/(\d+)/(?P\d+)/$' , views.login_func)
# 官方说不能混着用, 混着用只能取到有名分组捕获的值
# 只要不混着用,有名分组和无名分组支持多个相同类型的传参
url(r'^login/(\d+)/(\d+)/$', views.login_func)
url(r'^login/(?P\d+)/(?P\d+)/$' , views.login_func)
# 路由层
url(r'^login/$', views.login_func,name='login_name')
# 前端中使用(模板层)
<a href="{% url 'login_name' %}">登入</a>
# 后端中使用(视图层)
from django.shortcuts import reverse
url = reverse('login_name')
ps : redirect( ) 括号内也可以直接写别名
url(r'^login/(\d+)/', views.login_func,name='login_name')
from shortcuts import reverse
url = reverse('login_name',args=(1,)) # 随便给个数字
<a href="{% url 'login_name' 1 %}">登入</a> # 随便给个数字
路由层中分组匹配得到的数字并不是我们这样写死的, 一般情况下放的是数据的主键值, 我们可以通过获取到数据的主键.进而定位到数据对象, 从而可以对数据进行编辑和删除
# 路由层
url(r'^login/(\d+)/', views.login_func,name='login_name')
# 视图层
def edit(request,edit_id):
reverse('login_name',args=(edit_id,))
# 模板层
{% for user_obj in user_list %}
<a href="{% url 'login_name' user_obj.id %}">kkk</a>
url(r'^login/(?P\d+)/' , views.login_func,name='login_name')
from shortcuts import reverse
url = reverse('login_name',kwargs=(id:111)) # 随便给个数字
url= =
reverse('login_name',args=(111,)) # 也可以这样写
<a href="{% url 'login_name' id=111 %}">登入</a> # 随便给个数字
<a href="{% url 'login_name' 11 %}">登入</a> # 也可以这样写
由上面的视图层与模板层的第二种书写方式可以看出 : 无名有名都可以使用一种反向解析形式 : 就是无名反向解析
django是专注于开发应用的,当一个django项目特别庞大的时候, 所有的路由与视图函数映射关系全部写在一个 urls.py 里面很明显太冗余并且不便于管理
其实django中的每一个应用都可以有自己的 urls.py、static文件夹、templates文件夹, 基于上述特点, 使用django做分组开发非常的简便
每个人只需要写自己的应用即可, 最后由组长统一汇总到一个空的django项目中然后使用路由分发将多个应用关联到一起
注意 : 总路由正则后面不能添加 "$"
, 不然一配到 app01 就结束了
from django.contrib import admin
from django.urls import path,re_path,include
# 方式一 : 复杂写法
from app01 import urls as app01_ulrs
from app02 import urls as app02_ulrs
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^app01/', include(app01_ulrs)),
re_path(r'^app02/', include(app02_ulrs)),
re_path(r'^app03/', include(app03_ulrs))
]
# 方式二 : 高级写法
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^app01/', include('app01.ulrs')),
re_path(r'^app02/', include('app02.ulrs')),
re_path(r'^app03/', include('app03.ulrs'))
]
from django.contrib import admin
from django.urls import path,re_path
from [app名] import views
urlpatterns = [
re_path(r'^home/',views.home_func),
re_path(r'^index/',views.index_func),
re_path(r'^edit/',views.edit_func),
]
当多个应用设置了相同的别名, 在反向解析的时候前面路由会被后面的路由覆盖, 那么就无法触发前面路由对应的视图函数, 正常情况下, 反向解析是无法自动识别前缀的, 为了避免这种错误, 引入了名称空间
# app01
app_name='app01' # 应用命名空间
urlpatterns = [
re_path(r'^home/',views.home_func,name='home_name')
]
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^app01/', include('app01.ulrs',namespace='app01')),
re_path(r'^app02/', include('app02.ulrs',namespace='app02')),
re_path(r'^app03/', include('app03.ulrs',namespace='app03'))
]
# app01
app_name='app01'
urlpatterns = [
re_path(r'^home/',views.home_func,name='home_name')
]
# app02
app_name='app02'
urlpatterns = [
re_path(r'^home/',views.home_func,name='home_name')
]
# app03
app_name='app03'
urlpatterns = [
re_path(r'^home/',views.home_func,name='home_name')
]
# app01
from django.shortcuts import reverse
def home_func(request):
res = reverse('app01:home_name')
return HttpResponse(res) # /app01/home/
# app02
from django.shortcuts import reverse
def home_func(request):
res = reverse('app02:home_name')
return HttpResponse(res) # /app02/home/
# app03
from django.shortcuts import reverse
def home_func(request):
res = reverse('app03:home_name')
return HttpResponse(res) # /app03/home/
<a href="{% url 'app01:name_name' %}">app01a>
<a href="{% url 'app02:home_name' %}">app02a>
<a href="{% url 'app03:home_name' %}">app03a>
# app01
urlpatterns = [
re_path(r'^home/',views.home_func,name='app01_home_name'),
]
# app02
urlpatterns = [
re_path(r'^home/',views.home_func,name='app02_home_name'),
]
# app03
urlpatterns = [
re_path(r'^home/',views.home_func,name='app03_home_name'),
]
.html
, 但我们是可以对文章内容进行修改的ps : 再如何优化也比不过加钱居士
urlpatterns = [
re_path(r'home.html/',views.home_func),
]
# 访问 : 127.0.0.1:8888/home.html/
Django 1.x
版本与 2.x
、3.x
版本的区别
1.x
中使用的是 url( ) 方法, 第一个参数是正则表达式2.x
与3.x
中使用的是 path( ) 方法, 第一个参数不支持正则表达式, 些什么就匹配什么如果想要在
2.x
和3.x
中的第一个参数中使用正则表达式, 则需要导入 re_path 方法from django.urls import path,re_path
re_path 等价于
1.x
中的 url 方法
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////' , views.article_detail, name='date_time'),
]
pip install -r requirements.txt