django学习笔记7模板层过滤器逻辑运算for循环if分支自定义过滤器自定义标签inclusion_tag模板继承模型层单表操作增加create删除delete修改update查filter,values查看sql语句去重distinct排序order_by,reverse计数count反选exclude存在exists双下划线查询大于,小于gt,lt或in之间range模糊查询contains首尾startswith,endswith日期year,month,day总结
模板层
过滤器
html页面(前端)
length,slice,default,filesizeformat,date
views.py(后端)
from django.utils.safestring import mark_safe
res = mark_safe(标签语言)#转义操作
html页面传入{{res}}即可
<p>过滤器</p> <p>统计字符串的长度:({s|length}</p> <p>切片操作:({11st1|s11ce:'0:4:2'}}</p> <p>默认值:{(b|default:'666'}) (如果前面的数据有值(True),那就是前面的值, 如果没有(False)那就是后而的默认偵) </p> <p>文件大小:{fi1e_size|filesizeformat} (把数字变成文件大小的格式) </p> <p>日期格式化:{{current._time|date:'Y-m-d h:i:s')) (y:年,m:月,d:日,h:时,1:分,s:秒) </p> </body> </html>
逻辑运算
for循环
(写完for之后按tab键可以白动补齐)
{ % for foo in list1 % }
{{ foo }}
{%endfor %}
{{ foo }} 可以更换为{{ forloop }},for循环内部的变量名forloop,.可以得知一些关于 循环的信息.
for循环字典只能拿到键,非值
{% for foo in list1 %} <p> {{ forloop }}</p> {% endfor %}
if分支
{% if b %} <p>hello</p> {% elif s %} <p>good</p> {% e1se %} <p>bad</p> {% endif %}if,elif后面的条件不需要加括号
自定义过滤器
自定义过滤器,标签,inclusion_tag
1.先在应用下创建一个名字必须叫做 templatetags文件夹 2.再在该文件夹中创建任意名字的py文件 3.再在该py文件中必须书写以下两句话 from django import template register =template.Library() #通过Library实例化一个对象
day6>app01>templates>mytag.py
from django import template register = template.Library() #自定义过滤器 #name是过滤器的名字 @register.filter(name='hello') def mysum(v1,v2): return v1 + v2 #自定义标签 #自定义inclusion tag
func.html
<p>自定义的使用</p> {% load mytag %} <p>{{n|he11o:666}}/p> <!--n作为第一个参数,666作为第二个参数传递给后端--> </body> </html>
报错
告诉你templates文件不能叫作mytag.py,重启项目即可
自定义标签
day6>app01>templates>mytag.py
#自定义标签 @register.simple_tag(name='plus') def test(a,b,c,d): return '%s-%s-%s-%s'%(a,b,c,d)
func.html
<p>{% p1us 123 123 123 123 %}</p> </body> </html>
inclusion_tag
当html页面某一个地方需要传递参数才能 动态渲染出来,并且很多页面都需要用到这些数 据,那么就可以做成inclusion._tag的形式
#自定义inclusion_tag #先定义一个方法,在页面上调用该方法并且可以传值, #该方法可以生成一些数据然后传递给自定的htmL页面 #之后调用的就是这个渲染好的页面 @register.inclusion_tag('left_menu.html')
day6>app01>templates>mytag.py
@register.inclusion_tag('left_menu.html') def left(n): #列表生成式 data=['第{}项'.format(i+1) for i in range(n)] #将left()中所有的参数以字典的形式传递给前端left_menu.html return locals()
left_menu.html
<u1> {% for foo in data %} <1i>{{ foo }}</1i> {% endfor %} </u1>
func.html
<p>自定义inclusion_tag使用</p> <!--5传递给left这个参数--> {% 1eft 5 %}
模板继承
1.先选择好一个想要继承的模板页面 {% extends 'html文件' %}:继承文件所有内容
2继承之后子页面和模板长得一样 如果需要修改某块内容,可以提前划分好区域:
{% block 区域名 %} {% endblock %}3.之后在子页面中输入bock就可以修改当前划分 的区域.
{% block 区域名 %} {% endblock %}4.需要划分 css,html,js三块区域
<head>内:{% block css%} {% endblock %} <body>后:{% block js%} {% endblock %}
相应的继承界面应该是
{% block css%} css {% endblock %} {% block js%} <script> </script> {% endblock %}
{% extends 'home.html'%} {% block content %} <h1>登录</h1> <form action=""> <p>username:<input type="text"></p> <p>password:<input type="password"></p> <input type="submit"class="btn btn-block btn-success"> </form> {% endblock %} {% block js %} <script> </script> {% endblock %}
模型层
DATABASES = { 'default':{ #注意左侧全部是大写,右边基本都是小写! ENGINE':'django.db.backends.mysql', 'NAME ' : 'day7', 'USER' : 'root', 'PASSW0RD':123456', 'H0ST':'127.0.0.1', 'P0RT':3306, #show create database day7查看字符编码,如果不是utf8那么无效! 'CHARSET':'UTF8' } }
models.py
from django.db import models from datetime import datetime class User(models.Model): name = models.CharField(max_length=32) age = models.IntegerField()#默认长度11位 #年月日 register_time = models.DateField() def __str__(self): return self.name #dateField #dateTimeField #两个重要的参数,不能共存: #auto now:每次操作数据时,该字段自动更新当前时间 #auto_now_add:在创建数据的时候自动将创建的时间记录,
测试脚本 当你只想测试django某一个py文件的内容,可以 不用书写前后端的交互,直接写一个测试脚本即 可
app21>test.py
from django.test import Testcase import os #手动写name==main,将测试代码写在main里面! if name=='main_': #从manage.py复制过来 os.environ.setdefault('DJANGO_SETTINGS_MODULE','day6.settings') import django django.setup() #在这里代码块可以测试单个的py文件了 from appe1 import models res = models.User.objects.all().first() print(res)
单表操作
app01>test.py
增加create
#单表操作 #增加 import datetime ctime = datetime.datetime.now() #第一种,通过objects.create()进行记录的增加 models.User.objects.create(name='fengxi',age=25,register_time=ctime) #该操作可以有一个返回值,返回的是对象本身 res = models.User.objects.create(name='fengxi',age=25,register_time=ctime) print(res) #fengxi #第二种,通过实例化对象进行save保存 user_obj = models.User(name='haha',age=26,register_time=ctime) user_obj.save()
删除delete
#删除 #delete() #pk会自动查找当前表的主键 models.User.objects.filter(name='fengxi').delete()#filter得到对象列表,delete批量删除 #第二种 models.User.objects.filter(name='haha').first().delete()#单个删除
修改update
#修改 #update() models.User.objects.filter(pk=4).update(name='mujin') #get方法可以直接返回数据对象,但是数据不存在则报错,filter不会 user_obj = models.User.objects.get(pk=4) #对象操作需要save user obj.name ='muma' user_obj.save()
查filter,values
''' 1.all():查询所有的数据 2.filter():带有过滤条件的查询 3.get():直接拿数据对象,不存在则报错 4.first():拿queryset里面的第一个元素 5.last():拿queryset里面的最后一个元素 res = models.User.objects.filter(name='haha').first() res1 = models.User.objects.filter(name='haha').last() ''' print(res.age,res1.age) #6.values():获取指定的数据字段,列表套key-values #无条件,等同于select app01_user.name,age from app01_user; res = models.User.objects.values('name','age') print(res) #7.values_list: res = models.User.objects.values_list('name','age) print(res)
select app01_user.age from app01_user where name='haha';
select app01_user.name,age from app01_user;
得到对象列表后,将每个元素分开打印,得到字典
values_list得到元组列表(相较于values没了key)
查看sql语句
filter,values得到的都是QuerySet对象(对象列表),该对象的query方法可以将orm语句转化为sql语句
res = models.User.objects.values_list('name','age') print(res.query) #得到:SELECT app01_user'.name,app01_user'.age FROM appe1_user
也可以在settings加入配置
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': '[%(asctime)s] %(message)s' }, }, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, }, 'loggers': { 'django': { 'handlers': ['console'], 'level': 'DEBUG', }, }, }
去重distinct
#去重一定要是一模一样的数据,只要有一个字段不同都不会去掉(如pk) #去重失败,因为filter得到的主键都是各不相同的 res = models.User.objects.filter('name').distinct() #去重成功 res = models.User.objects.values('name').distinct() print(res)
排序order_by,reverse
res=models.User.objects.order_by('age')#默认升序ASC res1 = models.User.objects.order._by('-age')#降序DESC res = models.User.objects.order_by('age').reverse()#反转排序 print(res)
计数count
res = models.User.objects.count() print(res)
反选exclude
#得到排除name='jiuwei'的其他所有对象 res = models.User.objects.exclude(name='jiuwei') #等同于select * FROM app01_user WHERE NOT(appe1_user'.'name 'jiuwei') print(res)
存在exists
res = models.User.objects.filter(pk=7).exists() print(res)
双下划线查询
写在filter中
大于,小于gt,lt
#1.年龄大于25岁的数据 res models.User.objects.filter(age__gt=25) print(res) #2.年龄小于25岁的数据 res models.User.objects.filter(age__lt=25) print(res) #3.大于等于 res = models.User.objects.filter(age__gte=25) #小于等于 res1 = models.User.objects.filter(age__lte=25)
或in
#4.年龄是18或者20或25-->1n res = models.User.objects.filter(age__in=[18,20,25])
之间range
#5.年龄在16到25之间的-->between16and25 闭区间 res = models.User.objects.filter(age__range=[16,25])
模糊查询contains
#6.模糊查询-->Like #忽略大小写 res = models.User.objects.filter(age__contains='n') #不忽略大小写 res = models.User.objects.filter(age__icontains='n')
首尾startswith,endswith
res = models.User.objects.filter(name__startswith='m') res1 = models.User.objects.filter(name__endswith='n')
日期year,month,day
res = models.User.objects.filter(register_time__month='4') res1 = models.User.objects.filter(register_time__year='4')
总结
1.数据表名:django默认以小写应用名类名作为数据库表名 2.关于主键:django会为表创建自动增长的主键列,每个模型类中只能有一个主键列,如果使用选项设置某属性为主键列,之后django不会再创建自动增长的主键列.默认创建的主键列属性为id,可以用pk代替 3.字段类型 (1)AutoField:自动增长的IntegerField.通常不指定,django会自动创建一个 (2)BooleanField:布尔值字段,值为True或False (3)NullBooleanField:值为Null,True或False (4)CharField:字符串,参数max_length表示最大字符数(必须指定)
(5)TextField:大文本字段,一般超过几千个字符的时候使用 (6)IntegerField:整数(范围有限,不能存手机号) (7)DecimalField:浮点数,参数max digits表示总位数,参数decimal_places表示小数位 (8)FloatField:浮点型 (9)DateField:年月日 参数:auto_now表示每次修改保存对象时,设置当前时间。auto_now_add表示当创建对象时,设置当前时间 两个参数互斥 (10)TimeField:时间参数同DateField (11)DateTimeField:日期时间.参数同DateField (12)FileField:上传的文件的 (13)ImageField:继承FileField,对上传的文件进行校验,确保是图片
(14)EmailField:邮箱字段(在数据库中就是varchar(255),但是对于后面要将的内容有区分)
4.字段
nul:表示某个字段可以为空 default:设置默认值 unique:如果设置为True,表示字段唯一 db_column:字段的名称,如果未定,则使用属性名称 db_index:若值为True,则在表中为字段创建索引 primary_key:主键(True) 5.关系字段
ForeignKey:外键(一对多,建在多表中),参数 to:要关联的表 to_field:要关联的字段 on_delete:当删除关联表中的数据时,当前表与关联表的行为,一般用models..CASCADE OneToOneField:一对一字段,参数同ForeignKey ManyToManyField:多对多,会自动创建第三张表
执行命令
python manage.py makemigrations python manage.py migrate
from django.db import models from datetime import datetime class Book(models.Model): title models.CharField(max_length=32) price models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto now add=True) #一对多出版社 publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE) #多对多作者,是创建第三张表 authors = models.ManyToManyField(to='Author') class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=64) email = models.EmailField() class Author(models.Model): name = models.CharField(max length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE) class AuthorDetail(models.Model):I phone = models.BigIntegerField() addr = models.CharField(max_length=64)