day07自定义过滤器、标签、inclusion_tag、模板的继承与导、入双下划线查询

day07自定义过滤器、标签、inclusion_tag、模板的继承与导、入双下划线查询

昨日内容复习

  • 三板斧

    HttpResponse   render redirect
    视图函数必须返回一个HttpResponse对象
    
    
  • JsonResponse

    from django.http import JsonResponse
    #看源码得出来的结论
        JsonResponse(要序列化的变量名,json_dumps_parm={指定一个字典比如 ensure_ascii=False 中文直接显示 不让他转码},safe=False 非字典对象序列化这个参数设置为False就ok了)
    
    
  • from表单传文件

    首先必须是Post 然后必须指定entype='multipart/form-data' 才可以传输文件类对象
    
    前端还可以指定<input type="file" name="file" multiple>  一次性获取多个
    后端接受
    	文件类型:request.Post
        普通文本类型:request.Files
        	request.Files.get()获取文件对象单个
            request.Files.getlist()获取文件对象多个
    
  • FBV和CBV

    FBV:基于函数的视图
        from app01 import views
    	路由:url(r'^index/',视图函数名)
        
    CBV:基于类的视图
        from django.views import View
        路由:url(r'^login/',views.类名.as_view())
        
        视图层
    from django.views import View
    
    class Mylogin(View):
        def get(self,request):
            return HttpResponse('get请求')
    
        def post(self,request):
            return HttpResponse('post请求')
    '''
    口述CBV过程
    	发现了路由层调用一个函数 这个函数是哪的 因为是类调用直接去类找,没,去他的父类中找找到了,
    	as_view retrun了 view这个函数 view这个函数 定义了一个类的对象 return了 对象的dispatch方法
    	这个方法对象 没有 类没有 父类有 
    	这个方法把请求的方法转小写并判断是否在八个默认方法里面 在利用反射获取对象中具有与请求方法相同的方法名 内存地址赋值给handler 不在返回一个报错方法  最终执行这个handler并return 
        然后return 对象名()调用
    '''
    
  • 模板语法传值

    所有数据对象都能传过去
    render从后端传过去  可以字典传输 也可以locals全部传送
    前端只能用句点符取值 就是点的方式
    {{}}  # 跟变量名相关   
    {%%}  # 跟功能逻辑相关   for  if 
    
  • 模板语法之过滤器

    {{ 数据对象|过滤器名称:参数}}
    
    |length  #长度
    |add:参数     #添加
    |default:false执行的 # 默认值 前面是
    |date:'Y-m-d H:i:s'   # 日期格式
    |truncatewords:3 #按照单词截取不包括那三个点
    |truncatechars:10 #按照字符截取 包括三个点的位置
    |filesizeformat #统计大小 k kb等
    |safe #转义 后端的html 或者js等直接执行 不会返回字符串给前端
    
    #学习了该方法之后要有一个认识:html里面的代码不一定非要在html文件中编写  也可以在后端编写好了之后传递给前端
      
    后端也可以提前转义
    	from django.utils.safe_string import mark_safe
        res = mark_safe('<h1>123</h1>')
    
  • 模板语法之标签

    {% for foo in s %}
        {% if forloop.first %}   #第一次循环执行这个
            <p>这是第一次循环</p> 
        {% elif forloop.last %}  #最后一次循环执行这个
            <p>这是最后一次</p>
        {% else %}
            <p>继续!!!</p>
        {% endif %}
        {% empty %}
    
    
    forloop 里面的参数 
    	count0  从索引o开始
        count  从索引1开始
        revcounter 倒序 一直到索引1
        revcounter0 倒序 一直到索引0
        first 第一个为true 其他为false
        last  最后一个为true  其他为false
    
    
    
    
    {% for i in data_list %}
    	{{ forloop }}  # first last counter0 counter
        {% empty %}  # for循环对象内部没有值的情况下执行的代码
    {% endfor %}
    

今日内容概要

  • 自定义过滤器、标签、inclusion_tag(BBS作业用一次)

  • 模板的继承(django前后端结合 那么使用频率较高)

  • 模板的导入(类似于python中导入模块)

  • 模型层(ORM语句)

  • 图书管理系统表设计

  • ORM之神奇的双下划綫查询

今日内容详细

自定义义过滤器、标签、inclusion_tag (了解即可)

过滤器相当于python中的内置函数 自定义过滤器相当于python中自定义函数
自定义标签也是自定义函数

"""
自定义过滤器 标签 inclusion_tag都需要三步走战略
	1.在应用文件夹(app)下创建一个名字必须叫templatetags文件夹
	2.在创建的文件夹下创建一个任意名称的py文件 比如mytag
	3.在该py文件内先固定写两句话
		from django import template
		register = template.Library()
自定义过滤器:在html页面调用这个过滤器名称 他去自定义的过滤器找对应的函数 把函数返回值丢到调这个过滤器的html页面,最多只能传两个参数
自定义标签;在html页面调用这个标签名称 他去自定义的标签找对应的函数 把函数返回值丢到调这个标签的html页面
inclusion_tag:在html页面调用这个,也会去找对应的函数 但是他的返回值放在一个html页面(导航条 from表单等等,不是一个完整的页面),这个小页面塞到调这个的位置上

"""
在自定义的mytag.py里面创建
# 自定义过滤器(无论是内置的还是自定义都只能最多两个参数)
@register.filter(name='gailun')
def add(a, b):  
    return a + b


