django请求生命周期流程图
ps:缓存数据库的存在(绿色)
路由层相关
路由匹配
1.urls的匹配是正则表达式的匹配,当从上到下匹配到任意一个符合正则条件的网址,就会停止匹配
2.当在网页中输入url没有加/,而在urls层又有/时,django会自动加/再访问一次
如何取消自动加/?
在配置文件中:APPEND_SLASH = True/False
3.url的标准格式是
urls = [
url(r'^$'),对应的网址), # 匹配首页
url(r'^xxx/$',对应的网址),
url(r'',匹配尾页)
# 匹配尾页,由于能够接受到所有的网址,所以如果前面的网页需要斜杠
# 而又没有斜杠/,由于第一次匹配已经匹配到,所以不会进行第二次匹配
]
路由分组
无名分组
'''
就是用正则中的()进行分组
'''
url(r'^userinfo/(/d+)', views.userinfo)
def userinfo(request, number):
print(number)
'''
在视图函数中必须要用一个形参来接受数据,可以多个分组一起使用,
有几个分组就要用几个形参来接受.
'''
有名分组
'''
就是用正则中的(?P<name>表达式)进行分组
'''
url(r'^userinfo/(?P<cc>\d+)', views.userinfo),
def userinfo(request, cc):
print(cc)
'''
名字是什么传入的参数名就是什么
'''
注意
两者不能一起混合使用
反向解析
动态反向解析方法
# 通过一些方法得到结果,而结果能够对url直接进行访问
'''
反向解析步骤:
1.给url起别名
url('^login/',views.login,name='A')
2.后端反向解析
from django.shortcuts import reverse
reverse('A')
3.前端解析
<a href={% url 'A' %}>A</a>
'''
有名无名反向解析方法
'''
通过有名无名反向解析方法我们的目的是为了拿到一个url值,而且通常是对应的主键值
针对于正则匹配形式下的反向解析方法:
即面对动态的url,该如何获取我们想到的值
通常放的是数据库的主键值
1.无名反向解析方法:
1.起别名
url(r'^login/(\d+)',views.login,name='ooo')
2.拿到url
前端:
{% url 'ooo' '动态解析的值' %}
后端:
reverse('xxx',args=('动态解析的值',))
2.有名反向解析方法
1.起别名
url(r'^login/(?P<关键字>\d+)',views.login,name='ooo')
2.拿到url
前端:
1.){% url 'ooo' 关键字=''%}
2.){%url 'ooo' '直接传值'%} # 与无名前端拿url一致
后端:
1.reverse('ooo',args=('',))
2.reverse('ooo',kwargs={'关键字':'值'})
'''
'''
{% for user in user_data %}
<tr>
<td class="text-center">{{ user.id }}</td>
<td class="text-center">{{ user.name }}</td>
<td class="text-center">{{ user.password }}</td>
<td class="text-center"><a href='{%url 'bbb' user.id%}' class="btn btn-success">修改</a>
<a href="{% url 'aaa' user.id %}" class="btn btn-danger">删除</a></td>
</tr>
{% endfor %}
'''
'''
urlpatterns = [
# url(r'^admin/', admin.site.urls),
# url(r'^$', views.home),
# url(r'^userinfo/', views.userinfo,name='1'),
# url(r'^delete_userinfo/', views.delete_userinfo, name='0'),
# url(r'', views.error)
url(r'^userinfo/', views.userinfo, name='ccc'),
url(r'^change_userinfo/(\d+)/', views.change_userinfo, name='bbb'),
url(r'^delete_userinfo/(\d+)/', views.deleter_userinfo,name='aaa')
]
'''
路由分发
'''
django支持同步开发,在他的每一个APP下面都可以有知己的templates以及urls.py
这样即提高了开发的效率,又增强了可维护性.
利用路由分发,总路由只负责与分路由相互联系,然后交由分路由来进行路由匹配
'''
'''
路由分发的实现方法:
1.在app中建立路由与视图的关系
urls.py
2.在总url中建立与分url之间的关系
form django.conf.url import url,include
方法一:
from app import urls as app_urls
urlpatterns = [
url(^'app/',include(app_urls))
]
方法二:直接书写不必导入子urls
urlpatterns = [
url(^'app/',include('app.urls'))
]
'''
总URLS:
from django.conf.urls import url, include
from app01 import urls as app01_urls
urlpatterns = [
url(r'app01/', include(app01_urls))
# url(r'^app01/', include('app01.urls')),
]
分URLS:
from django.conf.urls import url
from app01 import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
# url(r'^$', views.home),
# url(r'^userinfo/', views.userinfo,name='1'),
# url(r'^delete_userinfo/', views.delete_userinfo, name='0'),
# url(r'', views.error)
url(r'^userinfo/', views.userinfo, name='ccc'),
url(r'^change_userinfo/(\d+)/', views.change_userinfo, name='bbb'),
url(r'^delete_userinfo/(\d+)/', views.deleter_userinfo, name='aaa')
]
名称空间
'''
分任务开发可能出现同样的名称,此时为了处理名称相同从而导致反向解析拿到名称混乱的问题:
有如下两种方法
1.namespace
在总urls中include中的namespace参数中设置名字
给每个APP的名称空间命名
如何取值?
后端reverse('指定的空间名:子urlname')
reverse('app01:reg')
reverse('app02:reg')
前端:
{% url 'app01:reg' %}
{% url 'app02:reg' %}
2.在子urls中取不同的名字
'''
方法一:
from django.conf.urls import url, include
from app01 import urls as app01_urls
urlpatterns = [
url(r'^app01/', include(app01_urls,namespace='app01'),),
# url(r'^app01/', include('app01.urls')),
url(r'^app02/', include('app02.urls',namespace='app02'))
]
方法二:在子urls中取不同的别名
urlpatterns = [
url(r'^userinfo/', views.userinfo, name='app01_ccc'),
url(r'^change_userinfo/(\d+)/', views.change_userinfo, name='app01_bbb'),
url(r'^delete_userinfo/(\d+)/', views.deleter_userinfo, name='app01_aaa')
]
结果:
1./app01/userinfo/
2./app02/user/
伪静态
'''
为什么要设置伪静态呢?
因为浏览器在本质上就是一个巨大的爬虫,静态文件能够更加优先被查找以及添加所以要设置成伪静态
如何设置伪静态?
在后缀加上.html
http://127.0.0.1:8000/app01/userinfo.html
'''
虚拟环境
'''
当单独处理一个项目时使用虚拟环境:
每创建一次虚拟环境就相当于重新下载一次python解释器,并且通常将项目使用的模块都存储在项目下的特定文件之中
'''
django版本区别
'''
1. 1.x和2.x中的path和url的区别
在1.x中默认使用url,第一个参数是正则
在2.x中默认使用path,第一个参数输入什么就是什么(查找也是,不再正则查询)
2.re_path和url
在2.x中re_path就等价于1.x中的urls
from django.urls import re_path
3.django支持五中转换器
str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
int,匹配正整数,包含0。
slug,匹配字母、数字以及横杠、下划线组成的字符串。
uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
例如:
path('index/<int:id>/',index)
# 将第二个路由里面的内容先转成整型然后以关键字的形式传递给后面的视图函数
def index(request,id):
print(id,type(id))
return HttpResponse('index')
4.还支持自定义转换器
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/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),
5.级联更新和级联删除
在1.x中默认数据表创建就是级联关系
而在2.x中需要手动设置
models.ForeignKey(to='Publish',on_delete=models.CASCADE...)
'''