在以前咱们就知道,不一样语言或者说系统之间,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表单是在前端,也就是html文件里面写的一种格式,能够用来给后端传一些数据,或者上传文件,下面举例form的写法python
# 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的全程为Class Based View,也就是基于类的视图,下面咱们经过一个实例来看一下这个东西的做用django
#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请求的,下面咱们详细分析一波.json
咱们先来看路由层里面,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) # 在调用获取到的方法
模板传值,其实就是把存在于后端的变量值传到前端并经过模板的形式展现出来,模板语法,最经常使用的符号有两种,即{{}}
,{% %}
,其中{{}}
里面写入变量相关的内容,{% %}
里面写入逻辑相关的内容.安全
实例以下:dom
#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的过滤器的做用有些相似于咱们以前学习的函数的内置方法,其用法就是:函数
会将|左边的值当作过滤器的第一个参数 ,|右边的当前过滤器第二个参数.oop
下面咱们介绍几种经常使用的过滤器
# 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判断里面使用的,可是自定义过滤器能够.