Django-3

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' %}

posted @ 2019-10-23 22:16  SweetJack  阅读(333)  评论(0编辑  收藏  举报