• Django 模板层


    FBV与CBV
                视图函数并不只是指函数 也可以是类
                    FBV(基于函数的视图) 面向函数式编程
                    CBV(基于类的视图)   面向对象式编程

    urls.py中
    url(r'^login/',views.MyLogin.as_view())
    views.py中
    from django.views import View
    
    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入手
    url(r'^login/',views.MyLogin.as_view())  由于函数名加括号执行优先级最高,所以这一句话一写完会立刻执行as_view()方法
    @classonlymethod
    def as_view(cls, **initkwargs):  # cls就是我们自己的写的类 MyLogin
    def view(request, *args, **kwargs):
        self = cls(**initkwargs)  # 实例化产生MyLogin的对象  self = MyLogin(**ininkwargs)
    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)  # dispatch返回什么 浏览器就会收到什么
    # 对象在查找属性或者方法的时候 你一定要默念 先从对象自己这里找  然后从产生对象的类里面找  最后类的父类依次往后
        return view                    
    通过源码发现url匹配关系可以变形成
        url(r'^login/',views.view)  # FBV和CBV在路由匹配上是一致的 都是url后面跟函数的内存地址
    2.当浏览器中输入login 会立刻触发view函数的运行
    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        # 我们先以GET为例
        if request.method.lower() in self.http_method_names:  # 判断当前请求方法是否在默认的八个方法内
        # 反射获取我们自己写的类产生的对象的属性或者方法
        # 以GET为例  handler = getattr(self,'get','取不到报错的信息')
        # handler = get(request)
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        return handler(request, *args, **kwargs)  # 直接调用我们自己的写类里面的get方法
        # 源码中先通过判断请求方式是否符合默认的八个请求方法 然后通过反射获取到自定义类中的对应的方法执行

    django settings源码
                前提:
                    1.django除了暴露给用户一个settings.py配置文件之外  自己内部还有一个全局的配置文件
                    2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多
                        from django.conf import settings
                    3.django的启动入口是manage.py

    import os
    import sys
    
    if __name__ == "__main__":
    # django在启动的时候 就会往全局的大字典中设置一个键值对  值是暴露给用户的配置文件的路径字符串                                                                                      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
                
    class Settings(object):
        def __init__(self, settings_module):  # settings_module = 'day54.settings'
        # update this dict from global settings (but only for ALL_CAPS settings)
            for setting in dir(global_settings):  # django全局配置文件
            # dir获取django全局配置文件中所有的变量名
                if setting.isupper():  # 判断文件中的变量名是否是大写 如果是大写才会执行/生效
            setattr(self, setting, getattr(global_settings, setting))  # 给settings对象设置键值对
            # 给settings对象设置键值对  settings[配置文件中大写的变量名] = 配置文件中大写的变量名所对应的值
    
            # store the settings module in case someone later cares
            self.SETTINGS_MODULE = settings_module  # 'day54.settings'
    
            mod = importlib.import_module(self.SETTINGS_MODULE)  # mod = 模块settings(暴露给用户的配置文件)
            for setting in dir(mod):  # for循环获取暴露给用户的配置文件中所有的变量名
                if setting.isupper():  # 判断变量名是否是大写
                    setting_value = getattr(mod, setting)  # 获取大写的变量名所对应的值
                    setattr(self, setting, setting_value)  # 给settings对象设置键值对
                    """
                    d = {}
                    d['username'] = 'jason'
                    d['username'] = 'egon'
                    用户如果配置了就用用户的
                    用户如果没有配置就用系统默认的
                    其实本质就是利用字典的键存在就是替换的原理 实现了用户配置就用用户的用户没配置就用默认的
                    """
                    
        class LazySettings(LazyObject):
            def _setup(self, name=None):
            # os.environ你可以把它看成是一个全局的大字典
                settings_module = os.environ.get(ENVIRONMENT_VARIABLE)  # 从大字典中取值键为DJANGO_SETTINGS_MODULE所对应的值:day54.settings
                # settings_module = 'day54.settings'
                self._wrapped = Settings(settings_module)  # Settings('day54.settings')
                            
                    
        settings = LazySettings()  # 单例模式

    模板层
                模板语法
                    两大类:    {{}}  变量相关,     {%%}  逻辑相关      

    view.py文件
    def
    reg(request): # 先验证是否python所有的数据类型都可以被传递到前端 n = 0 # ss = '' f = 1.11 s = '你妹的' l = [1,2,3,4,5,6,[12,3,4,{'name':'heiheihei'}]] d = {"name":'jason','password':123} t = (1,2,3,4,5) se = {1,2,3,4,5,6,7,} file_size = 12312312 info = 'my name is jason and my age is 18' info1 = '傻大姐 撒旦 技术 大 萨达 了 奥斯卡 的健康两 三点卡是考虑到' def index(xxx): print(xxx) print('index') return '我是index函数的返回值' class Demo(object): def get_self(self): return '绑定给对象的方法' @classmethod def get_cls(cls): return '绑定给类的方法' @staticmethod def get_static(): return '我是静态方法 其实就是函数' obj = Demo() # 给模板传值的方式 # 方式1 # 通过字典的键值对 指名道姓的一个个的传 # return render(request,'reg.html',{'n':n,'f':f}) # 方式2 # locals会将它所在的名称空间中的所有的名字全部传递给前端 # 该方法虽然好用 但是在某些情况下回造成资源的浪费 xxx = '<h1>波波棋牌室</h1>' yyy = '<script>alert(123)</script>' from django.utils.safestring import mark_safe zzz = mark_safe('<h1>阿萨德搜啊第三款垃圾袋</h1>') from datetime import datetime ctime = datetime.now() return render(request,'reg.html',locals()) # 为了教学方便 我们以后就用locals()
    reg.html文件
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> {#<p>{{ n }}</p>#} {#<p>{{ f }}</p>#} {#<p>{{ s }}</p>#} {#<p>{{ l }}</p>#} {#<p>{{ d }}</p>#} {#<p>{{ t }}</p>#} {#<p>{{ se }}</p>#} {#<p>传函数名,会自动加括号调用该函数,前端展示的是函数调用之后的返回值:{{ index }}#} {# 注意:如果函数需要参数的话 那么不好意思 模板语法不支持#} {#</p>#} {#<p>{{ obj }}</p>#} {#<p>{{ obj.get_self }}</p>#} {#<p>{{ obj.get_cls }}</p>#} {#<p>{{ obj.get_static }}</p>#} {#<p>总结:django的模板语法 不支持给函数传参!!!</p>#}

    为模板传值 :过滤器:  | 

    前后端取消转义:
          前端:  |safe
           后端:
                   from django.utils.safestring import mark_safe
                   zzz = mark_safe('<h1>阿萨德搜啊第三款垃圾袋</h1>')             
                   |safe,   |filesizeformat,   |date       

    <br>
    {#<h1>模板语法之标签:内部原理(会将|前面的当做第一个参数传入标签中)</h1>#}
    {#<p>{{ l|length }}</p>#}
    {#<p>{{ n|length }}</p>#}
    {#<p>{{ ss|default:'当|左边的变量为空就会返回|右边的值' }}  default跟你后端get方法很想</p>#}
    {#<p>{{ ss|default:'' }} default必须要有两个参数</p>#}
    {#<p>{{ file_size|filesizeformat }}</p>#}
    {#<p>{{ info|truncatewords:3 }} 就是按空格截取  三个点不算</p>#}
    {#<p>{{ info1|truncatewords:3 }}</p>#}
    {##}
    {#<p>{{ info|truncatechars:6 }}按字符截取内容 三个点也算</p>#}
    {##}
    {#<p>{{ xxx|safe }}</p>#}
    {#<p>{{ yyy|safe }}</p>#}
    {#<p>{{ zzz }}</p>#}
    {##}
    {#<p>{{ ctime }}</p>#}
    {#<p>{{ ctime|date:'Y-m-d' }} 只需要掌握年月日就可以了</p>#}
    {##}
    {#<p>{{ n|add:100 }}</p>#}
    {#<p>{{ s|add:'hahah 翻车啦' }}</p>#}
    
    <p>{{ l|slice:'0:3' }}</p>
    <p>{{ l|slice:'0:5:2' }}</p>
       

    标签: {%%}

    <br>
    <h1>模板语法之标签(逻辑相关)</h1>
    {#{% for foo in l %}#}
    {#    <p>{{ forloop }}</p>#}
    {#{% endfor %}#}
    
    {#{% if '' %}#}
    {#<p>xxx条件为true</p>#}
    {#    {% else %}#}
    {#    <p>xxx条件为false</p>#}
    {#{% endif %}#}
    
    {##}
    {#{% for foo in '' %}#}
    {#    {% if forloop.first %}#}
    {#        <p>这是我的第一次</p>#}
    {#        {% elif forloop.last %}#}
    {#        <p>这是最后一次了啊</p>#}
    {#        {% else %}#}
    {#        <p>来啊来啊!!!</p>#}
    {#    {% endif %}#}
    {#    {% empty %}#}
    {#    <p>当for循环的对象为空的时候 会走empty</p>#}
    {#{% endfor %}#}
    
    {#<p>#}
    {#    django模板语法在取值的时候 统一使用句点符(大白话就是 点号   .)#}
    {#    {% with l.6.3.name as ttt %}  可以给一个比较复杂的取值操作取一个别名 之后在with语句中 就可以使用该别名#}
    {#        {{ ttt }}#}
    {#        {{ l.6.3.name }}#}
    {#    {% endwith %}#}
    {#</p>#}
    
    {#{% 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>#}
    

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

    from django import template
    register = template.Library()
    
    # 自定义过滤器
    @register.filter(name='baby')
    def index(a,b):
        # 该过滤器只做一个加法运算  是|add建议版本
        """
        |length
        |add
        |default
        |filesizeformat
        |truncatewords
        |truncatechars
        |safe
        |slice
    
        :param a:
        :param b:
        :return:
        """
        print('下午刚起床 一脸懵逼')
        return a + b
    
    # 自定义标签
    # 支持传多个值
    @register.simple_tag(name='jason')
    def xxx(a,b,c,year):
        return '%s?%s|%s{%s'%(a,b,c,year)
    
    # 自定义inclusion_tag
    @register.inclusion_tag('bigplus.html')
    def bigplus(n):
        l = []
        for i in range(n):
            l.append('第%s项'%i)
        return {'l':l}

    模板的继承
        当多个页面整体的样式都大差不差的情况下 可以设置一个模板文件,在该模板文件中 使用block块划分多个预期,之后子版在使用模板的时候 可以通过block块的名字 来选定到底需要修改哪一部分区域,模板一般情况下 应该至少有三个可以被修改的区域

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>模板的继承</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        {% load  static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css'%}">
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>            
        {% block css %}
          子页面自己的css代码
        {% endblock %}
    </head>
    <body>              
                    
        {% block content %}
         子页面自己的html代码
        {% endblock %}               
                    
        {% block js %}
        子页面自己的js代码
        {% endblock %}
    </body>
    </html>                                   

     # 模板的继承  使用方式

    {% extends 'home.html' %}
    {#将home页面 继承过来#}
    {% block css %}
        <style>
        h1  {
            color: blue;
        }
        </style>
    {% endblock %}
    {% block content %}
    <h1>注册页面</h1>
        {{ block.super }}
    
        {% include 'beautiful.html' %}
    
        <form action="">
            <p>username:<input type="text" class="form-control"></p>
            <p>password:<input type="text" class="form-control"></p>
            <input type="submit" class="btn btn-danger">
        </form>
    
    {% endblock %}
    {% block js %}
    {% endblock %}               

      # 一般情况下 模板上的block越多 页面的可扩展性就越强   
                模板的导入
                    {% include 'beautiful.html' %}          
                    当你写了一个特别好看的form表单/列表标签等,可以将它当成一个模块 哪个地方需要 就直接导入使用即可

       # < 1 > all(): 查询所有结果
        # < 2 > filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
        # < 3 > get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
        # < 4 > exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
        # print(models.Book.objects.exclude(pk=1))  # 只要pk不是1的数据全部查询出来
    
    
        # < 5 > order_by(*field): 对查询结果排序('-id') / ('price')
        # print(models.Book.objects.order_by('price'))  # 默认是升序
        # print(models.Book.objects.order_by('-price'))  # 加负号就是降序
    
    
        # < 6 > reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
        # print(models.Book.objects.order_by('price').reverse())
    
        # < 7 > count(): 返回数据库中匹配查询(QuerySet)
        # print(models.Book.objects.count())  # 对查询出来的结果进行一个计数
    
    
        # 的对象数量。
        # < 8 > first(): 返回第一条记录
        # print(models.Book.objects.filter(pk=1).first())
        # < 9 > last(): 返回最后一条记录
        # print(models.Book.objects.all())
        # print(models.Book.objects.all().last())
    
        # < 10 > exists(): 如果QuerySet包含数据,就返回True,否则返回False
        # print(models.Book.objects.filter(pk=1000))
        # print(models.Book.objects.filter(pk=1000).exists())
    
    
        # < 11 > values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
        # model的实例化对象,而是一个可迭代的字典序列
        # print(models.Book.objects.values('title','price'))  # 得到的结果是列表套字典
    
    
    
        # < 12 > values_list(*field): 它与values()
        # print(models.Book.objects.values_list('title','price'))  # 得到的结果是列表套元组
    
    
        # 非常相似,它返回的是一个元组序列,values返回的是一个字典序列
        # < 13 > distinct(): 从返回结果中剔除重复纪录
        """
        去重的前提是 一定要有完全重复的数据 才能去重
        """
        # print(models.Book.objects.filter(title='三国演义').distinct())
        # print(models.Book.objects.values('title','price','create_time').distinct())

    双下滑查询

      查看orm内部sql语句的方法
                    1.如果是queryset对象 那么可以点query直接查看该queryset的内部sql语句
                    2.在django项目的配置文件中 配置一下参数即可实现所有的orm在查询的时候自动打印对应的sql语句

    LOGGING = {
                        'version': 1,
                        'disable_existing_loggers': False,
                        'handlers': {
                            'console':{
                                'level':'DEBUG',
                                'class':'logging.StreamHandler',
                            },
                        },
                        'loggers': {
                            'django.db.backends': {
                                'handlers': ['console'],
                                'propagate': True,
                                'level':'DEBUG',
                            },
                        }
                    }
         # 查询价格大于200的书籍
            # res = models.Book.objects.filter(price__gt=200)
            # print(res)
            # 查询价格小于200的书籍
            # res = models.Book.objects.filter(price__lt=200)
            # print(res)
    
            # 查询价格大于等于200.22的书籍
            # res = models.Book.objects.filter(price__gte=200.22)
            # print(res)
            # 查询价格小于等于200.22的书籍
            # res = models.Book.objects.filter(price__lte=200.22)
            # print(res)
    
    
            # 查询价格要么是200,要么是300,要么是666.66
            # res = models.Book.objects.filter(price__in=[200,300,666.66])
            # print(res)
            # 查询价格在200到800之间的
            # res = models.Book.objects.filter(price__range=(200,800))  # 两边都包含
            # print(res)

    原生sql语句,模糊匹配like, %匹配多个,_匹配一个

         # res = models.Book.objects.filter(title__contains='p')  # 仅仅只能拿小写p
            # res = models.Book.objects.filter(title__icontains='p')  # 忽略大小写
            # print(res)
    
            # 1.查询书籍是以三开头的,  2.查询结果以p结尾的
            # res = models.Book.objects.filter(title__startswith='')
            # res1 = models.Book.objects.filter(title__endswith='p')
            # print(res)
            # print(res1)
                     
            # 查询出版日期是2017的年(******)
            res = models.Book.objects.filter(create_time__year='2017')
            print(res)
    dayehui
  • 相关阅读:
    D365: 笔记(VS无法打开表浏览器)
    D365: 笔记(跟踪调试批处理代码)
    D365: 笔记(非批处理执行class中弹出交互式窗体或报表)
    D365: 笔记(现有量增加批号表字段查询条件)
    D365: 新功能(二)采购发票自动化流程
    D365: 新功能(一)按日期设置编号规则
    ES6 入门教程(未完)
    深入理解TypeScript(未完)
    项目
    vue + threejs 项目踩坑总结
  • 原文地址:https://www.cnblogs.com/zrh-960906/p/11552092.html
Copyright © 2020-2023  润新知