zoukankan      html  css  js  c++  java
  • Django学习之模板层

    三板斧

    render,HttpResponse,redirect
    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(基于类的视图)    面向对象式编程

      

    # 问题:基于CBV的视图函数 
    """get请求来就会走类里面get方法,post请求来就会走类里面post方法 为什么???"""
                    
    #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()  # 单例模式    
     

    模板层

    模板语法

      两大类:{{ }} 变量相关

          {% %} 逻辑相关

      为模板传值

    过滤器:|  

    <p>{{ xxx|safe }}</p>  {# 转义 #}
    <p>{{ file_size|filesizeformat }}</p> { # 文件大小 #}
    <p>{{ ctime|date:'Y-m-d' }}</p>{# 年月日 #}
    <p>{{ ss|default:'' }} default必须要有两个参数</p>{#当|左边的变量为空就会返回|右边的值#}
    <p>{{ l|length }}</p> {#返回长度#}
    <p>{{ info|truncatewords:3 }}</p>{# 就是按空格截取  三个点不算#}
    <p>{{ info|truncatechars:6 }}</p>{#按字符截取内容 三个点也算#}
    <p>{{ n|add:100 }}</p>{#数字相加#}
    <p>{{ s|add:'hahah 翻车啦' }}</p>{#字符串相加#}
    <p>{{ l|slice:'0:3' }}</p>
    <p>{{ l|slice:'0:5:2' }}</p>{#切片并且支持步长#}

      前后端取消转义

      前端:  |safa

      后端:  如果不转义传过去的就是字符串

    from django.utils.safestring import mark_safe
    zzz = mark_safe('<h1>111</h1>')
    标签:{% %}(逻辑相关)

    for循环

    
    
    <ul>
    {% for user in user_list %}
        <li>{{ user.name }}</li>
    {% endfor %}
    </ul>
    
    

    关于forloop

    
    

    
    

    if判断

    
    
     
    {% for foo in '' %}
        {% if forloop.first %}
            <p>这是我的第一次</p>
            {% elif forloop.last %}
            <p>这是最后一次了啊</p>
            {% else %}
            <p>来啊来啊!!!</p>
        {% endif %}
        {% empty %}
        <p>当for循环的对象为空的时候 会走empty</p>
    {% endfor %}
     
    
    

    with

    
    

    定义一个中间变量,多用于给一个复杂的变量起别名。

    
    

    注意等号左右不要加空格。

    
    
    {% with business.employees.count as total %}
        {{ total }} employee{{ total|pluralize }}
    {% endwith %}
     
                                    {#{% for foo in l %}#}
                    {#    <p>{{ forloop }}</p>#}
                    {#{% endfor %}#}
                    {##}
                    {##}
                    {#{% if '' %}#}
                    {#<p>xxx条件为true</p>#}
                    {#    {% else %}#}
                    {#    <p>xxx条件为false</p>#}
                    {#{% endif %}#}
    
                    {##}
                    {#{% for foo in l %}#}
                    {#    {% 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>
                    {% endfor %}
            
                for循环里面的forloop对象
                if判断            

     

    自定义标签 过滤器 inclusion_tag

    自定义固定的三步走战略:
      1.必须在你的应用下新建一个名为templatetags文件夹
      2.在该文件夹内新建一个任意名称的py文件
      3.在该py文件中固定先写下面两句代码

    from  django import template
                        
    register = template.Library()
    # 自定义过滤器
    @register.filter(name='baby')
    def index(a,b):
    
    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块的名字 来选定到底需要修改哪一部分区域

      模板一般情况下 应该至少有三个可以被修改的区域

    
    

    模板的继承与导入

    
    
     
    #首先需要再被继承的模块中划分多个区域
    {% block 给区域起的名字 %}
    
    {% endblock %}
    
    #通常情况下一个模板中应该至少有三块
    {% block css %}
    页面css代码块
    {% endblock %}
    
    {% block js %}
    页面js代码块
    {% endblock %}
    
    {% block contet %}  #注意起的名字不加引号
        页面主题内容
    {% endblock %}
     
    
    

    子板继承模板

    
    
     
    #先继承模板所有的内容
    {% extends 'home.html' %}
    
    #然后根据block块的名字修改指定区域的内容
    {% block content %}
        <form action="">
        <p>username:<input type="text" class="form-control"></p>
        <p>password:<input type="text" class="form-control"></p>
        </form>
    {% endblock %}
     
    
    

    模板的导入:将一段html当做模块的方式导入另一个html展示

    
    
    {%  include '想导入的html文件名' %}







    单表查询必会13条

    
    
    # < 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())
    
    
    
     
  • 相关阅读:
    mysql安装部署
    SSH升级
    符号、特殊字符的英文读法
    用python开发视频压缩器
    VSCode配置项
    工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)
    单例模式
    Jquery 绑定事件
    中文分词 新建索引 更新索引
    微信自动回复机器人
  • 原文地址:https://www.cnblogs.com/AbrahamChen/p/11544875.html
Copyright © 2011-2022 走看看