day54-Django视图层、模板层

视图层

HttpResponse

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

render和redirect都继承了HttpResponse

JsonResponse

前后端分离

前后端数据交互采用的都是json的字符串

前端

#js
JSON.stringify()

JSON.parse()

后端

#python
json.dumps()
json.loads()
def index(request):
    user_dic = {'name':'jason好帅哦 我好喜欢~','password':'123'}
    # 如何让json不自动帮你对中文进行转码
    # json_str = json.dumps(user_dic,ensure_ascii=False)
    # return HttpResponse(json_str)
    # return JsonResponse(user_dic,json_dumps_params={'ensure_ascii':False})
    l = [1,2,3,4,5,6,7,]
    # JsonResponse默认是序列化字典用的 如果你想序列化其他数据类型(json模块能够序列化的) 	 # 你要加一个safe参数
	return JsonResponse(l,safe=False)			

FBV和CBV

FBV

FBV是基于函数的视图

def index(request):
	return render(request, 'index.html')
#FBV路由
url(r'^index/',views.index)

CBV

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')
#CBV路由
url(r'^login/',views.MyLogin.as_view())

CBV源码

@classonlymethod
def as_view(cls, **initkwargs):
	def view(request, *args, **kwargs):  # 闭包函数
		self = cls(**initkwargs)  # cls是我们自己写的类 MyLogin  self是我们自己定义的类的对象
        # 在看源码的时候 你一定要把握住一个顺序 对象在查找属性和方法的时候
		# 先从对象自身找 再去产生对象的类中找 再去类的父类中找
		return self.dispatch(request, *args, **kwargs)
	return view
			
			
def dispatch(self, request, *args, **kwargs):
	# Try to dispatch to the right method; if a method doesn't exist,
	# defer to the error handler. Also defer to the error handler if the
	# request method isn't on the approved list.
	# 判断当前请求方式在不在默认的八个方法内
	# 1.先以GET请求为例
	if request.method.lower() in self.http_method_names:
		# 利用反射去我们自己定义类的对象中查找get属性或者是方法  getattr(obj,'get')
		# handler = get方法
		handler = getattr(self, request.method.lower(), 												self.http_method_not_allowed)
	else:
		handler = self.http_method_not_allowed
	return handler(request, *args, **kwargs)  # 调用get方法

CBV装饰器

from django.utils.decorators import method_decorator

# 2.可以指定给谁装
# @method_decorator(outter,name='post')
# @method_decorator(outter,name='dispatch')
class MyLogin(View):
    @method_decorator(outter)
    def dispatch(self, request, *args, **kwargs):  # 如果你想在视图函数执行之前 做一些操作 你可以在你的CBV中定义dispatch方法来拦截

		return super().dispatch(request,*args,**kwargs)
	# @outter  # 1.直接写
	# @method_decorator(outter)  # 1.推荐写法
	def get(self,request):
		print('我是MyLogin里面的get方法')
		return render(request,'login.html')
	# @outter
	def post(self,request):
		print('我是MyLogin里面的post方法')
		time.sleep(1)
		return HttpResponse('post')

模板层

模板语法

书写格式

{{}}		变量相关
{%%}		逻辑相关

模板传值

支持python所有基本数据类型

当给HTML页面传递函数名的时候,模板语法会自动调用该函数,并且将函数的返回值当作展示依据

模板语法不支持函数传参,因此只能传不需要参数的函数

当给HTML传类的时候,也和传函数名一样,只要是能加括号调用的,传递到HTML页面上都会自动调用

过滤器

语法结构:'参数一|参数二'

做多只能传两个参数

前后端取消转义

前端

xxx|safe

后端

from django.utils.safestring import mark_safe
#前端无需判断是否需要转义,直接转义
sss2 = "<h2>我的h2标签</h2>"
res = mark_safe(sss2)	

内置方法

{#<p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>#}
{#<p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>#}
{#<p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>#}

{#<p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>#}

{#<p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>#}
{#<p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>#}

{#<p>截取文本内容(按照空格计算) 截取五个单词 三个点不算 :{{ s1|truncatewords:5 }}</p>#}
			
{#<p>默认情况下 是不会自动帮你转换成前端html标签 防止恶意攻击</p>#}
{#<p>展示带有标签的文本:{{ sss|safe }}</p>#}
{#<p>展示带有标签的文本:{{ sss1|safe }}</p>#}

标签

逻辑相关

fo循环if联用

{% for foo in l %}
	{% if forloop.first %}
		<p>这是我的第一次</p>
	{% elif forloop.last %}
		<p>这是最后一次了啊</p>
	{% else %}
		<p>{{ foo }}</p>
	{% endif %}
	{% empty %}
		<p>当for循环的对象是空的时候会走</p>
{% endfor %}

变量相关

句点符

<!--
comp_dic = {'name':'slk', 'hobby':[1,2,[3,4[{'age':18}]]]}
-->
<p>{{ comp_dic.hobby.2.2.age }}</p>

自定义过滤器和标签?

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

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

  3. 在该py文件中,(必须)写一下两句代码

    from django.template import Library
    
    

register = Library()


### 自定义过滤器

​```python

@register.filter(name='baby')
def index(a,b):
    return a + b
{#<p>自定义过滤器的使用</p>#}
{% load mytag %}
{{ 1|baby:1  }}
{{ 1|baby:100  }}

自定义标签

# 自定义标签   可以接受任意多个参数
@register.simple_tag(name='mytag')
def mytag(a,b,c,d):
    return '%s?%s?%s?%s'%(a,b,c,d)
{#<p>自定义标签的使用 可以接受多个参数 参数与参数之间必须空格隔开</p>#}
{% load mytag %}
{% mytag 'a' 'b' 'c' 'd' %}

自定义inclusion_tag

@register.inclusion_tag('mytag.html',name='xxx')
def index666(n):
    l = []
    for i in range(n):
        l.append('第%s项'%i)
        return locals()  # 将l直接传递给mytag.html页面
{% load mytag %}
<p>自定义的过滤器可以在逻辑语句使用 而自定义的标签不可以</p>
<p>当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用</p>
{% if mytag '1' '2' '3' '4' %}
    <p>有值</p>
    {% else %}
    <p>无值</p>
{% endif %}

模板

模板的继承

需要事先在想要使用的页面上划定区域,在继承的时候,就可以修改划定的区域

如果没有划定区域,就无法修改页面内容

也可划定css、js区域

{% block contentName %}
 
<!--划定的区域-->
                 
{% endblock %}
<!--继承之后-->
{% extends 'home.html' %}

{% block contentName %}
<!--修改模板中content区域内容-->
{% endblock %}
{% 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区域越多,页面的可扩展性越强

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

模板的导入

{% include 'bform.html' %}

posted on 2019-11-26 22:59  shenblogs  阅读(164)  评论(0)    收藏  举报

导航