Django框架--路由分配系统
Python的WEB框架有Django、Tornado、Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等诸多功能。
本文将以下方面带大家全面了解Django框架,本章使用的版本为1.11.
-
流程
- 基本配置
- 路由系统
- 视图view
- 模板
- Model
- Form
- 分页
- Cookie
- Seesion
- admin
一、 Django流程介绍
MVC是众所周知的模式,即:将应用程序分解成三个组成部分:model(模型),view(视图),和 controller(控制 器)。其中:
M——管理应用程序的状态(通常存储到数据库中),并约束改变状态的行为(或者叫做“业务规则”)。
C——接受外部用户的操作,根据操作访问模型获取数据,并调用“视图”显示这些数据。控制器是将“模型”和“视图”隔离,并成为二者之间的联系纽带。
V——负责把数据格式化后呈现给用户。
Django也是一个MVC框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式:
M 代表模型(Model),即数据存取层。 该层处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。
T 代表模板(Template),即表现层。 该层处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。
V 代表视图(View),即业务逻辑层。 该层包含存取模型及调取恰当模板的相关逻辑。 你可以把它看作模型与模板之间的桥梁。
二、 Django 基本配置
1. 创建django程序
- 终端命令:django-admin startproject sitename (在当前目录下创建一个Django程序)
- IDE创建Django程序时,本质上都是自动执行上述命令
其他常用命令:
python manage.py runserver ip:port (启动服务器,默认ip和端口为http://127.0.0.1:8000/)
python manage.py startapp appname (新建 app)
python manage.py makemigrations (显示并记录所有数据的改动)
python manage.py migrate (将改动更新到数据库)
python manage.py createsuperuser (创建超级管理员)
python manage.py shell (命令行)
python manage.py (查看命令列表)
2. 程序目录
Django大致工作流程
1、客户端发送请求(get/post)经过web服务器、Django中间件、 到达路由分配系统
2、路由分配系统根据提取 request中携带的的url路径(path)与视图函数映射关系列表中,匹配到1个视图函数,foo(request)执行;
3、视图函数 使用原生SQL或者ORM去数据库拿到数据,在服务端进行渲染(模板+数据渲染)
4、视图函数return一个 response对象 返回客户端
3. 配置文件
a、数据库
支持SQLite 3(默认)、PostgreSQL 、MySQL、Oracle数据库的操作
# 默认是SQLit 3 的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # MySQL的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbname', #注意这里的数据库应该以utf-8编码 'USER': 'xxx', 'PASSWORD': 'xxx', 'HOST': '', 'PORT': '', } } # 对于python3的使用者们还需要再加一步操作 # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替 # 如下设置放置的与project同名的配置的 __init__.py文件中 import pymysql pymysql.install_as_MySQLdb() # PostgreSQL配置 DATABASES = { 'default': { 'NAME': 'app_data', 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': 'XXX', 'PASSWORD': 'XXX' } # Oracle配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': 'xe', 'USER': 'a_user', 'PASSWORD': 'a_password', 'HOST': '', 'PORT': '', } }
Django框架对于开发者而言高度透明化,对于不同数据库的具体使用方法是一致的,改变数据库类型只需要变动上述配置即可。
想要了解更多请戳这里
b、静态文件添加
# 首先在项目根目录下创建static目录 # 接着在settings.py 文件下添加 STATIC_URL = '/static/' # 默认已添加,使用静态文件时的前缀 STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), #行末的逗号不能漏 ) # 这样在template中就可以导入static目录下的静态文件啦 # 例: <script src="/static/jquery-1.12.4.js"></script>
三、 Django 路由系统
Django路由分配系统简介
Django project目录中的urls.py文件中, 以Python [ ( ) ]的数据类型记录了可以访问到该站点的url 和 视图函数一一对应关系表,当request请求到达路由系统,Django通过request中携带的path 遍历这个关系表,匹配到对应的视图函数,break;(所以1个 url 只能从路由关系表中自上而下匹配到1个视图函数)
1、Django的路由分配系统
1个URL对应1个视图函数
from django.conf.urls import url from django.contrib import admin from APP import view urlpatterns = [ url(r'^modal/',view.modal), url(r'^域名',对应的处理函数) 注意不要忘了写 ^ 表示正则匹配以。。开头的URL url(r'^modal_add/',view.modal_add), url(r'^modal_del/',view.modal_del), url(r'^modal_edit/',view.modal_edit), ]
2、在客户端通过url中的 path向后端传参数
在前端我们不仅可以通过get请求携带参数的方式向server端传数据; https://i.cnblogs.com/%EF%BC%9Fid=1&name=alex
Django也允许通过,path路径的方式向server端传值;
注意事项:按位置,和按关键字路由系统只能用1种,不能混合使用;
1)、path正则无名分组匹配《---------》视图函数按位置传参
from django.conf.urls import url,include from django.contrib import admin from app1 import views urlpatterns = [ url(r'^index/(\w+)/(\w+)/',views.index2), #酱紫的话客户端 输入:http://127.0.0.1:8000/index/a/b/也可以访问到该站点 url(r'^',views.error) ] urlpatterns = [ url(r'^/',index), #视图函数 index(request) url(r'^(\d{4})/\d{2}/$',timeer1), #视图函数 timeer1(request,实参1) 正则增加了分组,视图函数会增加一个参数; url(r'^(\d{4})/(\d{2)/$',timeer2) #视图函数 timeer2(request,实参1,实参2) 视图函数需要2个形参接收; # url(r'^(?P<year>\d{4})/(?P<month>\d{2})/$',timeer),
在路由系统定义了 几个正则分组(),在视图函数对应几个实参接收;
def timeer2(request,a1,a2): print(a1,a2) #打印参数a1,a2 就是 2个正则表达式匹配到的结果 return Httprespose('ok') #注意如果按位置传参的动态路由系统,必须在视图函数添加对应的参数接收!
2)、path正则有名分组匹配《---------》视图函数按关键字传参
按位置传参形参或实参错位会导致数据错乱,所以Django路由分发系统还可以以命名分组的形式匹配URL给视图函数按关键字传参;
from django.conf.urls import url,include from django.contrib import admin from app1 import views urlpatterns = [ url(r'^index/(P<n1>\w+)/(P<n2>\w+)/',views.index,name="zhanggen"), url(r'^(?P<year>\d{4})/(?P<month>\d{2})/$',timeer), url(r'^',views.error), ] #注意如果在路由系统正则内部定义了关键字n1,n2,视图函数接收参数也必须是 n1,n2; urlpatterns = [ # url(r'^/',index), #index(request) # url(r'^(\d{4})/\d{2}/$',timeer), #timeer(request,2014) 正则增加了分组,视图函数会增加一个参数; # url(r'^(\d{4})/(\d{2)/$',timeer1) , #timeer(request,2014,12) 视图函数需要两个形参接收 url(r'^(?P<year>\d{4})/$(?P<month>\d{2})',timeer2) #timeer(request,year=2017,month=6) 正则设置了有名分组,视图函数使用关键字传参 ]
在视图函数定义2个关键字参数, 接收 2个正则表达式匹配到的后缀;
def index(request,n1,n2): print(n1,n2) #注意必须和 路由系统中的一致 return HttpResponse('OK')
3)、URL path传值应用
有了动态路由就 可以不用在 url?nid=8这样传值了!
PS:
终止符:^edit$ 可以精确限制匹配URL的后缀内容
伪静态:url(r'^edit/(\w+).html$', views.edit) 装作成静态网站的url可以 提高 SEO高权重 百度排名靠前
url(r'^student_del/(.*).html/',views.student_del),
<a href="/student_del/{{row.id}}.html/">删除</a></td>
def student_del(request,args1):
return HttpResponse('nihao')
3、路由分发
1个Django 项目里面有多个APP目录大家共有一个 url容易造成混淆,于是路由分发让每个APP的拥有了自己单独的url;
from django.conf.urls import url,include from django.contrib import admin from app1 import views urlpatterns = [ url(r'^app1/',include('app1.urls')), url(r'^app2/',include('app2.urls')), #注意include的是字符串形式的 文件路径; url(r'^',views.error), ]
酱紫就可以在每个 Django目录下面写自己的 URL了
4、路由别名(应用站点权限管理)
1)、什么是路由别名?
给Django路由分发系统 URL--视图函数对应关系命个名,
然后在模板中{% url "zhanggen" i i1%}反生成 访问该站点URL,
或者在视图函数中reverse()反向生产当前访问URL;
2)、作用
保证前后端数据一致性,后端修改了匹配URL,不用在前段更改;
from django.conf.urls import url,include from django.contrib import admin from app1 import views urlpatterns = [ url(r'^index/(?P<n1>\w+)/(?P<n2>\w+)/',views.index,name="alex"), 给这个URL起别名 alex url(r'^',views.error), ]
在视图函数使用 reverse("别名", args=(1, 2)) 反生 位置参数动态路由的 别名
def index(request,n1,n2): print(reverse("zhanggen", args=(1, 2))) return render(request,'index.html',{'i':1,'i1':2})
在视图函数使用 reverse("别名",kwargs={"关键字参数":1,"关键字参数":2 }反生 关键字参数动态路由的 别名
def index(request,n1,n2): print(reverse("zhanggen",kwargs={"n1":1,"n2":2 })) return render(request,'index.html',{'i':1,'i1':2})
在模板中反生 URL
注意 在视图函数中 return render(request,'index.html',{'i':1,'i1':2})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>{{ i }}</p> <p>{% url "zhanggen" i i1%}</p> </body> </html>