Django基础2

一.Django的路由层(URLconf)
1.简单的路由配置
urlpatterns = [
url(r'^admin/$', admin.site.urls),
# 在urls中用正则捕获待匹配的路径,直行第二项的视图函数,并在app01中的views中添加视图函数
# def index(request):
# return HttpResponse("ok")
url(r'^index/$',views.index),
]
2.无名分组
(1)获取年份
# 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
url(r'^year/(\d{4})/$',views.year),#year_archive(request,2006)

def year(request,year):
date=datetime.datetime.now()
return HttpResponse('year:%s' % (year))
(2)获取年月
url(r'^year/(\d{4})/(\d{2})/$',views.year_month),#year_month(request,2006,12)

def year_month(request,year,mouth):
date = datetime.datetime.now()
return HttpResponse('year:%s mouth:%s' % (year,mouth))
注:
不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义
3.有名分组
获取年月
url(r'^year/(?P<year>\d{4})/(?P<mouth>\d{2})/$',views.year_month),#year_month(request,year=2006,mouth=12)

def year_month(request,year,mouth):
date = datetime.datetime.now()
return HttpResponse('year:%s mouth:%s' % (year,mouth))
给正则表达式中的每一个括号起一个名字,视图函数在使用时,
只能使用该名字,视图函数的参数由位置参数变成了关键字参数
4.分发
项目的url中
url(r'^app01/',include('app01.urls')),
url(r'^app02/',include('app02.urls')),
注:
此时不要忘了引入include
from django.conf.urls import include
app01中
from django.conf.urls import url,include
from app01 import views
urlpatterns=[
url(r'^aaa/$',views.aaa),
url(r'^bbb/$',views.bbb),
]
app02中
from django.conf.urls import url,include
from app02 import views
urlpatterns=[
url(r'^ccc/$',views.ccc),
url(r'^ddd/$',views.ddd),
]
app01的views中
def aaa(request):
return HttpResponse('aaa')
def bbb(request):
return HttpResponse('bbb')
app02的views中
def ccc(request):
return HttpResponse('ccc')
def ddd(request):
return HttpResponse('ddd')
5.反向解析
当程序进入aaa分支
urlpatterns=[
url(r'^aaa/$',views.aaa),
url(r'^bbb/$',views.bbb,name='xxx'),
]
进入aaa的视图函数
def aaa(request):
return render(request,'aaa.html')
获取aaa.html页面
表单提交到别名为xxx的地址中,返回上上层中,找到别名为xxx的地址,并进入
<form action="{% url 'xxx' %}">
<input type="text" name="content">
<input type="submit">
</form>
进入bbb视图函数
def bbb(request):
return HttpResponse('bbb')
注:反向解析的作用是,如果项目完成后,需要修改某个地址,只需要修改最初的一出,不用大量修改
二.Django的视图层
视图层:请求对象(request)和响应对象(HttpResponse)
1.request属性
def index(request):
print(request.method) #请求方式 GET
print(request.path) #请求路径 /index/
print(request.POST) #post请求的数据 字典格式 <QueryDict: {}>
print(request.GET) #get请求的数据 字典格式 <QueryDict: {}>
print(request.META) #请求头 ...
print(request.get_full_path()) #返回 path,如果可以将加上查询字符串。/index/
print(request.is_ajax()) #如果请求是通过XMLHttpRequest 发起的,则返回True, False
return HttpResponse('ok')
2.HttpResponse对象
(1)HttpResponse()
括号中可以是一个普通字符串,也可以是一个标签字符串
(2)render()
a.读取文件字符串
b.嵌入变量
在要执行的视图函数中动态改变变量
def index(request):
apple = '苹果'
return render(request,'start.html',{'apple':apple})
在对应的HTML文件中动态渲染变量
<body>
<p>{{ apple }}</p>
</body>
(3)redirect()重定向
在浏览器进入此地址时,让浏览器重新发一个请求,请求的地址时redirect返回的地址
def cdx(request):
return redirect('/index/')
三.Django的模板层
1.渲染变量{{ }}
(1)深度查询
当调用视图函数中的index方法时
def index(request):
import datetime
name='shy'
age=20
hobby=['eat','drink']
date=datetime.datetime.now()
class Foo():
def __init__(self,name,age):
self.name=name
self.age=age
# 此时的方法只能是无参的方法
def run(self):
return 'running'
a1=Foo('aaa',1)
a2=Foo('bbb',2)
a3=Foo('ccc',3)
list=[a1,a2,a3]
# locals()可代替传所有参数
return render(request,'index.html',{'name':name,'age':age,'hobby':hobby,'date':date,'list':list})
被盗调用的index.HTML
<body>
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ hobby.1}}</p>
<p>{{ date }}</p>
<p>{{ list.0.name }}</p>
<p>{{ list.0.run }}</p>
</body>
(2)过滤器
date:日期过滤器
语法:{{ var|过滤器名字:参数 }}
<p>{{ date|date:'Y:m:d' }}</p>
作用:可以将日期转换成想要的格式

