1.初识路由系统
路由系统是用户发请求到URL,然后URL根据路由系统重新指向到函数名的一个对应关系
2.创建project和app
django-admin startproject mysite cd mysite python manage.py startapp appd01
3.在项目的urls.py中定义路由关系,逻辑关系在views.py中。
views.py
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. def f1(request): return HttpResponse('OK') def login(request): return HttpResponse('Login') def detail(request,nid): print (nid) return HttpResponse('Detail') def detail2(request,nid,nnid): print (nid,nnid) return HttpResponse('Detail2') def detail3(request,n1,n2): print (n1,n2) return HttpResponse('Detail3')
urls.py
from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^index/', views.f1), url(r'^login/', views.login), url(r'^login2/', views.login), url(r'^detail/(d+)/', views.detail), url(r'^detail2/(d+)/(d+)/', views.detail2), url(r'^detail3/(?P<n1>d+)/(?P<n2>d+)/', views.detail3), ]
4.路由系统之分页
urls.py中定义页面与函数的对应关系
from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), # url(r'^index/', views.f1), url(r'^login/', views.login), url(r'^login2/', views.login), url(r'^detail/(d+)/', views.detail), url(r'^detail2/(d+)/(d+)/', views.detail2), url(r'^detail3/(?P<n1>d+)/(?P<n2>d+)/', views.detail3), url(r'^index/(d+)/', views.index), ]
定义views.py
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. def f1(request): return HttpResponse('OK') def login(request): return HttpResponse('Login') def detail(request,nid): print (nid) return HttpResponse('Detail') def detail2(request,nid,nnid): print (nid,nnid) return HttpResponse('Detail2') def detail3(request,n1,n2): print (n1,n2) return HttpResponse('Detail3') USER_LIST = [] for item in range(94): temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)} USER_LIST.append(temp) def index(request,page): page = int(page) start = (page -1)*10 end = page*10 user_list = USER_LIST[start:end] return render(request,'index.html',{'user_list':user_list})
定义index.html页面
<body> <table> <tr> <td>ID</td> <td>用户名</td> </tr> {% for item in user_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.username }}</td> </tr> {% endfor %} </table> </body>
5.路由系统分页之详细信息
urls.py
url(r'^index/(d+)/', views.index), url(r'^detail/(d+)/',views.detail)
views.py
USER_LIST = [] for item in range(94): temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)} USER_LIST.append(temp) def index(request,page): page = int(page) start = (page -1)*10 end = page*10 user_list = USER_LIST[start:end] return render(request,'index.html',{'user_list':user_list}) def detail(request,nid): nid = int(nid) user_list_dict = USER_LIST[nid] return render(request,'detail.html',{'user_list_dict':user_list_dict})
index.html
<body> <table> <tr> <td>ID</td> <td>用户名</td> </tr> {% for item in user_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.username }}</td> <td><a href="/detail/{{ item.id }}">详细信息</a></td> </tr> {% endfor %} </table> </body>
detail.html
<body> <ul> <li>{{ user_list_dict.id }}</li> </ul> <ul> <li>{{ user_list_dict.username }}</li> </ul> <ul> <li>{{ user_list_dict.email }}</li> </ul> </body>
6.路由分发系统
加入我们按照系统的模块来分,前端的访问界面用web字段开头,后面的管理模块用manager字段开头,那么需要定义两个虚拟主机,一个app01,一个manager01。
那么在项目s13day18_django中定义urls.py的时候就需要定义两个虚拟主机的映射关系,这时,可以在单独的虚拟主机中也定义对应的urls.py。
s13day18_django.urls.py
from django.conf.urls import url, include from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse from app01 import views urlpatterns = [ url(r'^web/', include('app01.urls')), url(r'^manager/',include('manager01.urls')) ]
app01.urls.py
urlpatterns = [ url(r'^index/(d+)/', views.index), url(r'^detail/(d+)/',views.detail) ]
manager01.urls.py未定义
app01.views.py
USER_LIST = [] for item in range(94): temp = {'id':item,'username':'alex'+str(item),'email':'email'+str(item)} USER_LIST.append(temp) def index(request,page): page = int(page) start = (page -1)*10 end = page*10 user_list = USER_LIST[start:end] return render(request,'index.html',{'user_list':user_list}) def detail(request,nid): nid = int(nid) user_list_dict = USER_LIST[nid] return render(request,'detail.html',{'user_list_dict':user_list_dict})
templates下面的index.html
<body> <table> <tr> <td>ID</td> <td>用户名</td> </tr> {% for item in user_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.username }}</td> <td><a href="/web/detail/{{ item.id }}">详细信息</a></td> </tr> {% endfor %} </table> </body>
以及detail.html
<body> <ul> <li>{{ user_list_dict.id }}</li> </ul> <ul> <li>{{ user_list_dict.username }}</li> </ul> <ul> <li>{{ user_list_dict.email }}</li> </ul> </body>
以后访问app01或者manager01的APP的时候,需要访问页面中输入http://127.0.0.1:8000/web/index/7/或者http://127.0.0.1:8000/manager/...
7.模板语言
在模板语言中使用render传递的变量
{{ k1 }} {{ k2.0 }} {% for item in k2 %} <p>{{ item}},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.first }},{{ forloop.last }},{{ forloop.revcounter }}</p> {% endfor %} {% if k1 == 'v1' %} <h1>V1</h1> {% elif k1 == 'v2' %} <h1>V2</h1> {% else %} <h1>OTHER</h1> {% endif %}
在模板语言中如何使用自定义函数
a.创建指定文件夹,名称不能改templatetags
b.创建任意.py文件,写函数,返回值register不能变
from django import template from django.utils.safestring import mark_safe from django.template.base import Node,TemplateSyntaxError register = template.Library() @register.filter def f1(value): return value+'10'
c.在HTML文件的开头导入自定义模块,并且在HTML文件中使用函数
{% load xx %}
......
<body>
{{ k1|f1 }}
</body>
d.在项目的settings.py中注册app01
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', ]
这样就可以在模板中使用自定义的函数了。但是在filter模式中,我们只能传递一个参数,如果要传递多个参数,可以自行分解传递的第一个参数,或者使用simple_tag的方式来处理。
使用simple_tag,只需要在原有的基础上修改装饰器的名字,然后调用方式修改一下。
@register.simple_tag def f2(s1,s2,s3,s4): return s1+s2+s3+s4
{% f2 1 2 3 4 %} //f2是函数名,1 2 3 4分别是传递过来的4个参数
filter可以支持模板语言的if条件,simple_tag不支持
在xx.py中定义
@register.filter def f3(value): if value == 'VVV': return True else: return False
在template.html中定义
{% if k1|f3 %} <h1>True</h1> {% else %} <h1>False</h1> {% endif %}
8.模板
假设我们有一个如下的样示:
每次点用户管理的时候,用户管理被选中,并且右侧栏显示用户管理的内容,点击资产管理的时候,资产管理被选中,并且右侧栏显示资产管理的内容。最简单的做法是分别再两个页面中添加active的属性,并且显示值。
userinfo.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .pg-header{ height: 48px; background-color: blue; } .pg-body{ min-height: 500px; } .pg-body .body-menu{ 20%; float: left; } .pg-body .body-content{ 80%; float: left; } .pg-footer{ height: 100px; background-color: brown; } .active{ background-color: blueviolet; color: white; } </style> </head> <body> <div class="pg-header"></div> <div class="pg-body"> <div class="body-menu"> <ul> <li><a href="/web/userinfo" class="active">用户管理</a></li> <li><a href="/web/assets">资产管理</a></li> </ul> </div> <div class="body-content"> <table border="1" solid red> {% for item in user_list %} <tr> <td>{{ item.username }}</td> <td>{{ item.sexy }}</td> </tr> {% endfor %} </table> </div> </div> <div class="pg-footer"></div> </body> </html>
assets.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .pg-header{ height: 48px; background-color: blue; } .pg-body{ min-height: 500px; } .pg-body .body-menu{ 20%; float: left; } .pg-body .body-content{ 80%; float: left; } .pg-footer{ height: 100px; background-color: brown; } .active{ background-color: blueviolet; color: white; } </style> </head> <body> <div class="pg-header"></div> <div class="pg-body"> <div class="body-menu"> <ul> <li><a href="/web/userinfo">用户管理</a></li> <li><a href="/web/assets" class="active">资产管理</a></li> </ul> </div> <div class="body-content"> <table border="1" solid red> {% for item in assets_list %} <tr> <td>{{ item.hostname }}</td> <td>{{ item.port }}</td> </tr> {% endfor %} </table> </div> </div> <div class="pg-footer"></div> </body> </html>
可以看到,在两段代码中有大量的重用。并且一旦修改,所有页面都要修改,有没有像函数一样可以导入的方式呢,把不变化的内容创建一个模板layout.html。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .pg-header{ height: 48px; background-color: blue; } .pg-body{ min-height: 500px; } .pg-body .body-menu{ width: 20%; float: left; } .pg-body .body-content{ width: 80%; float: left; } .pg-footer{ height: 100px; background-color: brown; } .active{ background-color: blueviolet; color: white; } </style> </head> <body> <div class="pg-header"></div> <div class="pg-body"> <div class="body-menu"> <ul> <li><a href="/web/userinfo">用户管理</a></li> <li><a href="/web/assets">资产管理</a></li> </ul> </div> <div class="body-content"> {% block body %}{% endblock %} </div> </div> <div class="pg-footer"></div> </body> </html>
assets.html
{% extends "layout.html" %} {% block body %} <table border="1" solid red> {% for item in assets_list %} <tr> <td>{{ item.hostname }}</td> <td>{{ item.port }}</td> </tr> {% endfor %} </table> {% endblock %}
userinfo.html
{% extends "layout.html" %} {% block body %} <table border="1" solid red> {% for item in user_list %} <tr> <td>{{ item.username }}</td> <td>{{ item.sexy }}</td> </tr> {% endfor %} </table> {% endblock %}
使用上面的方法之后,可以正常的显示页面了,但是选中菜单确没有了。有两种方式可以添加选中菜单,一种依旧是定义一个block,然后重写,另外一种就是给layout里面的元素添加ID,然后通过JS来访问。
layout.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .pg-header{ height: 48px; background-color: blue; } .pg-body{ min-height: 500px; } .pg-body .body-menu{ width: 20%; float: left; } .pg-body .body-content{ width: 80%; float: left; } .pg-footer{ height: 100px; background-color: brown; } .active{ background-color: blueviolet; color: white; } </style> </head> <body> <div class="pg-header"></div> <div class="pg-body"> <div class="body-menu"> <ul> <li><a id="userinfo" href="/web/userinfo">用户管理</a></li> <li><a id="assets" href="/web/assets">资产管理</a></li> {% block js %}{% endblock %} </ul> </div> <div class="body-content"> {% block body %}{% endblock %} </div> </div> <div class="pg-footer"></div> </body> </html>
userinfo.html
{% extends "layout.html" %} {% block body %} <table border="1" solid red> {% for item in user_list %} <tr> <td>{{ item.username }}</td> <td>{{ item.sexy }}</td> </tr> {% endfor %} </table> {% endblock %} {% block js %} <script> document.getElementById("userinfo").className="active"; </script> {% endblock %}
assets.html
{% extends "layout.html" %} {% block body %} <table border="1" solid red> {% for item in assets_list %} <tr> <td>{{ item.hostname }}</td> <td>{{ item.port }}</td> </tr> {% endfor %} </table> {% endblock %} {% block js %} <script> document.getElementById("assets").className="active"; </script> {% endblock %}
include的使用,假设在userinfo.html里面经常要使用多个对话框的时候,可以单独将多个对话框拿出来放在一个单独的html文件中,例如pizza.html
<form> <input type="text"> <input type="text"> <input type="text"> <input type="text"> </form>
然后要使用的时候,在userinfo.html中直接include即可:
{% extends "layout.html" %} {% block body %} <table border="1" solid red> {% for item in user_list %} <tr> <td>{{ item.username }}</td> <td>{{ item.sexy }}</td> </tr> {% endfor %} </table> {% include "pizza.html" %} {% include "pizza.html" %} {% include "pizza.html" %} {% endblock %} {% block js %} <script> document.getElementById("userinfo").className="active"; </script> {% endblock %}