Django框架 day04

今日内容:

模板层(模板语法)标签过滤器自定义标签,过滤器,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请求

增删改查操作详情:

 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

猜你喜欢

转载自www.cnblogs.com/zahngyu/p/11546334.html