项目里的ulrs文件
from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer),
# 路由配置:
# 路径对应相关试图处理,
# 正则表达式,注意2003匹配第一个,不往下匹配
# path引入后添加一个re_path
re_path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
# 分组匹配成功,调用函数会传入多个参数,
# 因此view里定义时要注意形参个数,year-archive(request,1999)
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
# 有名分组 ?P<名字> 相当于关键字传参,此时函数定义形参时命名一致。
re_path(r'^articles/(?P[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$', views.article_detail),
]
应用里的views文件
from django.shortcuts import render,HttpResponse
# 文件自己引入的,在后面添加 HttpResponse 响应对象
def timer(request):
# 文件会把浏览器请求信息作为参数request值传入,在此要接收request
import time
ctime = time.time()
return render(request, "timer.html", {"ct": ctime})
# render方法自动去找html文件,注意传入的ctime是字典格式
# 路由配置
def special_case_2003(request):
# 响应体的内容
return HttpResponse("special2003")
def year_archive(request,year):
return HttpResponse('year...')
def month_archive(request,year,month):
pass
def article_detail(request,year,month,num):
pass
根据全局urls文件路径分发到各个应用的urls文件里,每个urls文件里可以再分组匹配不同的路径视图。
urls全局文件
from django.contrib import admin
from django.urls import path,re_path,include # include引入
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('timer/', views.timer),
# 分发 除了全局的,把各自应用单独的放在各自新建文件夹urls里
re_path(r"app01/",include("app01.urls")) # 匹配路径之后,include各自的urls文件里执行
]
app01 urls
urlpatterns = [
# 有名分组 ?P<名字> 相当于关键字传参,此时函数定义形参时命名一致。
re_path(r'^articles/(?P[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$', views.article_detail),
]
path('login/', views.login),
view
def login(request):
# 请求方式判断
if request.method =='GET':
return render(request,"login.html")
else:
# request.POST字典格式,获取数据
user=request.POST.get('user')
pwd=request.POST.get('pwd')
# 连接数据库校验。。。
# 最后一定要有return
return HttpResponse("....")
login.html
如果url里路径改变,那action里也要修改,反向解析就是可以保持同步
# 路径可能会更改,更改之后,form表单action也得更改
# 反向解析
path('login/', views.login,name="Log")
{# 模板语法,在view里函数返回页面,render渲染时候,去找一个name=Log的url替换#}
url起个name
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
re_path(r'^articles/2003/$',views.special_case_2003,name='s_c_2003'),
re_path(r'^articles/(?P[0-9]{4})/$',views.year_archive,name='y'),
re_path(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})$',views.month_archive),
path('index/',views.index,name='indexes')
]
views,reverse函数
from django.shortcuts import render,HttpResponse
from django.urls import reverse
def special_case_2003(request):
url = reverse('s_c_2003')
print(url) # /app01/articles/2003/
return HttpResponse('special_case_2003')
def year_archive(request,year):
url = reverse('y',args=(year,)) # 这里有这正则表达式
print(url) # /app01/articles/2018/
return HttpResponse(year)
由于name没有作用域,Django在反解URL时,会在项目全局顺序搜索,当查找到第一个name指定URL时,立即返回。也就是说使用name属性反解出URL,当不小心在不同的app的urls中定义相同的name时,可能会导致URL反解错误,为了避免这种事情发生,引入了命名空间。
项目的urls文件:
rom django.urls import path,re_path,include
urlpatterns = [
path('app01/',include(('app01.urls','app01'))), # 元祖形式,限制名称空间
path('app02/',include(('app02.urls','app02'))),
]
app01.urls:
from django.urls import path,re_path,include
from app01 import views
urlpatterns = [
path('index/', views.index, name='index')
]
app02.urls:
from django.urls import path, re_path, include
from app02 import views
urlpatterns = [
path('index/', views.index, name='index')
]
app01.views
from django.shortcuts import render,HttpResponse
from django.urls import reverse
def index(request):
return HttpResponse(reverse('app01:index'))
app02.views
from django.shortcuts import render,HttpResponse
from django.urls import reverse
def index(request):
return HttpResponse(reverse('app02:index'))
在上述路径获取执行对应的views里的函数时,传参数传入的都是字符串类型。比如正则匹配的1999,就是字符串。
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
# 分组匹配成功,调用函数会传入多个参数,
# 因此view里定义时要注意形参个数,year-archive(request,1999)
在视图里可以转换,那可以在url里匹配之后传入之前就转好好?
另外,匹配规则重复了几次,要是改都得改。
urlpatterns = [
re_path('articles/(?P[0-9]{4})/', year_archive),
re_path('article/(?P[a-zA-Z0-9]+)/detail/', detail_view),
re_path('articles/(?P[a-zA-Z0-9]+)/edit/', edit_view),
re_path('articles/(?P[a-zA-Z0-9]+)/delete/', delete_view),
]
django的path可以解决:
from django.urls import path
from app01 import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles//', views.year_archive), # 注意
path('articles///', views.month_archive),
path('articles////', views.article_detail),
]
views文件
from django.shortcuts import render,HttpResponse
...
def year_archive(request,year):
print(year,type(year))
return HttpResponse(year)
...
def article_detail(request,year,month,str_data):
print(str_data,type(str_data))
return HttpResponse(str_data)
Django默认支持以下5个转化器:
新建一个文件,自定义一个类
自定义一个规则属性regex,
两个方法,
to_python(self, value) 方法,value是由类属性 regex
所匹配到的字符串,返回具体的Python变量值,以供Django传递到对应的视图函数中
to_url(self, value) 方法,和 to_python
相反,value是一个具体的Python变量值,返回其字符串,通常用于url反向引用。
在项目url里引用文件,用register_converter注册下。
在path里正常用
自定义py文件放在应用文件里app01文件夹下。
# 自定义一个类
class MonConvert:
# 自定义一个规则regex,
regex = '[0-9]{2}'
def to_python(self,value):
return int(value) # 直接就转换成int了
def to_url(self,value):
return '%04d'%value
urls.py文件
from django.urls import path,register_converter
from app01 import views
#文件引用
from app01.urlconvert import MonConvert
# 并用register_converter注册下
register_converter(MonConvert,'mm')
urlpatterns = [
# 上面注册成mm,这里就用mm
path('articles//', views.year_archive),
]
views.py文件
from django.shortcuts import render,HttpResponse
def year_archive(request,month):
print(month,type(month))
return HttpResponse(month)