1.路由系统之动态路由
前言:还记得之前的分页效果,这个如何实现呢?答案就是动态路由。
url(r'^detail/(d+)/$', views.detail), url(r'^detail2/(d+)/(d+)/$', views.detail2), url(r'^detail3/(?P<p1>d+)/(?P<x2>d+)/', views.detail3),#设定后端对应处理的函数分别为p1,x2
通过正则表达式,匹配包含数字的URL,交给views中的函数处理,对应的函数要传送匹配的参数,具体如下:
def detail(request, nid):
print(nid)
return HttpResponse('OK')
# detail2(1,2)
def detail2(request, xid, nnid):
print(xid,nnid)
return HttpResponse('OK')
# detail3(x2=234,p1=123)
def detail3(request, p1, x2):
print(p1,x2)
return HttpResponse('OK')
那么分页是怎么实现的呢,代码如下:
##url
url(r'^index/(d+)/', views.index),
##view
#生成一个包含字典的列表
USER_LIST = []
for item in range(94):
temp = {"id": item, 'username':'jason'+str(item), 'email': 'email' + str(item)}
USER_LIST.append(temp)
def index1(request, page):
print(page)
# 1,0-9
# 2,10-19
# 3,20-29
page = int(page)
start = (page - 1) * 10
end = page * 10
user_list = USER_LIST[start:end]#设定每页取值的范围
# return HttpResponse('OK')
return render(request, 'index1.html', {'user_list': user_list})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table> <tr> <td>ID</td> <td>用户名</td> <td>详细</td> </tr> {% for item in user_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.username }}</td> <td> <a href="/cmdb/detail/{{ item.id }}">查看详细</a> </td> </tr> {% endfor %} </table> </body> </html>
效果如下:
2.自定义标签方法
自定义标签目录名必须为templatetags, 否则django无法识别,分两步实现:
1、创建指定文件,名称不能改 templatetags
2、创建任意 .py 文件,如:mytag.py
# 必须不变 register = template.Library() # 创建函数 @register.filter def f1(value): value + "666"
3、在html模版的头部执行
{% load mytag %}
4、html代码
k1 = 'VVV' {{k1}} => vvv {{k1|f1}} => vvv666 ##将k1通过管道传给f1函数
5、 settings.py 中注册app
如下图:
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,arg):
##filter只能传一个参数,可以使用html中的if语句
return value + "666" + arg
@register.simple_tag
def f2(s1,s2,s3,s4):
#simplet tag 不支持html中的if语句
return s1 + s2 + s3 + s4
@register.filter
def f3(value):
##filter支持if语句
if value == 'VVV':
return True
return False
def template(request):
return render(request,
'template.html',
{'k1':'vvvv','k2':[11,22,33],'k3':{'nid':12,'name':'Jason'}}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {% load mytag %} </head> <body> {{ k1 }} {{ k1.1 }} {{ k1.name }} {% for item in k2 %} <p>{{ item }},{{ forloop.counter }},{{ forloop.counter0 }},{{ forloop.revcounter }},{{ forloop.first }},{{ forloop.last }}</p> {% endfor %} {% if k1 == 'vvvv' %} <h1>V1</h1> {% elif k1 == 'v2' %} <h1>V2</h1> {% else %} <h1>7777</h1> {% endif %} {% if k1|f3 %} <h1>True</h1> {% else %} <h1>False</h1> {% endif %} {{ k1 }} {{ k1|lower }} {{ k1|f1:"jason"}} <br> {% f2 1 2 3 4 %} </body> </html>
需要注意的tip:
1.filter
限制:传参
支持:模版语言的 if 条件
2.simple_tag
不支持:模版语言的 if 条件
3.模板的继承
首先了解下模板是什么概念?首先已博客园为例:
看下面的图片,在点击首页、精华、候选、新闻、管住、我评、我赞的时候 上面、左侧的红色框体都没有变,变得是中间的内容是怎么实现的呢?就是通过母版来实现的
我们创建一个母版 - 子版去继承母版就可以了,子版里是变化的内容即可。
详见下面的例子
1.母版:layout.html
提别提醒:母版最多允许出现一个母版(可以写多个,但是建议不要写多个)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="..." /> <style> .pg-header{ height: 48px; background-color: cadetblue; } .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: aquamarine; color: white; } </style> {% block css %}{% endblock %}#子模板替换的部分 </head> <body> <div class="pg-header"> 后台系统V1 </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> </ul> </div> <div class="body-content"> {% block body %}{% endblock %} #此处为子模板替换的部分 </div> </div> <div class="pg-footer"></div> <script src="xxx"></script> {% block js %}{% endblock %} </body> </html>
2.子模板
需要在HTML头部以如下的方式导入母版,有点类似Python导入模块的方式,extends 集成那个模板 ,在加一个block content 来书写变化的内容。
{% extends '母板html文件名' %}
{% block 名称 %} 具体子页面的内容... {% endblock %}
实例如下:
{% extends 'layout.html' %} {% block css %} <style></style> {% endblock %} {% block body %} <ul> {% for item in user_list %} <li>{{ item.username }},{{ item.salary }}</li> {% endfor %} </ul> {% endblock %} {% block js %} <script> document.getElementById('userinfo').className = 'active'; </script> {% endblock %}
3.导入标签
如何在html中导入我们想导入的别人的或定制的标签呢,答案是include方法;
son.html:
<form> <input /> <input /> <input /> <input /> </form>
include.htm:
{% extends 'master/layout.html' %} {% block body %} <table> {% for item in assets_list %} <tr> <td>{{ item.hostname }}</td> <td>{{ item.port }}</td> </tr> {% endfor %} </table> {% include 'include/son.html' %} {% include 'include/son.html' %} {% include 'include/son.html' %} {% include 'include/son.html' %} {% include 'include/son.html' %} {% include 'include/son.html' %} <h3></h3> {% endblock %} {% block js %} <script> document.getElementById('assets').className = 'active'; </script> {% endblock %}
效果如下:
以后比如某些公共的模块可以使用include的方式导入!很方便
4.Django静态文件配置
把所有的静态都放在static目录下,比如:css、js、imgs、等
配置引入static目录,在settings里,否则无法使用static目录下的静态文件,因为他找不到路径!的需要告诉django
STATIC_URL = '/ff/' #可以自己制定,html引用时要加入此前缀 STATICFILES_DIRS = ( os.path.join(BASE_DIR,'statics'), )
静态文件目录如下:
html引用方式如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/ff/style/style.css"> {# 然后在模板里,我们也会写一个block,如果子版里有需要使用自己的css样式可以自己定义#} {% block css %} {% endblock %} </head> <body> <div class="header"><h1>LOGO</h1></div> <div class="body"> <div class="menu">左侧菜单</div> <div class="content"> {#可变的子版内容,这个content和class content无关#} {% block content %} {% endblock %} </div> </div> {# 公共的js写到母版中,如果某一个模板里使用自己的js,在写一个block即可#} {% block js %} {% endblock %} </body> </html>
注:在模板里引入了相应的css和js之后,子版里是默认继承的。如果某个子版想独立使用它自己的js,我们可以通过:{% block css %} {% endblock %} || {% block js %} {% endblock %}来定义!
登录注册实例
1.url
在mysite 这个project下的urls定义路由如下
url(r'^app01/',include('app01.urls')),
在cmdb这个app中urls定义路由如下:
from django.conf.urls import url from django.contrib import admin from cmdb import views urlpatterns = [ url(r'^register/', views.register), url(r'^login/',views.login), ]
views函数定义如下:
def login(request): return render(request,'login.html')
html中form表单如何提交的呢?
<form class="form-horizontal" action="/login/" method="post">
提交到在form表单中的action里定义:这里的/login/是URL,当咱们访问URL的时候回给执行咱们定义的函数,前面和后面都要有/ 并且使用方法为post
咱们访问的时候是使用的GET方式,当咱们提交的时候使用的是post请求!我们就可以判断!
def login(request): #如果是GET请求 #如果是POST,检查用户输入 #print request.method 来查看用户是通过什么方式请求的 #还有个问题:当你POST的时候,会出现问题,现在临时解决方法是:在seetings里注释掉 ''' MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 注释掉这一行 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ''' if request.method == 'POST': input_email = request.POST['email'] input_pwd = request.POST['pwd'] if input_email == 'jason' and input_pwd == '123': #当登录成功后给它跳转,这里需要一个模块from django.shortcuts import redirect #成功后跳转到指定网址 return redirect('http://www.baidu.com') else: #如果没有成功,需要在页面告诉用户用户名和密码错误. return render(request,'login.html',{'status':'用户名或密码错误'}) #通过模板语言,来在login.html中添加一个status的替换告诉用户<span>{{ status }}</span> return render(request,'login.html')
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> <!--指定告诉ID用高版本的解析--> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <!-- Bootstrap --> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.4-dist/css/bootstrap.min.css"> </head> <body> <div style=" 200px;"> <form class="form-horizontal" action="/login/" method="post"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">Email</label> <div class="col-sm-10"> <input type="email" class="form-control" name="email" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">Password</label> <div class="col-sm-10"> <input type="password" class="form-control" name="pwd" placeholder="Password"> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">Sign in</button> <span style="color: red;">{{ status }}</span> </div> </div> </form> </div> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <script src="/static/js/jquery-2.2.1.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="/static/plugins/bootstrap-3.3.4-dist/js/bootstrap.min.js"></script> </body> </html>
如何利用JQuery封装的ajax实现提交数据到后台呢,方法如下:
a. 下载Jquery
b. 放置在static目录下
c. setting配置
c. html导入
$.ajax({ url: '/index/', type: 'POST', data: {'username': 'alex','password': '123'}, success: function(data){ // 当后台return之后,该函数自动执行 // data就是后台返回的数据 } })
此例子中ajax非Jquery独有,详细说明详见:http://www.cnblogs.com/wupeiqi/articles/5703697.html