# 自定义标签
@register.simple_tag(name='nuoke')
def output(a,b,c,d):
    return '%s-%s-%s-%s' %(a,b,c,d)


# 自定义inclusion_tag
@register.inclusion_tag('myul.html',name='my_ul')
def aaa(n):
    obj_list=[]
    for i in range(1,n+1):
        obj_list.append(i)
    return locals()

"""
html页面
	{% load lol %}  一定要先加载才能使用
    {{ s|gailun:111 }} #指定过滤器的名字
    {% nuoke 1 2 3 4 %} #调用标签时记得 参数不要加逗号
    {% my_ul 10 %} #不要加: , 
"""

模板的继承

在母版中先使用block划定将来可以修改的区域
	{% block 自定义名称 %}
    	母版内容
    {% endblock %}
 
在子版中继承并修改指定区域
	{% extends 'home.html' %}
    {% block 自定义名称 %}
    	自定义其他内容
        
        {{ block.super }}  # 也可以引用母版的内容
    {% endblock %}
    
"""
母版中最少应该有三块区域
	{% block content %}  可以根据页面内容的布局写多个
    {% endblock %}
    
    {% block css %}   #css 样式的
    {% endblock %}
    
    {% block js %} #js样式
    {% endblock %}
"""

#login
{% extends 'home.html' %}

{% block css %}
    <style>
        h1{
            color: red;
        }
    </style>
{% endblock %}
{% block content %}

    <h1 class="text-center">Hey men!!</h1>
    <p class="text-center">welcome to register !!!!</p>
    <form action="">
        <p>username:
            <input type="text" class="form-control">
        </p>
        <p>username:
            <input type="text" class="form-control">
        </p>
        <input type="submit" class="btn btn-danger btn-block" value="提交注册">
    </form>


{% endblock %}
{% block title %}
    注册
{% endblock %}

{% block js %}
    <script>confirm('qqqqqqqqq')</script>
{% endblock %}

模板的导入

类似于导模块
	该模板不应该是一个完整的页面 而是一个局部页面
    很多地方都需要使用的情况下可以使用模板的导入
{% include 'menu.html' %}

模型层(跟数据有关的都是核心)

#django自带的sqlite数据库功能非常的少 并且对日期格式不兼容
1.需要会mysql配置 databases 还有__init__里面配置
2.数据库迁移命令 (分正向反向)
	正向 python3 manage.py makemigrations 
    	python3 manage.py migrate
        
     反向 python3 manage.py inspectdb > app名称/models.py 或者
    	python manage.py inspectdb
3.models 创建表相关操作 
	charfield(对应sql varchar)记得指定max_length 大小
    DecimalField (对应sql decimal ) 记得指定 max_digits=总长度  decimal_places=小数点后面长度
    IntegerField (对应sql int)
    DateField    日期格式 年月日 auto_now:True自动更新当前时间(每次修改数据都会将时间自动更新)  auto_now_add:True自动更新当前时间(创建巨鹿时将时间自动更新 比如图书购买时间)
    DateTimeField 日期格式 年月日 时分秒

测试环境

1.python console
2.py文件形式(参考manage.py前四行)
import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "d19_dj6.settings")
    import django
    django.setup()
    #还需要导入models模块
    # 在该代码的下方才可以正常测试django文件

查询关键字