default:如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值
语法:{{ value|default:'默认值'}}
<p>{{ list|default:'没有符合条件的书籍' }}</p>
length:返回值的长度。它对字符串和列表都起作用
语法:{{ value|length }}
filesizeformat:将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。
语法:{{ value|filesizeformat }}
slice:切割字符串
语法:{{ value|slice:'1;3' }}
truncatechars:如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾
语法:{{ value|truncatechars:9 }}
注:在给定的数目-3处阶段,留三个位置给...
truncatewords :如果字符串字符多于指定的单词数量,那么会被截断
语法:{{ value|truncatewords:9 }}
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。
但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,
后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,
如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,
如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
value="<a href="">点击</a>"
{{ value|safe}}
2.渲染标签{% %}
for 标签
{% for foo in list %}
<p>{{ foo.age }}</p>
{% endfor %}
注:不能像python一样break

forloop辅助功能
forloop.counter 序号从1开始
forloop.counter0 序号从0开始
forloop.revcounter 序号倒序,最后一个是1
forloop.revcounter0 序号倒序,最后一个是0
forloop.first 判断是不是第一个
forloop.last 判断是不是最后一个
if标签
{% if age > 18 %}
<p>100</p>
{% elif age <= 18 %}
<p>{{ age }}</p>
{% endif %}
注:判断的符号两边要有空格

with标签(相当于起了一个简短的名字,在小区域内可以使用别名)
{% with list.0.name as a %}
<p>{{ a }}</p>
{% endwith %}

csrf_token
在form表单中的任意一个位置加一个{{ csrf_token }}即可解决form表单提交时的forbition
实际上是偷偷加了一个
<input type='hidden' name='scrfmiddlewaretoken' value='hhasgd7ew43jerf8efu'>
做了一个通行证,用于拦截不通过get请求就发post请求的人

3.模板继承 (extend)
在视图函数中
def index(request):
return render(request,"index.html")

def order(request):
order_list=["订单1","订单2","订单3"]
return render(request,"order.html",{"order_list":order_list})

def shopping_list(request):
shopping_list=["苹果","香蕉","苹果"]
return render(request,"shopping_list.html",{"shopping_list":shopping_list})

在母版中
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
{# block标签标示:子模版可能会覆盖掉模版中的这些位置。#}
{% block title %}
<title>Title</title>
{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
*{
margin: 0;
padding: 0;
}
.header{
width: 100%;
height: 50px;


}
</style>
</head>
<body>
<div class="header"></div>

<div class="container">
<div class="row">
<div class="col-md-3">
{% block menu %}
<div class="panel panel-success">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body">
<p><a href="/index/">首页</a></p>
<p><a href="/order/">订单</a></p>
<p> <a href="/shopping_list/">商品列表</a></p>
</div>
</div>
{% endblock %}
</div>
<div class="col-md-9">
{% block content %}
<h3>welcome!</h3>
{% endblock content%}
</div>
</div>
</div>
</body>
</html>
在index页面中
{#表示继承的模板,一定要写在以下内容的前面,否则会出错#}
{% extends "base.html" %}

{% block content %}
super的意思是既显示母版的内容,又显示这个内容
{{ block.super }}

<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}

{% block title %}
<title>首页</title>
{% endblock %}
在order页面中
{% extends "base.html" %}

{% block content %}
<h3>订单列表</h3>
{% for order in order_list %}
<p>{{ order }}</p>
{% endfor %}
{% endblock %}

{% block title %}
<title>订单</title>
{% endblock %}
在shopping_list页面中
{% extends "base.html" %}

每个模板都有自己的题目,所以顺序可以打乱
{% block title %}
<title>商品列表</title>
{% endblock %}

{% block content %}
<h3>商品列表</h3>
{% for foo in shopping_list %}
<p>{{ foo }}</p>
{% endfor %}
{% endblock %}


posted @ 2018-10-23 09:43  ★行者尚★  阅读(145)  评论(0编辑  收藏  举报