Django之视图层

Django之视图层

JsonResponse

JsonResponse是用来反回json格式的数据的.

1.因为要实现前后端分离, 那么他就是基于json格式来进行格式传输的.比如后端就专门写接口,前端调用这个接口,就能拿到一个json格式的字符串.然后前端在通过序列化反序列化转换成前端对应的数据类型.


json常用数据类型:
数值类型
字符类型
数组
自定义对象
undefined与null
布尔值 true False
symbol

前端序列化和反序列化
JSON.stringify  序列化  --->  json.dumps
JSON.parse     反序列化 ---->  json.loads

from表单上传数据

form表单上传文件
  注意事项:
     1.提交的方式必须是post
     2.enctype参数必须有默认值urlencoded变成formdata

FBV与CBV之CBV源码分析

FBV与CBV 即CBV源码分析
    FBV(Function Based View) 基于函数的视图
    
    CBV(Class Based View) 基于类的视图
        你在类中写了两个方法 一个叫get一个叫post
        为什么前端get请求来就会触发get方法
        post请求来就会触发post方法  如何实现的???
    
    # CBV路由
    url(r'^reg/',views.MyReg.as_view())
    
    @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
    
    # views.py 
    from django.views import View
    
    
      class MyReg(View):
        def get(self,request):
            return render(request,'reg.html')

        def post(self,request):
            return HttpResponse("我是MyReg类中post方法")
            
 """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)
            # handler = getattr(自己写的类产生的对象,'小写的请求方法(get\post)','获取不到对应的方法就报错')
            # handler就是我们自己定义的跟请求方法相对应的方法的函数内存地址
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)  # 在调用获取到的方法

模板传值

模板传值
    传函数名的时候 会自动加括号调用函数  将函数的返回值展示在html页面上
    django模板语法不支持函数传参
    
    django模板语法在获取容器类型内部元素的值的时候 统一只采用 句点符(.)

过滤器

1.add过滤器:
{{ value|add:"2" }} 用来做拼接.如果是int会相加

2.cut过滤器:
{{ value|cut:" "}} 会移除所有的空格

3.date过滤器:
{{ birthday|date:"Y/m/d" }} 将一个日期安照指定格式变成字符串反回

4.default过滤器:
{{ value|default:"0"}} 可以设置默认值

5.first过滤器
{{ value|first }} 反回列表/元祖/字符串的第一个元素

标签

1.标签用于解决编码问题,提高灵活性,方便项目管理
2.标签的语法:you{% 和 %}来定义的, 例如: { %tag% }{% endtag%}

1.if/else标签
{% if condition1 %}
    display1
{% elif condition2 %}
    display2
{% else %}
     display3
{ %endif% }
根据条件判断是否输出, if/else支持嵌套
接受 and, or 或则 not关键字来对多个变量做判断

2.for标签
1.# 遍历每一元素
{% for person in person_list %}
   <p>{{ person.name }}</p>
{% endfor %}

2.#可以利用{% for obj in list reversed %}反向循环

3.遍历每一个字典
{% for key,val in dic.items %}
   <p>{{key}}:{{val}}</p>
{% endfor %}

4.循环序号可以通过{{ forloop }} 显示
forloop.counter        当前循环的索引值(从1开始)
forloop.counter0       当前循环的索引值(从0开始)
forloop.revcounter     当前循环的倒序索引值(从1开始)
forloop.revcounter0    当前循环的倒序索引值(从0开始)
forloop.first          当前循环的第一次循环则返回True,否则反回False
forloop.last           当前循环是最后一次循环则反回True, 否则反回False
forloop.parentloop     当前循环的外层循环

5.for标签可以带有一个可选的{% empty %} 从句, 在变量person_list为空或者没有被找到时,则执行 empty子句
{% for person in person_list %}
    <p>{{person.name }}</p>
{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

演示:
url(r'^test/', views.test),

def test(request):
    names = ['kang', 'wei']
    dic = {'name': 'Kang', 'age': 14, 'sex': 'male'}
    list1 = []
    return render(request, 'test.html', locals())


<body>
<hr>
{% for name in names %}
    <p>{{ forloop.counter0 }}</p>
{% endfor %}
取出:
0
1
<hr>
{% for name in names reversed %}
    <p>{{ forloop.revcounter0 }}</p>
{% endfor %}
取出:
1
0
<hr>
{% for k, v in dic.items %}
    <p>{{ forloop.counter }} {{ k }}:{{ v }}</p>
{% endfor %}
取出:
1 name:kang
2 age:16
3 sex:male
{% for item in list1 %}
    <p>{{ item }}</p>
    {% empty %}
        <p>sorry, no value here</p>


{% endfor %}
取出:
sorry, no value here


</body>

常用之with标签
#with标签用来为一个复杂的变量起别名,如果变量的值来自于数据库,在起别名后只需要要使用别名即可,不需要每一次都向数据库发送请求,来从新获取变量值
{% with li.1.user as v %}
     {{ v }}
{% endwith %}

#常用之csrf_token标签
1.当用from表单提交POST请求时必须加上标签{% crsf_token %},该标签用于防止跨站伪造请求
<form action="" method="POST">
   <% csrf_token %>
   <p>用户名: <input type="text" name="name"></p>
   <p>密码: <input type="password" name="pwd"></p>
   <p><input type='submit' value="提交"></p>
</form>
#具体工作原理:
1.在GET请求到form表单时,标签{% csrf_token %}会被渲染成隐藏的input标签,该标签包含了由服务端生成的一串随机字符串,如:<input type="hidden" name="hjkasdhfjkds" value="hfdsiaf">
2.在使用form表单提交POST请求时,会提交上诉随机字符串, 服务端在接收到该POST请求时会对比随机字符串,对比成功则处理该POST请求,否则拒绝,以此来确定客户端的身份.

自定义过滤器、 标签

当内置的过滤器或标签无法满足我们的需求的时候,我们就可以自定义,具体操作步骤如下

步骤:
   1.在应用名下新建一个templatetags文件夹,(规定必须是这个名字)
   2.在这个文件夹下面,新建一个任意名称的py文件.
   3.在这个py文件内你要固定的写两行代码:
   from django.template import Library
   register = Lobrary()
   
1.自定义过滤器:
@register.filter
def my_milti_filter(v1, v2): # 自定义的过滤器只能定义最多两个参数, 针对{{ value | filter_multi:value2 }},参数传递为v1=value, v2=value2
     return v1 * v2
     
2.自定义标签
@register.simple_tag
def my_multi_tag(v1, v2): #自定义的标签可以定义多个参数
     return v1 * v2
4. 自定义过滤器或标签必须重新启动django方可生效
5. 自定义过滤器或标签的使用
<body>

<!--必须先加载存有自定义过滤器和标签的文件-->
{% load my_tags %}

<!--salary的值为10,经过滤器my_multi_filter的处理结果为120-->
{{ salary|my_multi_filter;12 }}

<!--结果为2-->
{% my_multi_tag 1 2%}

##对比自定义标签与自定义过滤器
1.自定义过滤器只能传两个参数, 而自定义标签却可以传多个参数
2.过滤器可以用于if判断,而标签不能
{% if salary|my_multi_filter:12 > 200 %}
      <p>优秀</p>
{% else %}
      <p>垃圾</p>
{% endif %}

模板的继承

模板的继承
   事先需要在模板中 通过block来划定区域.
     {% block 区域名字 %}
     
     {% endblock %}
   子版如何使用
     {% extends 区域名字 %}
     
     {% block %}
         <h1>登录页面<h1>
     {% endblock %}
在一个页面上面 block块越多, 那么页面的扩展性也就越高.
在统称情况下都应该有三片区域
            {% block css %}  #css不同

            {% endblock %}
            
            {% block content %}  #中间的一些内容

            {% endblock %}
            
            {% block js %} #js的不同

            {% endblock %}
            
  子板中还可以通过
  {{ block.super }} 来继续使用母版的内容

模板的导入

模板的导入
  当你写了一个比价好看的form表单,你想在多个页面中去调用它,你就可以将你写的form表单当作模块的形式导入. 导入过来之后就可以直接展示.
  
  {% include 'good_page.html' %}

posted @ 2019-10-24 22:29  Feeling_afraid  阅读(101)  评论(0编辑  收藏  举报