Django框架中的视图和模板

视图views

django中的视图就是用来定义函数来处理一些逻辑的核心地方。

django中通过urls来建立路径跟views中的视图函数的映射关系。

urls中的映射关系

 '''
    
    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
]


参数说明:

    一个正则表达式字符串
    一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    可选的要传递给视图函数的默认参数(字典形式)
    一个可选的name参数

    '''
注意:
    1 一旦匹配成功则不再继续
    2 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
    3 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
    4 每个正则表达式前面的'r' 是可选的但是建议加上。

分组

正则表达式还可以进行分组,加括号进行分组,分组之后就会把分组的内容当做参数传给对应的视图函数。

无名分组就是(位置传参)。

有名分组就是(关键字传参)。

视图函数

下面是一个返回当前日期和时间作为HTML文档的视图:

 
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)
 

让我们逐行阅读上面的代码:

  • 首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。

  • 接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request

    注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够精确地反映出它的功能。

  • 这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。

request参数的属性及方法:

'''
path:       请求页面的全路径,不包括域名

method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如

               if  req.method=="GET":

                         do_something()

               elif req.method=="POST":

                         do_something_else()

GET:         包含所有HTTP GET参数的类字典对象

POST:       包含所有HTTP POST参数的类字典对象

COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。

FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中
             name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:

             filename:      上传文件名,用字符串表示
             content_type:   上传文件的Content Type
             content:       上传文件的原始内容


user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
             没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
             可以通过user的is_authenticated()方法来辨别用户是否登陆:
             if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
             时该属性才可用

session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

'''
方法:

1
get_full_path()
注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:

1
request.POST.getlist("hobby")

render函数:

render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

参数:
     request: 用于生成响应的请求对象。

     template_name:要使用的模板的完整名称,可选的参数

     context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

     content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

     status:响应的状态码。默认为200。

redirect函数:

参数可以是:

  • 一个模型:将调用模型的get_absolute_url() 函数
  • 一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
  • 一个绝对的或相对的URL,将原封不动的作为重定向的位置。

默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

示例:

你可以用多种方式使用redirect() 函数。

传递一个对象

将调用get_absolute_url() 方法来获取重定向的URL:

1
2
3
4
5
6
from django.shortcuts import redirect
 
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object)

传递一个视图的名称

可以带有位置参数和关键字参数;将使用reverse() 方法反向解析URL: 

1
2
3
def my_view(request):
    ...
    return redirect('some-view-name', foo='bar')

传递要重定向的一个硬编码的URL

1
2
3
def my_view(request):
    ...
    return redirect('/some/url/')

也可以是一个完整的URL:

1
2
3
def my_view(request):
    ...
    return redirect('http://example.com/')

默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:

1
2
3
4
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object, permanent=True)  

模板层(template)

模板就是html代码加模板语法

模板语法有两种: { {   } }  跟 { %    % }

在 Django 模板中遍历复杂数据结构的关键是句点字符  .

语法:  

1
{{var_name}}

views:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def index(request):
    import datetime
    s="hello"
    l=[111,222,333]    # 列表
    dic={"name":"yuan","age":18}  # 字典
    date = datetime.date(199352)   # 日期对象
 
    class Person(object):
        def __init__(self,name):
            self.name=name
 
    person_w=Person("www")  # 自定义类对象
    person_x=Person("xxx")
    person_p=Person("ppp")
 
    person_list=[person_w,person_x,person_p]
 
 
    return render(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})  

template: 

1
2
3
4
5
6
<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<h4>类对象列表:{{ person_list.0.name }}</h4>

注意:句点符也可以用来引用对象的方法(无参数方法)

1
<h4>字典:{{ dic.name.upper }}</h4>

模板之过滤器

语法:

1
{{obj|filter__name:param}}

default

如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:

1
{{ value|default:"nothing" }}

length

返回值的长度。它对字符串和列表都起作用。例如:

1
{{ value|length }}

如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。

filesizeformat

将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB''4.1 MB''102 bytes', 等等)。例如:

1
{{ value|filesizeformat }}

如果 value 是 123456789,输出将会是 117.7 MB  

date

如果 value=datetime.datetime.now()

1
{{ value|date:"Y-m-d" }}  

slice

如果 value="hello world"

1
{{ value|slice:"2:-1" }}

truncatechars

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

参数:要截断的字符数

例如:

1
{{ value|truncatechars:9 }}

如果value“Joel 是 >,输出将为“Joel i ...”

safe

Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

1
value="<a href="">点击</a>"
1
{{ value|safe}}

这里简单介绍一些常用的模板的过滤器,

模板之标签 

标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。

一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

for标签

遍历每一个元素:

{% for person in person_list %}
    <p>{{ person.name }}</p>
{% endfor %}

可以利用{% for obj in list reversed %}反向完成循环。

遍历一个字典:

{% for key,val in dic.items %}
    <p>{{ key }}:{{ val }}</p>
{% endfor %}

注:循环序号可以通过{{forloop}}显示  

for ... empty

for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

if 标签

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

复制代码
{% if num > 100 or num < 0 %}
    <p>无效</p>
{% elif num > 80 and num < 100 %}
    <p>优秀</p>
{% else %}
    <p>凑活吧</p>
{% endif %}
复制代码

with

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

例如:

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

csrf_token

这个标签用于跨站请求伪造保护

自定义标签和过滤器

步骤:
1 在settings中的INSTALLED_APPS,是否有当前应用
2 如果有,在应用中创建一个templatetags
3 在templatetags中创建py文件:mytag.py
4 在mytag.py中:
引入:
from django import template
from django.utils.safestring import mark_safe

register = template.Library() #register的名字是固定的,不可改变

5 定义过滤器和标签
@register.filter
def multi(x,y):
return x*y

@register.simple_tag
def multiTag(x,y,z):
return x*y*z
6 在引用模板中导入:{% load myTag %}
7 调用:
过滤器: {{var|filter_name:参数}} # 参数只能是一个
标签: {% simple_tag 参数1 参数2 ... %}
对比过滤器与自定义标签的使用:
过滤器函数的参数只能有两个,自定义标签无参数限制
过滤器可以与逻辑标签共同使用,比如if标签。自定义标签不可以。

模板继承 (extends)

模板继承语法:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>
先创建母版html文件

母版就相当于一个网页的骨架,其他html文件要是继承了母版网页,就可以替换block里面的内容,如果不更改就默认继承母版里面的

{% extends "base.html" %}
 
{% block title %}My amazing blog{% endblock %}
 
{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
继承母版网页中的内容
如果想继续在母版网页block后面追加而不是替换,就可以用{{ block.super }} 。
原文地址:https://www.cnblogs.com/wxp5257/p/7725143.html