11.26

视图层

视图函数必须有一个返回值,并且返回值的数据类型必须是HTTPresponse对象

HttpResponse

响应对象,响应可以使任何形式的内容,比如一个html文件的内容,一个重定向,一个404错误,一个xml文档,或者一张图片等。所以无论视图本身包含什么逻辑,都要返回响应。响应对象主要有三种形式:HTTPResponse、render、redirect

使用方式from django.shortcuts import HttpResponse,render,redirect

HttpResponse()

括号内直接跟一个具体的字符串作为响应体

render()

render(request,template_name[,context])
#参数:
#1、request:用于生成响应的请求对象,固定必须传入的第一个参数
#2、template_name:要是用的模板的完整名称,必须传入,render默认会去templates目录下查找模板文件
#3、context:可选参数,可以传入一个字典用来替换模板文件中的变量

综上,render的功能可以总结为:根据给定字典渲染模板文件,并返回一个渲染后的HttpResponse对象

redirect()

#返回重定向信息
def my_view(request):
	...
	return redirect('/some/url/')
	
#重定向的地址也可以是一个完整的URL
def my_view(request):
	...
	return redirect('http://www.baidu.com/')

JsonResponse

向前端返回一个json格式字符串

前后端分离

前后端数据交互的方式:通常情况下前后端数据交互采用的都是json的字符串(字典)

后端只需要写好相应的url,前端访问这个url

前后端序列化反序列化的方法

后端

json.dumps/json.loads

js前端

json.stringify/json.parse

向前端返回一个json格式字符串的两种方式

方式一

import json
def my_view(request):
    data=['aaa','bbb']
    return HttpResponse(json.dumps(data))

方式二

from django.http import JsonResponse

def my_view(request):
    data=['aaa','bbb']
    return JsonResponse(data,safe=False)
# 默认safa=True代表只能序列化字典对象,safe=False代表可以序列化字典以外的对象

FBV和CBV

django的视图层由这两种形式构成

  1. FBV基于函数的视图(Function base view)
  2. CBV基于类的视图(Class base view)

CBV

需要导入from django.views import view

创建的类必须继承view

CBV可以根据请求方法的不同,自动执行对应的方法

from django.views import View

class MyLogin(View):
	def get(self,request):
		print('我是MyLogin里面的get方法')
		return render(request,'login.html')
	def post(self,request):
		print('我是MyLogin里面的post方法')
		return HttpResponse('post')

URLS.PY的不同

#FBV 写法 路由>>视图函数内存地址
url(r'^index/',views.index)

#CBV写法
url(r'^login/',views.MyLogin.as_view())
#as_view 项目一启动,自动执行as_view方法
#CBV 在路由匹配上,本质还是FBV

采用CBV可以引入面向对象的思想对数据进行更高程度的封装

CBV源码

  1. dispatch函数中,利用反射去自己定义的类的对象中查找get属性或者是方法 getattr(obj,'get')
  2. 在对象中找不到就到类里面找
  3. 找到了就return handler调用get方法
  4. post相同

给CBV加装饰器

推荐使用内置模块

from django.utils.decorators import method_decorator

方法:

  1. 直接在函数名头上加(@装饰器名)(推荐写法:method_decorator(装饰器名))
  2. 可以指定给谁装(@method_decorator(装饰器名,name='被装饰函数名')

如果想在视图函数执行之前做一些操作,可以在CBV中定义dispatch方法来拦截

def dispatch(self,request,*args,**kwargs):
    return super().dispatch(request,*args,**kwargs)

模板层

将Python嵌入到HTMl中

HTML代码+模板语法

def current_time(req):
    # ================================原始的视图函数
    # import datetime
    # now=datetime.datetime.now()
    # html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now
    # return HttpResponse(html)
    
    #另一种写法(推荐)
    import datetime
    now=datetime.datetime.now()
    return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})

模板语法的两种书写格式

变量相关:{{ }}

逻辑相关:{% %}

模板传值

python基本数据类型全部支持传值

给HTML页面传递函数名的时候,模板语法会自动加括号调用该函数,并将函数的返回值当做展示依据,模板语法不支持函数传参

给HTML页面传类名的时候,模板语法也会自动加括号实例化产生对象。

总结:只要能加括号调用的,传递到html页面上都会自动加括号调用

过滤器

default

如果变量是false或者为空,则使用给定的默认值。
{{ value|default:'nothing'}}

length

返回值的长度,对字符串和列表都起作用

{{ value|length}} 如果value是[1,2,3,4],那么输出是4

filesizeformat

将值格式化成'人类可读的'文件尺寸。例如:
{{1024|filesizeformat}}  输出为1kb

