Django之框架,视图,模板

Posted maojiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之框架,视图,模板相关的知识,希望对你有一定的参考价值。

day65 2018-06-15

 

1. Django框架详细介绍

 

MVC框架和MTV框架(了解)

Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架

 

DjangoMTV模式

       Model(模型):负责业务对象与数据库的对象(ORM)

       Template(模版):负责如何把页面展示给用户

       View(视图):负责业务逻辑,并在适当的时候调用ModelTemplate

此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的ModelTemplate

app

        

命令行创建

python manage.py startapp app01

技术分享图片

技术分享图片

 

下面围绕这几个点说

视图系统

1. 视图 views.py

 

1. FBV(function base view) 基于函数的视图

抛出一个问题:

函数的装饰器能不能直接用来装饰类中的方法

 

2. CBV(class base view) FBV(function base view)基于类

    

注意:

使用CBV时,urls.py中也做对应的修改:

# urls.py
url(r‘^add_class/$‘, views.AddClass.as_view()),

 

Request对象和Response对象

request对象

当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。

Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

 

官方文档

请求相关的常用值

·        path_info     返回用户访问url,不包括域名

·        method        请求中使用的HTTP方法的字符串表示,全大写表示。

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

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

·        body            请求体,byte类型 request.POST的数据就是从body里面提取到的

属性

所有的属性应该被认为是只读的,除非另有说明。

    

技术分享图片
3. 上传文件的注意事项:

1. 如果有上传文件,views.py中应该从request.FILES中取上传的文件对象

2. 如果有上传文件,html文件中的form表单一定要加 enctype="multipart/form-data"

 

file_obj = request.FILES.get("touxiang")  # 拿到上传文件对象

file_name = file_obj.name  # 拿到文件名

with open(file_name, "wb") as f:  # 在本地新建一个同名文件

for line in file_obj.chunks():  # 从上传的文件对象中一点一点读取数据

f.write(line)  # 写到新建的文件中

 return HttpResponse("上传OK")

 
View Code

 

 

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

request.POST.getlist("hobby")

 

使用

技术分享图片
传递字符串

from django.http import HttpResponse
response = HttpResponse("Here‘s the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")

设置或删除响应头信息

response = HttpResponse()
response[Content-Type] = text/html; charset=UTF-8
del response[Content-Type]
View Code

 

Response对象

与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse

HttpResponse类位于django.http模块中

使用

 

技术分享图片
传递字符串

from django.http import HttpResponse
response = HttpResponse("Here‘s the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")

设置或删除响应头信息

response = HttpResponse()
response[Content-Type] = text/html; charset=UTF-8
del response[Content-Type]
View Code

属性

HttpResponse.content:响应内容

HttpResponse.charset:响应内容的编码

HttpResponse.status_code:响应的状态码

 

4. JsonResponse

Django封装的一个专门用来返回JSON格式数据的方法()

 

from django.http import JsonResponse

 

JsonResponse(字典)(默认传字典)

JsonResponse(列表,safe=False)

默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

response = JsonResponse([1, 2, 3], safe=False)

 

补充一个知识点

python

技术分享图片

 

                   技术分享图片

                                     技术分享图片

 

我们在开发中通常需要清除浏览器缓存

 

 

Django shortcut functions

renderredirect

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

render()

技术分享图片

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

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

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

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

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

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

 

useing: 用于加载模板的模板引擎的名称。

 

一个简单的例子:

from django.shortcuts import render

def my_view(request):
    # 视图的代码写在这里
    return render(request, myapp/index.html, {foo: bar})

上面的代码等于:

 

from django.http import HttpResponse
from django.template import loader

def my_view(request):
    # 视图代码写在这里
    t = loader.get_template(myapp/index.html)
    c = {foo: bar}
    return HttpResponse(t.render(c, request))
View Code

 

redirect()

参数可以是:

·        一个模型:将调用模型的get_absolute_url() 函数

·        一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称

·        一个绝对的或相对的URL,将原封不动的作为重定向的位置。

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

示例:

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

 

技术分享图片
传递一个具体的ORM对象(了解即可)

将调用具体ORM对象的get_absolute_url() 方法来获取重定向的URL:



from django.shortcuts import redirect

 
def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object)



传递一个视图的名称

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

传递要重定向到的一个具体的网址

def my_view(request):
    ...
    return redirect(/some/url/)

当然也可以是一个完整的网址

