Django的日常-视图层
Django的日常-3
JsonResponse
在之前我们就知道,不同语言或者说系统之间,Json格式的数据是通用性最好的,所以我们通常会选择用json格式来从后端向前端传输数据,在Django里面,我们不需要像之前那样导入json模块然后用json.dumps和json.loads
来打包和解析json数据,因为我们有一个专门的函数来做json数据的转换,就叫做JsonResponse.
# 首先我们还是需要导入这个函数
from django.http import JsonResponse
# 下面的内容我们需要写在一个函数里面,方便调用
def index(request):
user = {'username':'nick哈哈哈','pwd':'123'}
return JsonResponse(user,json_dumps_params={'ensure_ascii':False})
l = [1, 2, 3, 4, 5, 5, 6]
return JsonResponse(l, safe=False)
'''
在使用JsonResponse模块的时候,要注意的几点是:
1. JsonResponse默认只支持序列化字典 如果你想序列化其他类型(json能够支持的类型) 你需要将safe参数由默认的True改成False,比如 JsonResponse(l, safe=False)
2. 在用JsonResponse序列化的时候,如果内容里面有中文,会自动被解析成二进制码,所以如果我们想要保留中文的话,需要在给JsonResponse传值的时候加入json_dumps_params={'ensure_ascii':False},即不自动解析,这样就能保留原始数据里面的中文,例如JsonResponse(user,json_dumps_params={'ensure_ascii':False})
'''
form表单上传文件
我们知道form表单是在前端,也就是html文件里面写的一种格式,可以用来给后端传一些数据,或者上传文件,下面举例form的写法
# up.html文件里面
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="username">
<input type="file" name="myfile">
<input type="submit">
'''
这里要注意两点:
1. form表单在向后端传输数据的时候,method方法必须是post
2. enctype参数必须设置为"multipart/form-data"
'''
# views.py后端
def up(request):
if request.method == 'POST':
print(request.POST) # 可以取到请求的内容
print(request.FILES)
# 获取文件对象
file_obj = request.FILES.get('myfile') # 这里的别名是前端的html文件里定义的别名
print(file_obj.name) # 获取文件名
with open(file_obj.name, 'wb') as f:
for chunk in file_obj.chunks():
f.write(chunk)
return render(request, 'up.html')
CBV的源码分析
首先,我们要知道CBV的全程为Class Based View,也就是基于类的视图,下面我们通过一个实例来看一下这个东西的作用
#urls.py
urlpatterns = [
url(r'^reg/',views.MyReg.as_view()),
#其实上面这句url相当于 url(r'^reg/',views.MyReg.get()),或者 url(r'^reg/',views.MyReg.post()),
]
#views.py
class MyReg(View):
def get(self, request):
return render(request, 'reg.html')
def post(self,request):
return HttpResponse("我是MyReg类中post方法")
#reg.html
<body>
<form action="" method="post">
<input type="submit">
</form>
</body>
我们在写完以上代码并执行起来以后,输入网址http://127.0.0.1:8000/reg/
,可以看到有个提交按钮,按下之后我们可以看到"我是MyReg类中post方法"
这句话,那么问题就来了,这个逻辑是怎样的,我们定义的MyReg类是怎么判定你发来的是get还是post请求的,下面我们详细分析一波.
我们先来看路由层里面,url里所使用的的as_view的部分源码如何:
#base.py class View/as_view源码
class View(object):
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls就是我们自己的写的MyReg类
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
# 上面的操作 就是给我们自己写的类的对象赋值
return self.dispatch(request, *args, **kwargs)
# 这里我们看到,最终返回的是self调用dispatch方法,所以我们再找到dispatch的源码来看
return view
# dispatch源码
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names: # 判断当前请求方式在不在默认的八个请求方式中,其实我们最常用的就是post和get请求
'''
八种请求方式为:GET,HEAD,POST,PUT,DELETE,CONNECT,OPTIONS,TRACE
'''
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
# handler = getattr(自己写的类产生的对象,'小写的请求方法(get\post)','获取不到对应的方法就报错')
# handler就是我们自己定义的跟请求方法相对应的方法的函数内存地址
# 我们用反射就是从类对象来反射出来并获取其生成时候的方法,最后返回调用该方法
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 在调用获取到的方法
视图层
模板传值
模板传值,其实就是把存在于后端的变量值传到前端并通过模板的形式展示出来,模板语法,最常用的符号有两种,即{{}}
,{% %}
,其中{{}}
里面写入变量相关的内容,{% %}
里面写入逻辑相关的内容.
实例如下:
#views.py 后端
from datetime import datetime
from django.utils.safestring import mark_safe
def login(request):
n = 123
f = 12.12
s = '你妹的 真难'
l = [1, 2, 3, 4, 5, 6]
d = {'username': 'jason', 'password': [123, 222, 444]}
t = (1, 2, 3, 4, 5)
se = {1, 2, 3, 4}
b = True
ctime = datetime.now()
file_size = 342384234234
w = '奥术 大师件 大事肯德 基按 实际对 拉 螺栓空当接 龙'
w1 = 'asdash ashd jkh sadas asdjjs had sjklad j a kjkjdsklas dkjsakldj dlsjakld '
w2 = 'he llow ord wqe asdsad sadsadsa dsadasds adasds adsadsadsada sdsad'
def func():
return '你好~'
obj = MyClass()
sss = "<h1>一脸懵逼</h1>"
sss1 = "<script>alert(123)</script>"
sss2 = "<a href='http://www.baidu.com'>好好学习</a>"
# mark_safe,转义,即我们会认定这个语句安全,然后让其转义之后再发送给前端,让前端可以直接显示出其特定格式
res = mark_safe(sss2)
xo = '123213213'
xo1 = 222
yyy = {'user_list': [1, '22', {'username': ['jason', 'egon']}]}
return render(request, 'login.html', locals())
#login.html 前端
<body>
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ s }}</p>
<p>{{ l }}</p>
<p>{{ d }}</p>
<p>{{ se }}</p>
<p>{{ t }}</p>
<p>{{ b }}</p>
{#以上数值类型都可以直接传值并显示出来#}
{#如果传递给前端一个函数名,会直接加括号调用,将函数的返回值展示到前端,尤其需要注意的是!!!!!django的模板语法,不支持给函数传参,不支持传参,不支持传参,不支持传参#}
<p>{{ func }}</p>
{#方法也都不能传参#}
<p>{{ obj }}</p>
<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_func }}</p>
<p>{{ obj.get_self }}</p>
{#模板语法取值,这里要注意,django模板语法在获取容器类型内部元素的值的时候,要统一采用句点符的形式取值,也就是(.),不支持别的取值方式#}
<p>{{ l.1 }}</p>
<p>{{ l.3 }}</p>
<p>{{ d.username }}</p>
<p>{{ d.password }}</p>
<p>{{ d.password.1 }}</p>
{#前面的变量有值就拿值,没值就用后面默认的,前面变量不存在的情况下也是显示后面的默认值#}
<p>{{ xo|default:'hello' }}
</body>
过滤器
django的过滤器的作用有些类似于我们之前学习的函数的内置方法,其用法就是:
会将|左边的值当做过滤器的第一个参数 ,|右边的当前过滤器第二个参数.
下面我们介绍几种常用的过滤器
# login.html
<body>
{#add,如果两者都是数值会相加,如果都是字符串会拼接#}
<p>{{ n|add:100 }}</p>
<p>{{ n|add:'abc' }}</p>
<p>{{ s|add:'sasahhdasda' }}</p>
{#upper,大写#}
<p>{{ n|upper}}</p>
{#lenth,返回前者的长度,常用于容器类的元素#}
<p>{{ l|length }}</p>
<p>{{ d|length }}</p>
{#capfirst会把第一个字母大写#}
<p>{{ s|capfirst }}</p>
{#random,返回列表中随机的一项#}
<p>{{ l|random }}</p>
{#filesizeformat,会把数值当做文件大小,并转换成最合适的单位,比如MB,比如GB,比如TB#}
<p>{{ file_size|filesizeformat }}</p>
{#truncatechars,truncatewords 按字符截取和按单词截取#}
<p>截取10个字符 三个点也算{{ w1|truncatechars:10 }}</p>
<p>截取10个字符 三个点也算{{ w|truncatechars:10 }}</p>
<p>安装空格截取单词 三个点不算{{ w1|truncatewords:6 }}</p>
<p>安装空格截取单词 三个点不算{{ w|truncatewords:6 }}</p>
<p>安装空格截取单词 三个点不算{{ w2|truncatewords:6 }}</p>
{#切片,支持索引切片#}
<p>{{ l|slice:'0:5' }}</p>
<p>{{ l|slice:'0:5:2' }}</p>
{#date,将日期格式化#}
<p>{{ ctime|date:'Y-m-d' }}</p>
<p>{{ ctime|date:'Y年/m月' }}</p>
{#safe,语句安全,支持转义,即我们语句中的符合前端的语法会被转义并显示出来,这种写法是前端转义#}
<p>{{ sss|safe }}</p>
<p>{{ sss1|safe }}</p>
{#该句是在后端转义完毕之后传到前端的#}
<p>{{ res }}</p>
</body>
#view.py
#这里的login函数还是用上面模板传值的
标签
django里面的常用标签即if判断和for循环
# login.html
<body>
{#if...else判断#}
{% if xo %}
<p>xo有值</p>
{% else %}
<p>xo没有值</p>
{% endif %}
{#if...elif...else#}
{% if xo %}
<p>xo有值</p>
{% elif xo1 %}
<p>xo1有值</p>
{% else %}
<p>去他大爷的</p>
{% endif %}
{#for...#}
{% for foo in l %}
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次了啊</p>
{% else %}
<p>嗨起来 大宝贝~</p>
{% endif %}
{% endfor %}
{#设置empty,如果循环体xo为空的话,会返回empty里面的内容#}
{% for foo in xo %}
<p>{{ forloop.counter }}:{{ foo }}</p>
{% empty %}
<p>你给我的对象是个空的没法进行for循环</p>
{% endfor %}
{#对字典里的值进行循环取值,包括items键值对,keys关键字以及values值#}
{% for foo in d.items %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in d.keys %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in d.values %}
<p>{{ foo }}</p>
{% endfor %}
{#对取到的值起一个别名,这样在endwith的结构体里面就可以直接用这个别名来调用#}
<p>{{ yyy.user_list.2.username.1 }}</p>
{% with yyy.user_list.2.username.1 as dsb %}
<p>{{ dsb }}</p>
<p>{{ yyy.user_list.2.username.1 }}</p>
{% endwith %}
</body>
自定义过滤器和标签
我们在自定义过滤器和标签的时候,要牢记以下三个步骤:
首先我们要在应用名下新建一个文件夹,名为
templatetags
,注意,名字不能错,不然django会找不到这个东西以至于自定义的过滤器和标签都不生效在刚刚创建的
templatetags
文件夹下面新建一个py文件,名字任意,我们这里起名字叫做my_tag.py
在该
my_tag.py
文件里写入以下两行代码# my_tag.py
from django.template import Library register = Library()
做完以上三步我们就可以来写自己的过滤器和标签了,同样是在这个my_tag.py
文件里写
自定义过滤器如下:
# my_tag.py
@register.filter(name='myplus') #给过滤器起别名为myplus,调用的时候用别名即可
def index(a, b):
return a + b
# 这个过滤器的作用即是将传入的两个参数相加,然后返回
# 另外,过滤器最多只能穿两个参数,不能多于两个参数
自定义过滤器的调用:
# login.html,在前端调用
<body>
{% load my_tag %}
{{ 123|myplus:123 }}
# 显示的结果为246
</body>
自定义标签如下:
# my_tag.py
@register.simple_tag(name='mysm')
def login(a, b, c, d):
return '%s/%s/%s/%s' % (a, b, c, d)
自定义标签的调用:
# login.html
<body>
{% mysm 1 2 3 4 %}
</body>
要注意的一点是,自定义标签是不能在if判断里面使用的,但是自定义过滤器可以.
Django的日常-视图层的更多相关文章
- Django 学习 之 视图层(views)
一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何 ...
- [Django框架之视图层]
[Django框架之视图层] 视图层 Django视图层, 视图就是Django项目下的views.py文件,它的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相 ...
- Django学习之视图层
视图层 小白必会三板斧 HttpResponse render redirect django视图函数必须要给返回一个HttpResponse对象(render和redirect内部返回的也是一个Ht ...
- Django基础之视图层
内容概要 小白必会三板斧 request对象方法初识 form表单上传文件 Jsonresponse FBV与CBV 内容详细 1 小白必会三板斧 HttpResponse render redire ...
- web框架开发-Django视图层
视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...
- django 实战篇之视图层
视图层(views.py) django必会三板斧 HttpResponse >>> 返回字符串 render >>> 支持模板语法,渲染页面,并返回给前端 red ...
- Django视图层
本文目录 1 视图函数 2 HttpRequest对象 3 HttpResponse对象 4 JsonResponse 5 CBV和FBV 6 简单文件上传 回到目录 1 视图函数 一个视图函数,简称 ...
- $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传
1 虚拟环境:解决问题同一台机器上可以运行不同版本的django, 1 用pychanrm创建--->files-->newproject--->选择虚拟环境 2 setting ...
- python 全栈开发,Day69(Django的视图层,Django的模板层)
昨日内容回顾 相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 pyt ...
随机推荐
- 判断APP是否已安装
NSString *str = [NSString stringWithFormat:@"%@://%@",[dic objectForKey:@"ios_url_sch ...
- STL之__ type_traits
__type_traits:双底线是说明这是SGI STL内部使用的东西,不在STL标准范围之内.iterator_traits负责萃取迭代器(iterator)的特性.而__type_traits则 ...
- 关于TMDS
https://en.wikipedia.org/wiki/Transition-minimized_differential_signaling TMDS,Transition Minimized ...
- excel导入、下载功能
1.excel导入.下载功能 2.首先,我们是居于maven项目进行开发引入poi,如果不是那就手动下载相应的jar包引入项目就可以了 <!-- poi --> <dependenc ...
- 尚学python课程---13、python基础语法
尚学python课程---13.python基础语法 一.总结 一句话总结: legend2系统使我能够快速掌握一门语法,特别有用 pass 语句:空语句:是为了保持程序结构的完整性 :作用:比如: ...
- 简单总结Class.forName("").newinstance()和new()以及classLoader.loadClass("")的区别
文章目录 背景 三种方法简单介绍 Class.forName("").newinstance()方式 new方式 classLoader.loadClass("" ...
- hive 总结二
本文参考:黑泽君相关博客 本文是我总结日常工作中遇到的坑,结合黑泽君相关博客,选取.补充了部分内容. 查询函数(Hive高级) NVL(cloumn,replace_with) 如果cloumn为NU ...
- Java 高级面试知识点汇总!
1.常用设计模式 单例模式:懒汉式.饿汉式.双重校验锁.静态加载,内部类加载.枚举类加载.保证一个类仅有一个实例,并提供一个访问它的全局访问点. 代理模式:动态代理和静态代理,什么时候使用动态代理. ...
- 第四周课堂笔记1th
函数 关键字def 函数名加括号 是调用函数 Return 相当于给函数算完之后给予另一个返回值 返回的是元组 如果return后没写返回none Return在函数中可以结束整 ...
- HYNB Round 8: 2016 ICPC Amritapuri Regionals
HYNB Round 8: 2016 ICPC Amritapuri Regionals A - Tim and BSTs 做法 经典的树 DP 问题. \(dp[u][i]\) 表示考虑以 u 为根 ...