Django-3
JsonResponse
返回json格式的数据
为什么要给前端返回json格式的字符串
前后端分离,就是基于json格式传输数据
前端从后端写的接口中拿到一个能够共同识别的json格式的数据
前端 | 后端 |
---|---|
JSON.stringify() | json.dumps() |
JSON.parse() | json.loads() |
# JsonResponse,后端给前端传json数据 def index(request): dic = {'username':'jason真帅 我好喜欢哦~','pwd':'123'} #### 指定json序列化时,不自动转ascii,这样就能显示中文了 json_str = json.dumps(dic,ensure_ascii=False) return HttpResponse(json_str) #### 利用JsonResponse里的json_dumps_params的默认值,改为字典{'ensure_ascii':False}的键值对形式,也能将中文显示出来。 return JsonResponse(dic,json_dumps_params={'ensure_ascii':False}) lis = [1,2,3,4,5,] str = 'aiefiaef' b = True #### JsonResponse默认只支持序列化字典 如果你想序列化其他类型(json能够支持的类型) 你需要将safe参数由默认的True改成False return JsonResponse(b,safe=False)
form表单上传文件
注意事项:
- 提交方式必须是post
enctype
参数必须重置为multipart/form-data
# up.html <form action="" method="post" enctype="multipart/form-data"> 用户名:<input type="text" name="username"> <input type="file" name="myfile" > <input type="submit" class="btn btn-danger"> </form> # 表单上传文件 def up(request): if request.method == 'POST': print(request.POST) print(request.FILES) file_obj = request.FILES.get('myfile') with open(file_obj.name,'wb') as f: for line in file_obj: f.write(line) return render(request,'up.html')
CBV源码分析
FBV (Function Based View) 基于函数的视图
CBV (Class Based View) 基于类的视图
案例:
1 配置路由
url(r'^reg/',views.get_post.as_view()),
2 编写视图类
from django.views import View class get_post(View): def get(self,request): return render(request,'reg.html') def post(self,request): return HttpResponse('jason牛逼') ''' 当前端发送get请求时,会响应get方法,返回reg.html 当前端发送post请求时,会响应post方法,返回相应的字符串 为什么会这样呢??? '''
3 编写html页面
# reg.html # 当只访问reg.html页面时,发送的是get请求,当提交表单数据时,发送的是post请求 <form action="" method="post"> <h1> get 页面 </h1> <input type="submit" class="btn btn-danger"> </form>
分析
@classonlymethod 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) return view """CBV最精髓的部分""" def dispatch(self, request, *args, **kwargs): if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) ''' 首先,as_view是View的一个类方法,当类来调用是,自动将类当作第一个参数传给as_view as_view内部的view函数先是自定义了类本身的名称空间,并且将携带所有的参数交给dispatch方法 然后在dispatch中,拿到self(也就是自定义类实例化得到的对象)和参数, 先判断小写的请求方式在不在已经定义好的八大请求这个列表中 如果在的话,通过小写的请求方式字符串反射拿到对应请求方式的对象handler,其实handler就是自定义类中自定义的方法,如get或者post 如果不在的话,将报错信息的内存地址赋值给handler 最后调用handler这个对象,并且将结果返回。 '''
模板传值
基本上前端能够接收所有后端能传过来的数据类型,包括函数对象或者类实例化的对象
但也有一些不好的地方,例如:
- 传函数名的时候,会自动加括号调用函数,将函数的返回值展示在html页面上
- django模板语法不支持函数传值
- django模板语法在获取容器类型内部元素的值的时候,统一只采用句点符(.),不支持中括号取值和.get()取值。这一点jinja2模块做的更好。
过滤器
常见的过滤器:
|add:
|length:
|truncatechars:
|truncatewords:
|date:
|safe
|default:
<p>{{ num|add:100 }}</p> <p>{{ str|add:'菜鸡' }}</p> <p>{{ lis|length }}</p> <hr> <p>{{ chuan|truncatechars:15 }}</p> <p>{{ chuan1|truncatechars:15 }}</p> <hr> <p>{{ dtime|date:'y年-m月-d日' }}</p> <hr> <p>{{ sss|safe }}</p> 在后端用字符串写前端代码传给前端,用safe过滤器才会在前端起效果 也可以在后端指定用mark_safe()方法,效果等同于safe过滤器。
标签
- if判断
- for循环
{% for f in lis %} {% if forloop.first %} <p>第一次循环到我</p> {% elif forloop.last %} <p>最后一次循环</p> {% else %} <p>循环体</p> {% endif %} {% endfor %} # forloop对象 {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}
自定义过滤器和标签
步骤
- 在应用名下新建一个templatetags文件夹
- 在该文件夹下新建一个任意名字的py文件
- 在该文件中导入Library模块
- 实例化一个Library对象,并且固定叫register
自定义过滤器:
from django.template import Library register = Library() # 所传的两个参数如果是字母则相加并大写,否则返回空字符 @register.filter(name='myupper') def ss(a,b): if a.isalpha() and b.isalpha(): return (a+b).upper() return '' # 使用 {% load my_tag %} <p>{{ 'faef'| myupper:'afhiawf' }}</p>
自定义标签:
from django.template import Library register = Library() # 将所传参数里的数字相加 @register.simple_tag(name='myadd') def xx(*args): l = len(args) s = 0 for i in range(l): if isinstance(args[i],int): s += args[i] return s # 使用 {% load my_tag %} {% myadd 1 4 5 6 %}
模板的继承
事先需要在模板中 通过block划定区域 {% block 区域名字 %} {% endblock %} 子板中如何使用 {% extends '模板的名字'%} {% block 区域名字 %} <h1>登录页面</h1> {% endblock %} 一个页面上 block块越多 页面的扩展性越高 通常情况下 都应该有三片区域 {% block css %} {% endblock %} {% block content %} {% endblock %} {% block js %} {% endblock %} 子板中还可以通过{{ block.super }} 来继续使用母版的内容
模板的导入
当你写了一个特别好看的form表单,你想再多个页面上都使用这个form表单,你就可以将你写的form表单当作模块的形式导入,导入过来之后,就可以直接展示。
{% include 'good_page.html' %}