# 查
	#在类里加一个__str__(print输出对象时候执行此方法)
    def __str__(self):
        return self.title
    # 1.all()
    # res = models.Books.objects.all()  # QuerySet res=列表套数据对象
    # print(res) 所有数据对象
    # print(res.first()) #第一个数据对象
    # print(res.last())  #最后一个数据对象
    # print(res[1]) #索引1的数据对象
    '''queryset支持正数的索引取值'''
    # print(res)
    # 2.filter()
    # res = models.Books.objects.filter(id=1)  QuerySet
    '''pk能够自动定位当前表的主键字段 避免了你自己去频繁查看'''
    # res = models.Books.objects.filter(pk=2)  QuerySet id=2的数据对象
    # print(res)
    '''filter括号内可以存放多个条件默认是and关系'''
    # res = models.Books.objects.filter(pk=2,title='jpm')
    # print(res)
    # 3.values()
    '''values可以指定查询的字段 结果QuerySet  列表套字典'''
    # res = models.Books.objects.values('title','price')
    # 4.values_list()
    '''values_list也可以指定查询的字段 结果QuerySet  列表套元组'''
    # res = models.Books.objects.values_list('title', 'price')
    # print(res)
    # 5.first()与last()  分别获取queryset第一个和最后一个数据对象
    #下面这个先获取全部数据对象 where没条件 然后获取title和price字段
    # res = models.Books.objects.all().filter().values('title','price')
    # print(res)
    '''只要是queryset对象 就可以无限制的调用queryset对象的方法'''
    # 6.get()  不推荐使用
    # res = models.Books.objects.get(pk=1)
    '''get方法可以直接获取到数据对象'''
    # print(res,res.pk,res.title,res.price,res.publish_time)
    '''但是该方法当查询条件不存在的时候会直接报错 没有filter好用!!!'''
    # res = models.Books.objects.get(pk=100)  #报错
    # res1 = models.Books.objects.filter(pk=100) #返回一个空的queryset
    # print(res1)
    # 7.exclude()  取反  QuerySet  列表套数据对象
    # res = models.Books.objects.exclude(pk=1)   #查找主键值不是1的 数据对象
    # print(res)
    # 8.order_by()  排序  QuerySet  列表套数据对象
    # res = models.Books.objects.order_by('price') #默认升序   
    # res1 = models.Books.objects.order_by('-price') #查询的字段前面加一个- 实现了降序
    # print(res)
    # 9.reverse()  翻转(必须提前有顺序才可以) 挺鸡肋的 先排序在降序 直接上面那个价格-就ok了
    # res = models.Books.objects.all()
    # print(res)
    # print(res.order_by('price'))
    # print(res.order_by('price').reverse())
    # 10.distinct()  去重
    '''尤其要注意主键字段''' 主键绝对不会一样 
    # res = models.Books.objects.all()
    # print(res)
    # print(res.distinct())
    # 11.count()  计数
    # res = models.Books.objects.all().count()
    # res1 = models.Books.objects.count()
    # print(res, res1)  # 4 4
    # 12.exists()  判断结果集是否有数据(不需要使用)
    # res = models.Books.objects.all().exists()
    # res1 = models.Books.objects.filter(id=100).exists()
    # print(res,res1)  # True False
    # 13.create()、update()、delete()、对象.save()

如何查看SQL语句

1.如果当前对象是queryset那么可以直接点query查找该对象内部SQL语句
2.配置文件(只要执行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',
            },
        }
}

神奇的双下划线查询

# 神奇双下划綫查询
    # 1.查询价格大于800的书籍
    # res = models.Books.objects.filter(price__gt=800)
    # print(res)
    # 2.查询价格小于800的书籍
    # res = models.Books.objects.filter(price__lt=800)
    # print(res)
    # 3.查询价格大于等于800的书籍
    # res = models.Books.objects.filter(price__gte=800)
    # print(res)
    # 4.查询价格小于等于800的书籍
    # res = models.Books.objects.filter(price__lte=800)
    # print(res)
    # 5.查询价格是989.45 或者278.89 或者888.21
    # res = models.Books.objects.filter(price__in=["888.21","278.89","989.45"])
    # print(res)
    # 6.查询价格在200到800之间的书籍
    # res = models.Books.objects.filter(price__range=(200,800))
    # print(res)
    # 7.查询书籍名称中包含字母p的书(区分大小写)
    # res = models.Books.objects.filter(title__contains='p')
    # print(res)
    # res = models.Books.objects.filter(title__icontains='p')
    # print(res)
    # 8.查询书籍是否以...开头 ...结尾
    # res = models.Books.objects.filter(title__startswith=)
    # res1 = models.Books.objects.filter(title__endswith=)
    # 9.查询出版日期是2021的书(常用)
    res = models.Books.objects.filter(publish_time__year=2021)
    res1 = models.Books.objects.filter(publish_time__month=11)
    print(res,res1)
    
#统计  
	字段名__gt=值     某个字段大于某个值的数据对象 
    字段名__gte=值     某个字段大于等于某个值的数据对象 
    
    字段名__lt=值     某个字段小于某个值的数据对象 
    字段名__lte=值     某个字段小于等于某个值的数据对象 
    
    字段名__in=['123','234']     某个字段等于值1或值2或值3 的数据对象 
    	加引号看前提 ,如果是浮点型要加引号,因为python对浮点数这块不够精确
        
    字段名__range=(200,500)    某个字段的值在200-500之间 的数据对象 
    
    字段名__contains='p'   某个字段的值包含字母'p'之间 的数据对象   区分大小写
    字段名__icontains='p'   某个字段的值包含字母'p'之间 的数据对象   不区分大小写
    
    字段名__startswith='人'   某个字段以'人'开头的数据对象
    字段名__ebdswith='的'   某个字段以'的'结束的数据对象
    
    
    #前提是日期类型
    字段名__year=2021  某个字段的年份为'2021'的数据对象
    字段名__month=11  某个字段的月为'11'的数据对象

图书管理系统表设计

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)
    publish = models.ForeignKey(to='Publish')
    authors = models.ManyToManyField(to='Author')


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDetail')

    
class AuthorDetail(models.Model):
    phone = models.BigIntegerField()
    addr = models.CharField(max_length=32)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值