zoukankan      html  css  js  c++  java
  • Django框架——视图(views)层、模板层

    JsonResponse

    ​ 返回一个json格式数据

    ​ 为什么要给前端返回一个json字符串?

    ​ 答:前后端分离就是基于json格式传输数据 前端调用接口 就能够拿到json格式的字符串,然后前端利用序列化(json.stringify)反序列化(json.parse)转换成前端对应的数据类型

    向前端返回一个json格式字符串的两种方式

    方式一:

    import json
    
    def my_view(request,ensure_ascii=True):
        data = ['jsaon','yjy']
        return HttpResponse(json.dumps(data))
    #ensure_ascii=True可以不会把中文序列化,可以将中文正常显示

    方式二:

    from django.http import JsonResponse
    
    def my_view(request):
        data = ['jsaon','yjy']
        return JsonResponse(data,safe=False)
        #默认safe=True代表只能序列化字典对象,safe=False可以序列化字典以外的对象

    重写Django中的json的某个方法

    重写Django中的json的某个方法让他也能够序列化datetime

    class MyJsonClass(json.JSONENcoder):
        def default(self,o):
        if isinstance(o,datetime):
            return o.strftime('%Y-%m-%d')
        else:
            super().default(self,0)
    d = {'ctime':datetime.today()}
    print(json.dump(d,cls= MyJsonClass))

    form表单上传文件

    注意事项:

    • 提交方式必须是post
    • method属性需要由默认的get变成post
    • enctype参数必须有默认的urlencoded变成formdata

    视图层

    def up(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)
            #获取文件对象
            fille_obj = request.FILES.get('myfile')
            print(file_obj.name)
            with open(file_obj.name,'wb') as f:
                for chunk in fille_obj.chunks():
                    f.write(chunk)
         return render(request,'up.html')

    前端页面

    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile">
    </form>

    FBV与CBV

    FBV与CBV

    FBV

    基于函数的视图,一直介绍的是FBV

    CBV

    url(r'^reg/',views.MyReg.as_view())

    基于类的视图

    urls.py

    from django.urls import path,register_converter
    from app01 import views
    
    url = [
        url('r^login/',view.MyReg.as_view())
    ]
    #必须调用类下的方法as_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(自己写的类产生的对象,'小写的请求方法(getpost)','获取不到对应的方法就报错')
                # handler就是我们自己定义的跟请求方法相对应的方法的函数内存地址
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)  # 在调用获取到的方法
    
    django settings源码分析及实际应用(你可以不掌握 但是我希望你掌握思路)
        
        django的配置文件有两个
            一个是暴露给用户可以自定义配置的
            一个是默认的全局配置文件
                用户指定了就用用户的
                用户没有指定就用默认的
                

    Django settings源码分析及实际应用

    Django的配置文件有两个

    一个是暴露菇用户可以自定义的
    一个是全局的配置文件

    用户指定了就用用户的,没有指定就用全局的

    from django.conf import settings
        settings = LazySettings()
    
    
     class LazySettings(LazyObject):
            
            def _setup(self, name=None):
         
                # os.environ你可以把它看成是一个全局的大字典
                settings_module = os.environ.get(ENVIRONMENT_VARIABLE)  # 从大字典中取值
                # settings_module = 'day59.settings'
      
                self._wrapped = Settings(settings_module)  # Settings('day59.settings')
        
        class Settings(object):
            def __init__(self, settings_module):  # settings_module = 'day59.settings'
                for setting in dir(global_settings):  # 循环获取global_settings文件中所有的名字
                    if setting.isupper():  # 在判断名字是否是大写
                        # 如果是大写 利用反射 获取到大写的名字所对应的值  不停地添加到对象中
                        setattr(self, setting, getattr(global_settings, setting))
                # store the settings module in case someone later cares
                self.SETTINGS_MODULE = settings_module
                mod = importlib.import_module(self.SETTINGS_MODULE)  # 'day59.settings'
                # from day59 import settings
                # mod 指代的就是暴露给用户的配置文件模块名
               
                for setting in dir(mod):  # 循环获取暴露给用户配置文件中所有的名字
                    if setting.isupper():  # 判断是否是大写
                        setting_value = getattr(mod, setting)  # 如果是大写 获取大写的变量名所对应的值
                        setattr(self, setting, setting_value)  # 不停的给对象设置值
       

    模板传值

    模板传值可以传数字、字符串、字典、集合、列表、函数、类等

    如果传递给 前端一个函数名,会直接加括号调用,将返回值展示到页面上

    Django模板语法不支持传参

    Django模板语法在获取容器类型内部元素的值得时候只能通过句点符取值

    过滤器(|)

    过滤器有点类似于小的内置方法

    特点:会将|左边的当做过滤器的第一个元素,会将|右边的当做过滤器的第二个元素

    eg:

    add:加

    <p>{{n|add:100}}</p> 

    length:长度

    filesizeformat:文件转大小

    truncatechars:6截取6个字符,3个点也算

    truncatewords:6截取单词,按照空格截取,3个点不算

    slice:0:3:对列表进行索引取值,还可以支持步长

    date:'Y-m-d' 时间格式转换

    前端:

    safe前后端取消转义

    后端:

    from django.utils.safestring import mark_safe

    res=makesafe(变量名),把res传到前端

    default:你给我的值是空的:有值就传值,没值就用后面默认的

    注意:

    模板语法的符号就两种
              {{}}  变量相关
              {%%}  逻辑相关

    标签

    前端if 标签

    {% if n %}
        <p>n有值</p>
    {% else %}
        <p>n没有值</p>
    {% endif %}

    if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

    {% if n %}
        <p>n有值</p>
    {% elif m%}
        <p>m有值</p>
    {% else %}
        <p>没有值</p>
    {% endif %}

    前端for标签

    遍历每一个元素

    {% for person in person_list %}
        <p>{{ person.name }}</p>
    {% endfor %}

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

    {% for foo in l %}
        {% if forloop.first %}   #forloop.first为True的时候
            <p>这是我的第一次</p>
        {% elif forloop.last %}    #forloop.last为True的时候
            <p>这是最后一次了啊</p>
        {% else %}
            <p>嗨起来 大宝贝~</p>
        {% endif %}
    {% endfor %}

    for标签可以带有一个可选的{% empty %} 从句,在变量xo为空或者没有被找到时,则执行empty子句

    {% for foo in xo %}
        <p>{{ forloop.counter }}:{{ foo }}</p>
        {% empty %}
        <p>你给我的对象是个空的没法进行for循环</p>
    {% endfor %}

    还可以循环字典中的键值对,键、值

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

    前端with标签

    with标签用来为一个复杂的变量名起别名,如果变量的值来自于数据库,在起别名后只需要使用别名即可,无需每次都向数据库发送请求来重新获取变量的值,如果你要重复利用一个很复杂的值,你就可以给这个值起一个别名,到时候直接用别名就好了

    {% with li.1.upper as v %}
        {{ v }}
    {% endwith %}

    自定义过滤器、标签

    步骤:(******)

    • 在应用名下面新建一个templatetags文件夹(必须)
    • 在该文件夹下新建一个任意名称的py文件
    • 在该py文件内 固定先写两行代码
    from Django.template import Library
    
    register = Library()

    自定义的过滤器

    自己新建的文件

    @registe.filter(name = 'myplus')
    def index(a,b):
        return a+b

    前端页面

    {% load my_tag %}
    {{123|myplus:123 }}

    自定义标签

    自己新建的文件

    @registe.simple_tag(name = 'mysm')
    def login(a b c d):
        return '%s %s %s %s'%(a b c d)

    前端页面

    {% mysm 1 2 3 4 %}

    自定义的过滤器和自定义标签

    自定义的过滤器可以在if中使用,自定义标签不能在if中使用。

    eg:

     {% if 0|myplus:123 %}  可以用
                <p>有值</p>
            {% endif %}
    {% if mysm 1 2 3 4 %}  不能用
               <p>有值</p>
           {% endif %}

    模板的继承

    事先需要在模板中通过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' %}

    Django请求生命周期

  • 相关阅读:
    友盟—安卓巴士【Android开发原创教程大赛】
    iOS开发视频教程下载/iphone开发视频教程下载
    发一个Android开发的外包项目。欢迎外包团队来骚扰
    安卓巴士总结了近百个Android优秀开源项目,覆盖Android开发的每个领域
    安卓巴士精选Android开发教程
    做了一个系列的Android开发教程列表
    深刻理解C#的传值调用和传引用调用
    《CLR Via C# 第3版》笔记之(四) 类中字段的默认赋值
    《CLR Via C# 第3版》笔记之(七) const和readonly
    《CLR Via C# 第3版》笔记之(十二) 事件
  • 原文地址:https://www.cnblogs.com/lulingjie/p/11766255.html
Copyright © 2011-2022 走看看