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)

转载于:https://www.cnblogs.com/zrh-960906/p/11552092.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值