• Django框架


    今日内容:

    模板层(模板语法)标签过滤器自定义标签,过滤器,inclusion_tag模板的继承

    模板的导入


    首先来说一下render内部原理和FBV与CBV

    三板斧  
    FBV
    render返回一个html页面 并且还能够给该页面传数据 render内部原理
    from django.template import Template,Context def index(request): temp = Template('<h1>{{ user }}</h1>') con = Context({"user":{"name":'jason',"password":'123'}}) res = temp.render(con) print(res) return HttpResponse(res)

    FBV与CBV

    FBV与CBV
    视图函数并不只是指函数,也可以是类
      FBV(基于函数的视图)面向函数式编程
      CBV(基于类的视图)面向对象式编程
      # 问题:基于CBV的视图函数
      get请求来就会走类里面的get方法,post请求来就会走类里面post方法,这是为什么了???

    #
    CBV
    urls.py中 url(r'^login/',views.MyLogin.as_view()) views.py中 from django.views import View
    from django.views import View # from django.conf import settings class MyLogin(View): def get(self,request): print("from MyLogin get方法") return render(request,'login.html') def post(self,request): return HttpResponse("from MyLogin post方法")

    研究方向:

    1.从url入手

    View Code

    什么settings里面的变量都要用大写的,用小写的没用:

    django settings源码

     1     django settings源码
     2         前提:
     3             1.django除了暴露给用户一个settings.py配置文件之外  自己内部还有一个全局的配置文件
     4             2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多
     5                 from django.conf import settings
     6             3.django的启动入口是manage.py 
     7             
     8         import os
     9         import sys
    10 
    11         if __name__ == "__main__":
    12             # django在启动的时候 就会往全局的大字典中设置一个键值对  值是暴露给用户的配置文件的路径字符串
    13             os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
    14         
    15         class Settings(object):
    16             def __init__(self, settings_module):  # settings_module = 'day54.settings'
    17                 # update this dict from global settings (but only for ALL_CAPS settings)
    18                 for setting in dir(global_settings):  # django全局配置文件
    19                     # dir获取django全局配置文件中所有的变量名
    20                     if setting.isupper():  # 判断文件中的变量名是否是大写 如果是大写才会执行/生效
    21                         setattr(self, setting, getattr(global_settings, setting))  # 给settings对象设置键值对
    22                         # 给settings对象设置键值对  settings[配置文件中大写的变量名] = 配置文件中大写的变量名所对应的值
    23 
    24                 # store the settings module in case someone later cares
    25                 self.SETTINGS_MODULE = settings_module  # 'day54.settings'
    26 
    27                 mod = importlib.import_module(self.SETTINGS_MODULE)  # mod = 模块settings(暴露给用户的配置文件)
    28                 for setting in dir(mod):  # for循环获取暴露给用户的配置文件中所有的变量名
    29                     if setting.isupper():  # 判断变量名是否是大写
    30                         setting_value = getattr(mod, setting)  # 获取大写的变量名所对应的值
    31                         setattr(self, setting, setting_value)  # 给settings对象设置键值对
    32                         """
    33                         d = {}
    34                         d['username'] = 'jason'
    35                         d['username'] = 'egon'
    36                         用户如果配置了就用用户的
    37                         用户如果没有配置就用系统默认的
    38                         其实本质就是利用字典的键存在就是替换的原理 实现了用户配置就用用户的用户没配置就用默认的
    39                         """
    40             
    41         class LazySettings(LazyObject):
    42                 def _setup(self, name=None):
    43                     # os.environ你可以把它看成是一个全局的大字典
    44                     settings_module = os.environ.get(ENVIRONMENT_VARIABLE)  # 从大字典中取值键为DJANGO_SETTINGS_MODULE所对应的值:day54.settings
    45                     # settings_module = 'day54.settings'
    46                     self._wrapped = Settings(settings_module)  # Settings('day54.settings')
    47 
    48 
    49         settings = LazySettings()  # 单例模式    
    View Code

    模板层

    模板语法:一共分为俩大类
    {{ }} 跟变量相关的
    {%%} 跟逻辑相关的

    后端给前端传值的方式:

    后端朝前端页面传递数据的方式
        # 第一种
        return render(request,'index.html',{'n':n})
        # 第二种
        return render(request,'index.html',locals())  
        # 将当前所在的名称空间中的名字全部传递给前端页面
        
        后端传函数名到前端,会自动加括号调用,但是不支持传参

    详情代码:

    前端:

     1 <p>{{ n }}</p>
     2 <p>{{ f }}</p>
     3 <p>{{ s }}</p>
     4 <p>{{ l }}</p>
     5 <p>{{ d }}</p>
     6 <p>{{ t }}</p>
     7 <p>{{ se }}</p>
     8 <p>{{ index }}</p>
     9 
    10 <p>{{ obj }}</p>
    11 <p>{{ obj.get_self }}</p>
    12 <p>{{ obj.get_cls }}</p>
    13 <p>{{ obj.get_static }}</p>
    View Code

    后端:

     1 def reg(request):
     2     # 以下的数据类型都是可以被传递给前端的
     3     n = 0
     4     # ss = ''
     5     f = 1.11
     6     s = '你妹的'
     7     l = [1, 2, 3, 4, 5, 6]
     8     d = {"name": 'jason', 'password': 123}
     9     t = (1, 2, 3, 4, 5)
    10     se = {1, 2, 3, 4, 5, 6, 7, }
    11 
    12     def index():
    13         print('index')
    14 
    15     class Demo(object):
    16         def get_self(self):
    17             return '绑定给对象的方法'
    18         @classmethod
    19         def get_cls(cls):
    20             return '绑定给类的方法'
    21         @staticmethod
    22         def get_static():
    23             return '我是静态方法  其实就是函数'
    24     obj = Demo()
    25 
    26     # 给模板传值的方式
    27     # 方式1 通过字典的键值对方式,然后指名道姓的一个个传
    28     # return render(request,'reg.html',{'n':n,'f':f})
    29     # 方式2 而用一下locals()会将它所在的名称空间中所有的名字全部传递给前端
    30     # 这个方法虽然好用,但是在某些情况下会造成资源的浪费,这里只是为了
    31     return render(request,'reg.html',locals())
    View Code

    模板语法之过滤器:

    前端:
        |safe
    后端:
       from django.utils.safestring import mark_safe
       zzz = mark_safe('<h1>阿萨德搜啊第三款垃圾袋</h1>')
    
    <h1>模板语法之过滤器:它内部的原理就是(会将|前面的当做第一个参数传入标签中)</h1>
    <p>{{ l|length }} 计算标签内的数据是多长 </p>
    <p>{{ n|length  }}必须要是放在容器里面才能计算长度</p>
    <p>{{ ss|default:'当|左边的变量为空时,就会返回|右边的值'}}</p>
    <p>{{ file_size|filesizeformat }} 就相当于是一个转换,把kb转为mb</p>
    <p>{{ info|truncatewords:3}} 按照空格截取内容的 三个点不算</p>
    <p>{{ info|truncatechars:9 }}按字符截取内容的 三个点也算 </p>
    <p>{{ xxx|safe }}前端取消转义 </p>
    <p>{{ yyy|safe}} 前端取消转义</p>
    <p>{{ zzz }} 这个在后端取转义了</p>
    <p>{{ time }}</p>
    <p>{{ time|date:'Y-m-d' }} 只需要掌握年月日就可以了</p>
    <p>{{ n|add:100 }} 做数字相加</p>
    <p>{{ s|add:'大傻叉' }} 做字符串拼接</p>
    <p>{{ l|slice:'0:3' }}切片取值</p>
    <p>{{ l|slice:'0:5:2' }}切片取值</p>

    后端详细代码:

     1 def reg(request):
     2     # 以下的数据类型都是可以被传递给前端的
     3     n = 0
     4     ss = ''
     5     f = 1.11
     6     s = '你妹的'
     7     l = [1, 2, 3, 4, 5]
     8     d = {"name": 'jason', 'password': 123}
     9     t = (1, 2, 3, 4, 5)
    10     se = {1, 2, 3, 4, 5, 6, 7, }
    11     file_size = 12312312
    12     info = 'my name is zy'
    13     xxx = '<h1>呃呃呃呃呃</h1>'
    14     yyy = '<script>alert(123)</script>'
    15 
    16     from django.utils.safestring import mark_safe
    17     zzz = mark_safe('<h1>你是弱智</h1>')
    18     from datetime import datetime
    19     time=datetime.now()
    20 
    21     return render(request,'reg.html',locals())
    View Code

    模版语法之标签(逻辑相关):

    for 循环执行流程图:

    # for 循环
    {% for s in l %}
        <p>{{ forloop }}</p> # forloop可以看到for循环的执行流程
        {{ s }}
    {% endfor %}
    
    # if else  判断 对象有值就走true  对象为空就走false
    {% if '' %}
    <p>xxx条件为true</p>
        {% else %}
        <p>xxx条件为false</p>
    {% endif %}
    
    #for 循环里面可以套if elif  else  判断是for循环是否为第一次和最后一次
    #如果判断对象为空,就走empty
    {% for foo in '' %}
        {% if forloop.first %}
            <p>这是我的第一次</p>
            {% elif forloop.last %}
            <p>这是最后一次了啊</p>
            {% else %}
            <p>来啊来啊!!!</p>
        {% endif %}
        {% empty %}
        <p>当for循环的对象为空的时候 会走empty</p>
    {% endfor %}
    
    #django模板语法在取值的时候 统一使用句点符(大白话就是 点号   .)
    #俩种写法  
    1.
    {{l.6.3.name}}
    但是这么写,如果多个地方需要取到的值,太麻烦了
    2.
    <p>
        {% with l.6.3.name as ttt %}  可以给一个比较复杂的取值操作取一个别名 之后在with语句中 就可以使用该别名
            {{ ttt }}
        {% endwith %}
    </p>
    
    
    # for 循环环也支持循环字典 对象.kyes values items
    {% for foo in d.keys %}
        <p>{{ foo }}</p>
    {% endfor %}
    {% for foo in d.values %}
        <p>{{ foo }}</p>
    {% endfor %}
    {% for foo in d.items %}
        <p>{{ foo }}</p>
    {% endfor %}

    后端详细代码:

     1 def reg(request):
     2     # 以下的数据类型都是可以被传递给前端的
     3     n = 0
     4     ss = ''
     5     f = 1.11
     6     s = '你妹的'
     7     l = [1,2,3,4,5,6,[12,3,4,{'name':'heiheihei'}]]
     8     d = {"name": 'jason', 'password': 123}
     9     t = (1, 2, 3, 4, 5)
    10     se = {1, 2, 3, 4, 5, 6, 7, }
    11     file_size = 12312312
    12     info = 'my name is zy'
    13  
    14     
    15     return render(request,'reg.html',locals())
    View Code

    自定义过滤器的使用:

    自定义标签 过滤器 inclusion_tag
    自定义固定的三步骤(重点)
        1.必须在你的应用下新建一个名为templatetags文件夹
        2.在该文件夹内新建一个任意名称的py文件
        3.在该py文件中固定先写下面俩句代码
        from  django import template                
        register = template.Library()

    |length
    |add
    |default
    |filesizeformat
    |truncatewords
    |truncatechars
    |safe
    |slice

    自定义过滤器,自定义标签,自定义inclusion_tag:

    后端:
    # 自定义过滤器
    @register.filter(name='baby')
    def index(a,b):
        # 这个过滤器只是做一个简单的加法运算
        return a + b
    
    前端:
    {% load mytage %}
    {{ 123|baby:1 }}
    
    注意:
    自定义过滤器 只能由两个形参
        但是你可以在给第二个参数传值的时候 传一个字符串
        只要思想不滑坡
        方法总比困难多
        {{ 123|baby:'1|2|3|4|5|6'}}

    自定义标签:

    后端:
    # 它可以支持传多个值
    @register.simple_tag(name='zy')
    def zzz(a,b,c,year):
        return '%s %s %s %s'%(a,b,c,year)
    前端:
    {#支持传多个值,参数与参数之间必须要用空格隔开#}
    {% load mytage %}
    {% zy 1 2 3 year=5 %}

    自定义inclusion_tag:

    当你的页面上有一部分html代码需要经常被各个inclusion_tag地方使用  并且需要传参才能渲染出来
        那么你可以把该html代码部分制作成一个inclusion_tag
        任何页面都能使用
    
    后端:
    #自定义inclusion_tag
    @register.inclusion_tag('bigplus.html')
    def bigplus(n):
        l=[]
        for i in range(n):
            l.append('第%s项'%i)
        return {'l':l}
    
    前端bigplus里面:
    <ul>
        {% for foo in l %}
            <li>{{ foo }}</li>
        {% endfor %}
    </ul>
    前端reg里面:
    {% load mytag %}
    {% bigplus 5 %}

    模板的继承(重点):

    当多个页面整体的样式都大差不差的情况下,可以设置一个模板文件,在该模板文件中,
    使用block块划分多个区域,之后其他子版要使用模板的时候,可以通过block块的名字,
    来选定到底需要修改那一部分区域。 模板一般情况下,应该至少有三个可以被修改的区域
    1. {% block css %} 子页面自己的css代码 {% endblock %} 2. {% block content %} 子页面自己的html代码 {% endblock %} 3. {% block js %} 子页面自己的js代码 {% endblock %}
    注意:

    一般情况下 模板上的block越多,页面的可扩展性就越强

    模板的导入:

    模板的导入
    {% include 'beautiful.html' %}
    
    当你写了一个特别好看的form表单/列表标签等
    可以将它当成一个模块 哪个地方需要 就直接导入使用即可

    模型层:

    单表操作:

    1.单表操作
    create_time = models.DateField()
      关键性的参数
      1.auto_now:每次操作数据 都会自动刷新当前操作的时间
       2.auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段
    
    ps:在django中 你可以写一个单独测试某一个py文件的测试脚本 不需要再频繁的走web请求


    查看orm内部sql语句的方法有哪些
    
    1.如果是queryset对象 那么可以点query直接查看该queryset的内部sql语句
    
    2.在django项目的配置文件中 配置一下参数即可实现所有的orm在查询的时候自动打印对应的sql语句
    
    直接把以下代码拷贝就可以了
     1 LOGGING = {
     2                     'version': 1,
     3                     'disable_existing_loggers': False,
     4                     'handlers': {
     5                         'console':{
     6                             'level':'DEBUG',
     7                             'class':'logging.StreamHandler',
     8                         },
     9                     },
    10                     'loggers': {
    11                         'django.db.backends': {
    12                             'handlers': ['console'],
    13                             'propagate': True,
    14                             'level':'DEBUG',
    15                         },
    16                     }
    17                 }
    View Code

     

    必知必会13条:

    1.all():
    查询所有的结果
    2.filter(**kwargs):
    它包含了所给筛选条件相匹配的对象,传入的是字典的格式(**kwargs)
    3.get(**kwargs):
    返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
    4.exclude(**kwargs):
    exclude就是取反的意思,拿到除了这个其他所有对象的请求集合
    5.values():
    返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列,values相当于查找某一特定字段的所有值
    6.values_list():
    它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
    7.order_by():
    对查询结果排序
    8.reverse():
    对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
    9.distinct():
    去重的意思,必须一模一样
    10.count():
     返回数据库中匹配查询的对象数量。
    11.first():
    返回第一条记录
    12.last():
    返回最后一条记录
    13.exists():
    如果包含数据,就返回True,否则返回False。没什么用
    
    返回QuerySet对象的方法有:
    all()
    filter()
    exclude()
    order_by()
    reverse()
    distinct()
    特殊的QuerySet
    
    values()       返回一个可迭代的字典序列
    values_list() 返回一个可迭代的元祖序列
    返回具体对象的
    get()
    first()
    last()
    
    返回布尔值的方法有:
    exists()
    
    返回数字的方法有
    count()

    增删改查操作详情:

     1 import os
     2 import sys
     3 
     4 if __name__ == "__main__":
     5     # django在启动的时候 就会往全局的大字典中设置一个键值对  值是暴露给用户的配置文件的路径字符串
     6     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
     7 
     8     import django
     9     django.setup()
    10     from app01 import models
    11     models.Book.objects.all()
    12     #
    13     # 方式1: create
    14     # book_obj  = models.Book.objects.create(title='三国',price=19.99,create_time='2019-11-11')
    15     # print(book_obj.title)
    16     # 方式2:对象点save()方法
    17     # from datetime import datetime
    18     # ctime = datetime.now()
    19     # book_obj = models.Book(title='金瓶',price=96.66,create_time=ctime)
    20     # book_obj.save()
    21 
    22     #
    23     # print(models.Book.objects.all())
    24     # print(models.Book.objects.get(id=1))
    25     # print(models.Book.objects.get(pk=1))
    26     """
    27     pk会自动查找到当前数据的主键字段
    28     """
    29     # print(models.Book.objects.filter(pk=2))
    30 
    31     #
    32     # 1.update
    33     # models.Book.objects.filter(pk=1).update(title='三国演义')
    34     # 2.对象.save()
    35     # book_obj = models.Book.objects.get(pk=1)
    36     # book_obj.price = 666.66
    37     # book_obj.save()
    38 
    39     # 删除  delete()
    40     # models.Book.objects.filter(pk=2).delete()
    41 
    42     # < 1 > all(): 查询所有结果
    43 
    44     # < 2 > filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
    45     # < 3 > get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
    46     # < 4 > exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
    47     # print(models.Book.objects.exclude(pk=1))  # 只要pk不是1的数据全部查询出来
    48 
    49 
    50     # < 5 > order_by(*field): 对查询结果排序('-id') / ('price')
    51     # print(models.Book.objects.order_by('price'))  # 默认是升序
    52     # print(models.Book.objects.order_by('-price'))  # 加负号就是降序
    53 
    54 
    55     # < 6 > reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
    56     # print(models.Book.objects.order_by('price').reverse())
    57 
    58     # < 7 > count(): 返回数据库中匹配查询(QuerySet)
    59     # print(models.Book.objects.count())  # 对查询出来的结果进行一个计数
    60 
    61 
    62     # 的对象数量。
    63     # < 8 > first(): 返回第一条记录
    64     # print(models.Book.objects.filter(pk=1).first())
    65     # < 9 > last(): 返回最后一条记录
    66     # print(models.Book.objects.all())
    67     # print(models.Book.objects.all().last())
    68 
    69     # < 10 > exists(): 如果QuerySet包含数据,就返回True,否则返回False
    70     # print(models.Book.objects.filter(pk=1000))
    71     # print(models.Book.objects.filter(pk=1000).exists())
    72 
    73 
    74     # < 11 > values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
    75     # model的实例化对象,而是一个可迭代的字典序列
    76     # print(models.Book.objects.values('title','price'))  # 得到的结果是列表套字典
    77 
    78 
    79 
    80     # < 12 > values_list(*field): 它与values()
    81     # print(models.Book.objects.values_list('title','price'))  # 得到的结果是列表套元组
    82 
    83 
    84     # 非常相似,它返回的是一个元组序列,values返回的是一个字典序列
    85     # < 13 > distinct(): 从返回结果中剔除重复纪录
    86     """
    87     去重的前提是 一定要有完全重复的数据 才能去重
    88     """
    89     # print(models.Book.objects.filter(title='三国演义').distinct())
    90     # print(models.Book.objects.values('title','price','create_time').distinct())
    View Code

      

        

    # FBV
  • 相关阅读:
    buildroot的make menuconfig配置
    mac上如何设置ssh不断掉,并且session保持
    深度学习中网络设计的几点经验
    深度学习中将类别标签映射到one_hot向量
    python 过滤掉字符串中的回车符与换行符( )
    对训练集中的数据做随机抽样,并对抽样出的数据可视化观察分布情况
    利用Python的collections包下Counter的类统计每个数据出现的个数
    模型使用的数据集如何保证验证集和测试集的分布保持一致
    生成随机数的几个总结
    模型训练过程中的训练集、训练开发集、开发集和测试集总结
  • 原文地址:https://www.cnblogs.com/zahngyu/p/11546334.html
Copyright © 2020-2023  润新知