Django数据传递与模板语法

Django数据传递与模板语法

视图函数返回值

1.视图函数的返回值其实本质上返回的都是HttpResponse对象,HttpResponse其实是一个类,我们最常使用的render和redirect都是这个类中的函数,所以返回值本质上都是HttpResponse对象
1.1HttpResponse源码
	class HttpResponse(HttpResponseBase):(本质上是一个类属性对象)
    	pass
1.2render源码
	def render(request, template_name, context=None, content_type=None, status=None, using=None):(本质上是一个函数属性对象)
		return HttpResponse(content, content_type, status) (返回值返回的是一个HttpResponse属性对象)
1.3redirect源码
	def redirect(to, *args, permanent=False, **kwargs):(本质上也是一个函数属性)
		redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect (将HttpResponse对象赋值给redirect_class)
		return redirect_class(resolve_url(to, *args, **kwargs)) (返回值是上方的类然后我们继续返回得到的还是一个HttpResponse对象)
    

JsonResponse

1.视图函数返回json格式数据
    user_dict = {'name': '菜kunkun', 'pwd':777, 'hobby': ['jump','rap','basketball']}  自己准备一个数据
    return JsonResponse(user_dict, json_dumps_params={'ensure_ascii':False})  使用JsonResponse展示数据
    # import json  # 使用json格式序列化数据并展示
    # json_str = json.dumps(user_dict, ensure_ascii=False)
    # return HttpResponse(json_str)

class JsonResponse(HttpResponse):  这个格式返回的也是HttpResponse所有符合规范

    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,json_dumps_params=None, **kwargs):  解码safe = True
        if json_dumps_params is None:  
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super().__init__(content=data, **kwargs)
序列化非字典型数据还需要指定safe参数改为False

form表单携带文件数据

1.form表单携带数据文件数据
	method属性值必须是POST
	enctype属性值必须是multipart/form-data