def my_view(request):
    ...
    return redirect(http://example.com/)

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

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

扩展阅读: 

临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。

A页面临时重定向到B页面,那搜索引擎收录的就是A页面。

A页面永久重定向到B页面,那搜索引擎收录的就是B页面。
View Code

 

 

模板

2. 模板语言(重要)

 

1. 目前已经学到的模板语言内容

1. {{变量}}

2. {% 逻辑操作 %}

1. for循环

{% for i in list %}

{{ i }}

{% endfor %}

 

forloop.counter

forloop.counter0

 

forloop.last

 

{% empty %}

 

2. if判断

{% if 条件 %}

条件成立要做的事儿

{% else %}

条件不成立要做的事儿

{% endif %}

3. 逻辑判断

1. in 判断

2. == 判断

 

1. 模板语言变量相关

1. 字典的key对应的值

{{ dic.key}}

2. 列表按索引取值

{{ list.1 }}

3. 对象的属性和方法

{{ obj.name }}

{{ obj.dream }}  --> 方法不要加括号

 

2. Filters (对变量做一些额外的操作)

1. 内置的filter

 

语法: {{ value|filter_name:参数 }}

          

default

{{ value|default: "nothing"}}

如果value值没传的话就显示nothing

length

{{ value|length }}

‘|‘左右没有空格没有空格没有空格

返回value的长度,如 value=[‘a‘, ‘b‘, ‘c‘, ‘d‘]的话,就显示4.

filesizeformat

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

{{ value|filesizeformat }}

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

slice

切片

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

date

格式化

{{ value|date:"Y-m-d H:i:s"}}

safe

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

比如:

value = "<a href=‘#‘>点我</a>"

{{ value|safe}}

 

2. 自定义的filter

 

1. app下面新建一个Python package,包名必须叫 templatetags

2. 在上面的包中新建一个python文件,里面定义函数,并且注册到django的模板语言

from django import template

# 生成一个用于注册自定义filter方法的实例

register = template.Library()

 

 

@register.filter(name="sb")

def add_sb(value):

return "{} sb".format(value)

3. 使用自定义的filter方法

{% load py文件名 %}

{{ value|sb }}

3. tags

 

for

<ul>
{% for user in user_list %}
   
<li>{{ user.name }}</li>
{% endfor %}
</ul>

for循环可用的一些参数:

 

Variable

Description

forloop.counter

当前循环的索引值(从1开始)

forloop.counter0

当前循环的索引值(从0开始)

forloop.revcounter

当前循环的倒序索引值(从1开始)

forloop.revcounter0

当前循环的倒序索引值(从0开始)

forloop.first

当前循环是不是第一次循环(布尔值)

forloop.last

当前循环是不是最后一次循环(布尔值)

forloop.parentloop

本层循环的外层循环

for ... empty

<ul>
{% for user in user_list %}
   
<li>{{ user.name }}</li>
{% empty %}
   
<li>空空如也</li>
{% endfor %}
</ul>


if,elifelse

{% if user_list %}
 
用户人数:{{ user_list|length }}
{% elif black_list %}
 
黑名单数:{{ black_list|length }}
{% else %}
 
没有用户
{% endif %}


当然也可以只有ifelse

{% if user_list|length > 5 %}
 
七座豪华SUV
{% else %}
   
黄包车
{% endif %}

if语句支持 and or==><!=<=>=innot inisis not判断。

with

定义一个中间变量

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

 

csrf_token

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

在页面的form表单里面写上{% csrf_token %}

注意事项

1. Django的模板语言不支持连续判断,即不支持以下写法:

{% if a > b > c %}
...
{% endif %}

 

2. Django的模板语言中属性的优先级大于方法

def xx(request):
    d = {
"a": 1, "b": 2, "c": 3, "items": "100"}
   
return render(request, "xx.html", {"data": d})

如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个keyitems并且还有默认的 d.items() 方法,此时在模板语言中:

{{ data.items }}

默认会取ditems key的值。

 

 

4. 母版与继承

1. 定义母版   --> 其他很多页面会用到的共用部分 我们可以提取出来放在单独的一个html文件中

技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Title</title>
  {% block page-css %}
  
  {% endblock %}
</head>
<body>

<h1>这是母板的标题</h1>

{% block page-main %}

{% endblock %}
<h1>母板底部内容</h1>
{% block page-js %}

{% endblock %}
</body>
</html>
View Code

 

注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。

 

2. 在母版中 通过定义不同的 block 等待子页面来替换对应的内容

3. 在子页面中 通过 {% extends ‘base.html ‘%}来继承已经定义好的母版

4. 在子页面中通过 block 来实现自定义页面内容     

通过在母板中使用{% block  xxx %}来定义""

5. 通常会在母版中定义 子页面专用的 page-css page-js 两个块

   一起定义这两个

5.组件

把功能相对独立的html代码 放在一个单独的文件中 作为组件 供其他页面使用

{% include ‘nav.html‘ %}

 


 

 































以上是关于Django之框架,视图,模板的主要内容,如果未能解决你的问题,请参考以下文章

人生苦短,我用python-- Day19 django框架之URL路由系统视图应用模板应用django之orm应用

Django之模板层

Django框架之第二篇

Django框架之第二篇

PythonWeb框架之Django初识

django框架之模板系统