date

如果value=datetime.datetime.now()

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

slice

切片

{{ name|slice:'0:3:3' }}

truncatechars

如果字符串多余指定字符数量,多余会被截断,替换成("...")结尾。

{{ value|truncatechars:9}}

safe

Django模板为了安全默认会对HTML标签和js等语法标签进行转义,有时候我们不希望这些元素被转义,可以通过设置过滤器。

script="'<script>alert(111)</script>"
{{ script|safe }}

注意:过滤器参数包含空格,必须用引号包起来

模板之标签

标签是为了在模板中完成一些特殊功能,语法为{%标签名%},一些标签还需要搭配结束标签{%endtag%}

常用标签

for标签

{% for person in person_list %}
    <p>{{ person }}</p>
{% end for%}
#遍历每一个元素

Django为for标签内置了一些属性

forloop.counter:循环的当前索引值,从1开始计数;常用于生成一个表格或者列表的序号!
forloop.counter0:循环的当前索引值,从0开始计数;
forloop.revcounter: 循环结束的次数(从1开始)
forloop.revcounter0 循环结束的次数(从0开始)
forloop.first:判断当前是否循环的第一次,是的话,该变量的值为True。我们经常要为第一行加点特殊的对待,就用得上这个判断了,结合if。
forloop.last:如果这是最后一次循环,则为真
forloop.parentloop:对于嵌套循环,返回父循环所在的循环次数。某些场景下,这是个大杀器,能解决你很多头疼的问题。
for...empty
for标签带有一个可选的{% empty %}从句,在给出的组是空的或者没有被找到时执行的操作

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 %}

注:在if标签中使用括号是错误的语法,这点不同于Python if语句支持 ,优先级可以使用if嵌套。if支持and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

with

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

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

自定义标签和过滤器

通过python代码自定义标签和过滤器,然后使用{%load%}标签

必须要先有三步准备

  1. 在应用名下新建一个名字必须叫templatetags的文件夹

  2. 在该文件夹内新建一个任意名称的py文件

  3. 在该py文件中必须先写下两句代码

    from django.template import Library

    register=Library()

之后就可以用register来自定义过滤器和标签

使用自定义的过滤器

需要先再html页面上加载

  • 自定义过滤器和默认的过滤器一样,最多只能接收两个参数

    @register.filter(name='aaa')
    def index(a,b):
        return a+b
    
    #使用方式:
    {% load mytag %}
    {{ 1|aaa:1  }}
    {{ 1|aaa:100  }}
    
  • 自定义标签,可以接收任意多个参数

    @register.simple_tag(name='mytag')
    def mytag(a,b,c,d):
        return '%s?%s?%s?%s'%(a,b,c,d)
    
    #使用方法:
    #参数与参数之间必须用空格隔开
    {% load mytag %}
    {% mytag 'a' 'b' 'c' 'd' %}
    {% load mytag %}
    
  • 自定义inclusion_ tag

    是一个函数 能够接受外界传入的参数 然后传递给一个html页面
    页面上获取数据 渲染 完成之后
    将渲染好的页面 放到调用inclusion_tag的地方
    @register.inclusion_tag('mytag.html',name='xxx')
    def index(n):
        l=[]
        for i in range(n):
            l.append('第%s项'%i)
        return locals() # 将l直接传递给mytag.html页面
    
    #使用方法:
    #当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag
    {% load mytag %}
    {% xxx 5 %}
    

注意:自定义的过滤器可以在逻辑语句使用 而自定义的标签不可以

模板的继承

需要事先在要使用的页面上划定区域,之后继承的时候就能使用这个区域

在页面上利用block划定想改的区域

{% block content%}
	...
{% endblock %}

继承之后就可以通过名字找到对应的区域进行修改

{% extends 'home.html' %}
{% block content%}
	修改模板中content区域内容
{% endblock %}

建议:一个模板页面至少有三块区域

	1. css区域
    		2. html代码区域,可以设置多个block
        		3. js区域
{% extends 'home.html' %}

{% block css %}
<style>
	p {
		color: green;
	}
</style>
{% endblock %}

{% block content %}
<p>login页面</p>
{% endblock %}


{% block js %}
<script>
	alert('login')
</script>
{% endblock %}

{{block.super}}:在子页面上继续沿用父页面的内容

模板的继承

  1. 在要继承的页面上通过block划定要改的区域
  2. 在子页面上继承extends
  3. 利用block,选择要修改的内容区域

模板的导入

将html页面当做木块直接导入

{% include 'xxx.html'}

posted @ 2019-11-26 21:06  mqb11  阅读(166)  评论(0编辑  收藏  举报