页面信息:
<body>
{#    <form action="" method="post" enctype="application/x-www-form-urlencoded"></form>#}  只能传文本文件,不能传递文件和其他
    <form action="" method="post" enctype="multipart/form-data">  # 这种什么格式都可以传递,但是由于pycharm打不开mp4和img文件就很遗憾
    <p>username:
        <input type="text" name="username">
    </p>
    <p>file:
        <input type="file" name="file">
    </p>
    <input type="submit" value="提交数据">
</form>
</body>
后端:
  if request.method == 'POST':
        print('request.POST',request.POST)
        print('request.FILES',request.FILES)
        file_obj = request.FILES.get('file')
        print(file_obj.name)
        with open(file_obj.name,'wb') as f:
            for line in file_obj:
                f.write(line)
    return render(request,'index.html')
获取文件:
request.FILES <MultiValueDict: {'file': [<InMemoryUploadedFile: Django生命周期_20220901205059.jpg (image/jpeg)>]}>
Django生命周期_20220901205059.jpg
2.从后端获区文件数据的操作
	request.FILES

FBV和CBV

FBV:基于函数的视图
	def 函数名(request):
	    return HttpResponse()
	path('函数名/',views.函数名)
CBV:基于类的视图
urls页面:
	path('func/', views.MyView.as_view())
views页面:
	form django import views
	class MyView(views.View):
	def get(self,request):  # 如果是get请求那么走这个
		return HttpResponse('我是CBV里面的get方法')
	def post(self,request):  # 如果是post请求走这个
	    return HrrpResponse('我是CBV里面的post方法')

    
CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行

CBV源码

1.源码入口
	path('func/', views.MyView.as_view())  # 直接ctrl+点击as_view即可进入

2.绑定给类sa_view的方法
	@classonlymethod
	for key in initkwargs:
		if key in cls.http_method_names:
  			raise TypeError("You tried to pass in the %s method name as a ""keyword argument to %s(). Don't do that." % (key, cls.__name__))
		if not hasattr(cls, key):
			raise TypeError("%s() received an invalid keyword %r. as_view ""only accepts arguments that are already ""attributes of the class." % (cls.__name__, key))

        def view(request, *args, **kwargs):
				(......)
            return self.dispatch(request, *args, **kwargs)
        return view  # 首先返回view
3.证明了CBV匹配的本质和FBV一样都是最后产生一个函数,通过调用函数来触发执行
	path('func/', views.view)

4.访问view还是ctrl选中然后点击进入查看源码
	def view(request, *args, **kwargs):
		(......)
		return self.dispatch(request, *args, **kwargs)  # 找到顺着执行找到dispatch

5.研究dispatch方法
	def dispatch(self, request, *args, **kwargs):
		(......)
		return handler(request, *args, **kwargs)

模板语法传值的两种方式

1.模板语法传值
	方式一:指名道姓传值,不会浪费资源,但是只要数据多的话那么就会有点吃不消,;浪费时间 
	return render(request, 'modal.html', {'name':name}) 

	方式二:将整个局部名称空间中的名字去全部传入简单快捷,但是较为浪费资源,关键字locals()
	return render(request,'modal.html',locals())

模板语法传值特性

1.模板语法传值的范围
	我们八个基础数据类型都可以直接传递(int,float,str,list,dict,tuple,set,bool)

	函数名的传递会自动加括号帮我们执行并且返回值也会展示到页面上,但是在传参的时候有参函数不会执行也不会展示,模板语法中不支持有参函数的传递也会自动加括号产生对象并展示到页面上
	如果直接是传递的对象那么就会自动传入,不需要加各种东西,直接展示
	模板语法使用时如果第一个不符合要求,那么就会继续下一个知道判断完每一个名字是否可以调用。
	Django模板语法字操作容器类型的时候只允许使用句点符的方式进行操作

模板语法之过滤器

代码 功能

{{ s|length }}

统计长度

{{ i|add:520 }}

加法运算

{{ s|add:'hahaha' }}

加法运算

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

日期转换

{{ file_size|filesizeformat }}

文件大小会帮忙统计成值正确的最大单位

{{ 1|slice:'0:99' }}

数据切片,如果切得够大然后数据不够的话那么,不会报错,能取多少取多少

{{ s1|truncatechars:6 }}

字符截取(三个点算一个)

{{ s1|truncatewords:6 }}

单词截取(空格算间距只要有一个空格他就算你有一个单词)

{{ script_tag|safe }}

语法转义,确定安全

{{ script_tag|safe }}

语法转义,主动确认安全
1.Django模板语法中的符号就两个
	1. {{}}  需要使用数据的时候那么就是用这个和数据交互
	2. {% %}  如果调用方法的话那么就是用这个调用方法
2.有时候在html页面上的数据不一定非要在html页面上编写了,也可以后端写好传入
	from django.utils.safestring import mark-safe
	script_tagl ='<script>alert(520)</script>'
	res = mark_safe(script_tagl)

模板语法之标签

1.模板语法标签(与python流程控制类似)
1.1if循环
{% if 条件 %}
	条件成立执行的代码
{% elif 条件1 %}
	条件1成立所执行的代码
{% else %}
	条件都不成立所执行的代码
{% endif %}

2.2for循环if嵌套

{% for i in s %}
	{% if forloop.first %}
		<p>首次出现的被捕获</p>
	{% elif forloop.last %}
		<p>最后一次出现的被捕获</p>
	{% else %}
			<p>{{ i }}</p>
	{% endif %}
	{% empty %}
		<p>这是个啥,你想让我循环什么东西</p>
{% endfor %}

自定义相关功能

1.自定义标签函数、过滤器、inclusion_tag
	如果想要自定义的话那么就需要先满足以下条件:
		1.1 在应用下创建一个名为templatetags文件夹
		1.2 在该文件夹创建任意名称的py文件
		1.3 在该py文件中编写自定义相关代码
		from django.template import Library
		register = Library()

2.自定义过滤器,一个最简单的加法
@register.filter(name='myfilter')
def my_add(a,b):
	return a+b

3.自定义标签函数
@register.simple_tag(name='mt')
def func(a, b, c, d)
	return a + b + c + d

4.自定义inclusion_tag
@register.inclusion_tag(filename='it.html')
def index(n):
	html = []
	for i in range(n)
		html.append('第%s页'%i)
	return locals()

5.功能补充
	{% load mytag %}
	{% i|myfilter %}
	{% mt 1 2 3 4 %}
	{% index 10 %}

模板的继承与导入

{% extends 'html文件名' %}
{% block 名字 %}
	模板内容
{% endblock %}

{% block 名字 %}
	子版内容
{% endblock %}
	一般情况下模板中至少应该有三个区域是的扩展性更强一些
	css content js

替换内部css文件
{% block css %}
{% endblock %}

{% block content %}
{% endblock %}

替换内部js文件
{% block js %}
{% endblock %}

模块的导入

将html页面的某个部分当做模块的形式导入使用
	{% include'menu.html' %}
posted @ 2022-09-02 23:01  Joseph-bright  阅读(182)  评论(0编辑  收藏  举报