Django框架4

目录

  • Django框架4
    • 一.render简单实现
    • 二.CBV与FBV
    • 三.CBV源码
    • 四.基于django settings 源码应用到自己的项目中
    • 五.模板语法的传值
    • 六.过滤器
    • 七.标签
    • 八.自定义过滤器及标签
    • 九.模板的继承
    • 十.模板的导入

Django框架4


一.render简单实现

from django.shortcuts import render,HttpResponse
from django.template import Template, Context

def db_render(request):
    temp = Template("

{{user_dic}}{{user_dic.username}}{{user_dic.password}}

") user_dict = Context( { 'user_dic': { 'username': 'jason', 'password': 1123, } } ) res = temp.render(user_dict) return HttpResponse(res)

结果展示:

二.CBV与FBV

视图函数不一定就是函数,也可以是类

fbv: 基于函数的视图

cbv: 基于类的视图

cbv基本的写法:

from django.views import View


class MyLogin(View):

    def get(self, request):
        return render(request, 'login_cbv.html')

    def post(self, request):
        return HttpResponse('我是类里面的post方法')

前端代码




    
    Title
    
    
      


    

这里是login_cbv页面

提交

朝着login_cbv提交get请求时会自动执行MyLogin里面的get方法

而提交post请求也会自动执行MyLogin里面的post方法

为什么MyLogin针对不同的请求方法能够自动执行对应的方法,引入cbv源码

三.CBV源码

研究源码的突破口:
url(r'^login_cbv', view.MyLogin.as_view())

​ 猜想

​ as_view要么是类里面定义的普通函数 @staticmethod

​ 要么是类里面定义的绑定给类的方法 @classmethod

看到源码发现是类的绑定方法

详细步骤注释图解:

Django框架4_第1张图片

Django框架4_第2张图片

Django框架4_第3张图片

Django框架4_第4张图片

流程详情:

fbv与cbv在路由匹配上本质是一样的

# 首先MyLogin是我们自己创建的类,里面写了get与post方法
# 然后这个类继承了View类,所以调用了View里面的as_view方法
# as_view方法返回的是View类里的闭包函数view的地址值
# 所以url(r'^login/',views.MyLogin.as_view())就相当于:url(r'^login/',views.view)
# 正则匹配到login后,调用view函数,首先生成了一个我们自己创建的类的对象,self,接着给self对象添加属性,再通过对象.属性调用方法dispatch方法,对象以及产生对象的类中没有这个方法,所有调用了父类中的dispatch方法
# 在displatch中首先判断请求的请求方式是否在默认的八大请求方式中,再在对象中找到对应的请求方法post或get,display返回的是请求方式()就是执行了请求方法
所以:
    朝着login_cbv提交get请求时会自动执行MyLogin里面的get方法

而提交post请求也会自动执行MyLogin里面的post方法

CBV源码(******)
MyClass.as_view()
# 函数名加括号执行优先级最高
@classonlymethod
def as_view(...):
def view(...):
...
return view
# 变形
url(r'^index/',views.view) # CBV与FBV在路由匹配上本质是一样的

            def view(...):
                self = cls(...)  # 生成的是我们自己写的类的对象
                ...
                return self.dispatch(...)
                """
                当你看到self.属性或方法的时候 不要想当然 
                一定要遵循对象的属性和方法的查询顺序
                对象本身  产生对象的类  类的父类
                """
            def dispatch(...):
                # 先判断当前请求方式是否在默认的八个合法请求方式内
                if request.method.lower() in ['get','post','delete','options'...]
                    # 利用反射获取对象中对应的属性
                    handler = getattr(self,request.method.lower(),报错信息)
                
                return handler(...)  # 执行获取到的方法
                

四.基于django settings 源码应用到自己的项目中

​ django暴露给用户一个可以自定义的配置,但是内部也有一个默认的配置

​ 用户配置了就用用户的, 用户没有配置就用默认的

django settings源码
django其实有两个配置文件 一个是暴露给用户的可以自定义的配置 一个是项目默认的配置
用户如果配置了就用用户的 没有配置就用默认的

    from django.conf import global_settings,settings
    
    settings = LazySettings()
    
    
    class LazySettings(...):
        def _setup(...):
            # 获取暴露给用户的配置文件字符串路径
            setting_module = os.environ.get(纯大写变量名)
            """
            manage.py
            os.environ.setdefault(纯大写变量名,'暴露给用户的配置文件字符串路径')
            """
            
            Settings(setting_module)
    def Settings(...)
        # 先遍历全局默认的配置文件       给对象设置键值对
        for setting in dir(global_settings):
            if setting.isupper():
                setattr(self,setting,getattr(global_settings,setting))
                
        
        # 再遍历暴露给用户的配置文件     给对象设置键值对
        md = importlib.import_module(setting_module)
        for setting in dir(md):
            if setting.isupper():
                setattr(self,setting,getattr(md,setting))
        """
        利用的其实就是字典的键存在和不存在 下面语句的作用
        dict[key] = value
        """
    

五.模板语法的传值

模板语法符号

​ {{ }} 变量相关

​ {% %} 逻辑相关

模板层之模板传值

{#模板语法的注释 这个注释前端浏览器检查是看不见的#}

​ python基本数据类型全部支持传递给html文件

​ 函数与类:

​ 函数和类会自动添加括号执行

​ 函数得到的是函数的返回值,而类得到的是它的对象

​ 模板语法不支持传参

后端给html文件传递数据的两种方式:

1.指名道姓

​ return render(request, 'index.html', {'n':n, 'm':m})

2.locals() 会将当前名称空间中所有的变量名全部传递给html页面

​ return render(request, 'index.html', locals())

html页面上 如何获取到后端传递过来的数据

{{变量名}}

取值:

​ django模板语法取值 只有一种操作方式 句点符

​ 点索引

​ 点键

​ 示例:

            

{{ l.2 }}

{{ d.username }}

{{ d.password }}

{{ d.hobby.1.username.1 }}

六.过滤器

|... 格式要规范,不可乱加空格

过滤器 |左边的会当做过滤器的第一个参数 过滤器名右边的会当做过滤器的第二个参数

求数据长度:

{{ s|length }}

加法运算:

{{ n|add:12 }}, 两个整型是相加求和 {{ s|add:'da'}} 两个字符串是拼接 如果一个是字符串一个是整型会报错

默认值(判断值是否为空): 如果前面的值是空,则返回:后面的,如果前面的值不为空,则返回:前面的

{{ b|default:'这个b布尔值是true'}}, {{ ff|default:'这个ff布尔值是false'}}

截取字符(截取5个字符 三个点也算):

{{ s|truncatechars:8 }},

截取单词 (截取4个单词 三个点不算): 以空格为一个单词结束

{{ ss|truncatewords:4 }}

文件大小:

{{ file_size|filesizeformat }}

切片操作:

{{ s|slice:'0:2' }}, {{ s|slice:'0:8:2'}}

日格式化:

{{ ddd|date:'Y年/m月/d日' }}

转义:直接传前端语法,为防止恶意脚本,传过去并不执行, 除非后端用mark_safe()来包装一下 或者前端用|safe来表示安全

{{ res|safe }}, {{res1}},{{res2}}

ps:前端代码不一定非要在前端页面写,可以在后端写好传递给前端页面使用,这样就可以利用到后端更加多的逻辑语法

七.标签

逻辑相关的

{% for foo in l %}
    {% if forloop.first %}
        

第一次

{% elif forloop.last %}

最后一次

{% else %}

{{foo}}

{% endif %} {% empty %}

for循环的对象内部没有值

{% endfor %}

八.自定义过滤器及标签

标签 inclusion_tag

先完成以下前期准备工作

​ 1.在应用名下新建一个名字必须叫templatetags文件夹

​ 2.在该文件内新建一个任意名称的py文件夹(mytag)

​ 3.在该文件内 必须先写以下两行代码

​ from django.template import Library

​ register = Library()

# 自定义过滤器
@register.filter(name='my_sum')
def index(a,b):
    return a+b

# 自定义标签
@register.simple_tag(name='my_baby')
def xxx(a,b,c,d):
    return '%s?%s?%s?%s'%(a,b,c,d)

# 自定义inclusion_tag
@register.inclusion_tag('test.html', name='myin')
def index1(n):
    l=[]
    for i in range(n):
        l.append(i)
    return {'l':l}

使用方法

自定义过滤器的使用
{% load mytag %}

{{ 10|my_sum:90 }}

自定义标签的使用 {% load mytag %}

{% my_baby 1 2 3 'hello world' %}

自定义的过滤器可以在逻辑语句中而自定义的标签不可以

{% if 10|my_sum:100 %}

条件成立

{% endif %} {% if my_baby 1 2 3 4 %}

条件成立

{% endif %} 自定义inclusion_tag的使用

{% load mytag %} {% myin 5 %}

总结 页面上想要使用他们 要统一导入 {% load mytag %}

九.模板的继承

​ 某一个页面大部分区域是公用的 那这个页面就可以作为模板页面

当别人继承这个页面之后 再修改对应的区域

先在模板页面上通过block实现划定区域
    {% block content %}
        模板页面的内容
    {% endblock %}

子页面中先导入整个模块
    {% extends '模板页面.html' %}
    修改特定的区域 通过实现划定好的区域名称
    {% block content %}
        子页面内容
    {% endblock %}

通常情况下 模板页面应该起码有三块区域
    {% block css %}
        模板页面内容
    {% endblock %}

    {% block content %}
        模板页面内容
    {% endblock %}

    {% block js %}
        模板页面内容
    {% endblock %}

    # 模板的block块越多 可扩展性越高
    
    还支持子页面调用父页面对应区域的内容 并且可以无限次调用
        {{ block.super }}

十.模板的导入

​ 将hml页面当做模块来使用 哪里需要倒哪里 这个html页面通常都不是完整的 只是一个局部样式

{% include 'left.html' %}

你可能感兴趣的:(Django框架4)