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>

自定义过滤器和标签

我们在自定义过滤器和标签的时候,要牢记以下三个步骤:

  1. 首先我们要在应用名下新建一个文件夹,名为templatetags,注意,名字不能错,不然django会找不到这个东西以至于自定义的过滤器和标签都不生效

  2. 在刚刚创建的templatetags文件夹下面新建一个py文件,名字任意,我们这里起名字叫做my_tag.py

  3. 在该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的日常-视图层的更多相关文章

  1. Django 学习 之 视图层(views)

    一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何 ...

  2. [Django框架之视图层]

    [Django框架之视图层] 视图层 Django视图层, 视图就是Django项目下的views.py文件,它的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相 ...

  3. Django学习之视图层

    视图层 小白必会三板斧 HttpResponse render redirect django视图函数必须要给返回一个HttpResponse对象(render和redirect内部返回的也是一个Ht ...

  4. Django基础之视图层

    内容概要 小白必会三板斧 request对象方法初识 form表单上传文件 Jsonresponse FBV与CBV 内容详细 1 小白必会三板斧 HttpResponse render redire ...

  5. web框架开发-Django视图层

    视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...

  6. django 实战篇之视图层

    视图层(views.py) django必会三板斧 HttpResponse >>> 返回字符串 render >>> 支持模板语法,渲染页面,并返回给前端 red ...

  7. Django视图层

    本文目录 1 视图函数 2 HttpRequest对象 3 HttpResponse对象 4 JsonResponse 5 CBV和FBV 6 简单文件上传 回到目录 1 视图函数 一个视图函数,简称 ...

  8. $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传

    1 虚拟环境:解决问题同一台机器上可以运行不同版本的django,  1 用pychanrm创建--->files-->newproject--->选择虚拟环境  2 setting ...

  9. python 全栈开发,Day69(Django的视图层,Django的模板层)

    昨日内容回顾 相关命令: 1 创建项目 django-admin startproject 项目名称 2 创建应用 python manage.py startapp app名称 3 启动项目 pyt ...

随机推荐

  1. JS对象 指定分隔符连接数组元素join() join()方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。

    指定分隔符连接数组元素join() join()方法用于把数组中的所有元素放入一个字符串.元素是通过指定的分隔符进行分隔的. 语法: arrayObject.join(分隔符) 参数说明: 注意:返回 ...

  2. Vue.js小游戏:测试CF打狙速度

    此项目只测试反应速度,即手点击鼠标的反应速度 html代码 <div id="top">请等待图片变颜色,颜色便的那一刻即可点击测手速</div> < ...

  3. springboot EL @Value

    一,springboot中 看一下代码: @Controller public class HelloController { //读取枚举值 @Value("#{T(com.example ...

  4. python的update方法

    b = {"c":0, "position":{}} b["position"]["IF"] = {} print(b) ...

  5. 【JZOJ6294】动态数点

    description analysis 这题出的失败在只卡正解不卡暴力 比较好想的方法是枚举约数,向两边二分,但是这个不满足二分性 首先用\(ST\)表维护区间的\(\gcd\),不用线段树,这样查 ...

  6. chrome的驱动安装

    首先找到对应的chromedriver,百度搜索,http://npm.taobao.org/mirrors/chromedriver/ 将下载好的chrome驱动解压,放在/usr/loacl/bi ...

  7. poj 1742 Coins(二进制优化多重背包)

    传送门 解题思路 多重背包,二进制优化.就是把每个物品拆分成一堆连续的\(2\)的幂加起来的形式,然后把最后剩下的也当成一个元素.直接类似\(0/1\)背包的跑就行了,时间复杂度\(O(nmlogc) ...

  8. 在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢

    在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢  

  9. WinDBG常用断点命令

    WinDBG提供了多种设断点的命令: bp 命令是在某个地址 下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction . 对于后者,WinDBG 会自动找到MyA ...

  10. VS2010-MFC(常用控件:树形控件Tree Control 下)

    转自:http://www.jizhuomi.com/software/203.html 前面一节讲了树形控件Tree Control的简介.通知消息以及相关数据结构,本节继续讲下半部分,包括树形控件 ...