13_单表查询
显示ORM底层生成SQL
def showsql():
from django.db import connection
queries = connection.queries
print queries[-1]['sql'] # 返回queries当中的最后一个字典(也就是最新一次查询)的sql语句
查询单个对象
#所有的继承自models.Model的类 都会有一个叫objects(管理器)
* 查询一个 (有且只能有一个)(少于一个或者多余一个都报错)
* 返回值Movie对象
Movie.objects.get(mid=147)
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mid` = 147
* 获得第一个
Movie.objects.first()
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` ORDER BY `movie`.`mid` ASC LIMIT 1
* 获得最后一个
Movie.objects.last()
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` ORDER BY `movie`.`mid` DESC LIMIT 1
* 获得记录的总数
Movie.objects.count()
SELECT COUNT(*) AS `__count` FROM `movie`
查询多个对象
* 获得所有的记录
Movie.objects.all()
# 在diango的1.11.6中默认只是获得21个,
# 懒加载
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` LIMIT 21
* 切片 (不支持负数索引)
Movie.objects.all()[20:40]
# 底层直接使用了limit字句,可以自动的分页
# django的ORM(对象关系映射)性能非常强大,能节省很多工作
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` LIMIT 20 OFFSET 20
* 过滤
# 集和(游标,结果集,查询集)
Movie.objects.filter(mname='麻辣学院')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mname` = '麻辣学院' LIMIT 21
* 模糊查询
* like
* %(多个字符) _(一个字符)
* SELECT * from movie WHERE mname LIKE '%爱情_'
* 查询爱情结尾的
SELECT * from movie WHERE mname LIKE '%爱情'
Movie.objects.filter(mname__endswith='爱情')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mname` LIKE BINARY '%爱情' LIMIT 21
* 查询爱情开头的
SELECT * from movie WHERE mname LIKE '爱情%'
Movie.objects.filter(mname__startswith='爱情')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mname` LIKE BINARY '爱情%' LIMIT 21
* 包含爱情的
SELECT * from movie where mname like '%爱情%'
Movie.objects.filter(mname__contains='爱情')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mname` LIKE BINARY '%爱情%' LIMIT 21
* 完全相等
Movie.objects.filter(mname__exact='麻辣学院')
Movie.objects.filter(mname='麻辣学院')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE `movie`.`mname` = '麻辣学院' LIMIT 21
* 忽略大小写
Movie.objects.filter(mname__istartswith='h')
* 查询某个字段是否为null
Movie.objects.filter(mname__isnull=True)
* 多条件查询
Movie.objects.filter(mname__contains='爱情',mid=147)
and
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE (`movie`.`mname` LIKE BINARY '%爱情%' AND `movie`.`mid` = 147) LIMIT 21
Movie.objects.filter(mname__contains='爱情').filter(mid=147)
* 部分查询
Movie.objects.values('mname','mid').filter(mname__contains='爱情')
* 排除一部分
Movie.objects.filter(mname__contains='爱情').exclude(mname__startswith='爱情')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` WHERE (`movie`.`mname` LIKE BINARY '%爱情%' AND NOT (`movie`.`mname` LIKE BINARY '爱情%')) LIMIT 21
* 排序
Movie.objects.order_by('mid')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` ORDER BY `movie`.`mid` ASC LIMIT 21
Movie.objects.order_by('-mid')
SELECT `movie`.`mid`, `movie`.`mname`, `movie`.`mdesc`, `movie`.`mimg`, `movie`.`mlink` FROM `movie` ORDER BY `movie`.`mid` DESC LIMIT 21
日期查询
* 查询大于某个时间的记录
Post.objects.filter(created__gt='2017-10-20')
SELECT `post_post`.`id`, `post_post`.`title`, `post_post`.`created` FROM `post_post` WHERE `post_post`.`created` > '2017-10-20' LIMIT 21
* 查询最近一个月的帖子(查询最近不活跃的用户)
def get_recent_month_posts():
import datetime
current = datetime.date.today()-datetime.timedelta(days=30)
current = str(current)
return Post.objects.filter(created__gt=current)
* 查询十月二十号--十一月二十号的所有的记录
* 错误的
Post.objects.filter(created__in=('2017-10-20','2017-11-20'))
指的是这两个时间中的一个
* 正确 (sql语句)
Post.objects.filter(created__range=('2017-10-20','2017-11-20'))
SELECT `post_post`.`id`, `post_post`.`title`, `post_post`.`created` FROM `post_post` WHERE `post_post`.`created` BETWEEN '2017-10-20' AND '2017-11-20' LIMIT 21
BETWEEN '2017-10-20' AND '2017-11-20' :包头也包尾,即包括‘2017-10-20’和‘2017-11-20’以及二者之间的所有
14_单表增_删_改
增加
#方法1
post = Post(title='博客11',created='2017-2-28')
post.save()
#方法2
Post.objects.create(title='博客12',created='2018-11-11')
# 返回值是添加的对象
删除
#方法1:(删除一条)
Movie.objects.get(mid='147').delete()
#BINARY不是函数,是类型转换运算符,比较时 区分大小写
DELETE FROM `movie` WHERE `movie`.`mname` LIKE BINARY 'h%'
* 方法2 (删除所有包含博客名字的帖子,删除多条)
Post.objects.filter(title__contains='博客').delete()
修改
#方法1 (更新的是所有的字段)
post = Post.objects.first()
post.title='更新了'
post.save()
UPDATE `post_post` SET `title` = '更新了', `created` = '2017-11-27' WHERE `post_post`.`id` = 26
#方法2(只更新修改的字段),推荐使用
Post.objects.filter(id=26).update(title='又更新了')
UPDATE `post_post` SET `title` = '又更新了' WHERE `post_post`.`id` = 26
15_创建单表
常用字段类型
- django所有的数据模型都继承自models.Model
- CharField max_length (输入框)
- TextField 没有长度限制的字符串 (文本域)
- DateField 日期
- DateTimeField 日期+时间
- BooleanField 真假
- NullBooleanField Null,真假,
- Integer 整数
- PositiveIntegerField 正整数
- DecimalField max_digits(几位数) decimal_places(小数点后保留几位)
- ImageField 图片 依赖于 Pillow(处理图片) upload_to='upload' 指定文件上传到目录
- FileField(ImageField继承FileField)
- AutoField
- ForeignKey 1:n
- ManyToManyField n:n
- EmailField 邮箱
- UUIDField 重复的概率非常低基本可以忽略,全世界都不一样的标示,uuid的产生和服务器的环境有关(CPU,网关,) 唯一性的标示,用户模块,订单号
- 不同的字段在后台对应不同的html的组件
ImageField 依赖于Pillow组件(python库)
常用属性
- unique 标示这个字段唯一
- default 默认的意思 ,(如果不写的话就使用默认的值)
- null=True 允许字段为null,(允许数据库为null)数据库层面的
- blank=True 表单阶段的,admin后台的
- auto_now 针对时间的,自动调整当前,(当修改条目的时候,这个时间会自动更新),每次修改都会更新 (修改,保存的时候才会生效,)
- auto_now_add 针对时间的,只添加一次,(创建的时间)
重点理解属性
- 表单层面的东西(js判断字段是否是" "),不需要重写迁移数据库
- unique=True 可以任何字段
- default 数据库+表单层面(同时生效)
- auto_now_add 创建的时候会自动的添加时间(数据库),(后台表单层面找不到这个字段)
- auto_now 每次修改的时候自动更新,(数据库+表单层面)
- null=True 数据库层面,允许为Null,不是空字符串
- blank=True 表单层面的,后台选填(表单项元素可以为空,表单不会进行非空校验)
uuid
uuid.uuid4().get_hex() 【python2】
uuid.uuid4().hex 【python3】
django迁移失败如何处理
- 删除模块下(问题模块)的所有的迁移记录
- 删除数据库中django_migrations中问题模块的迁移记录
DELETE FROM django_migrations WHERE app='模块名' - 删除这个模块下已经产生的所有的表
- 重新生成迁移文件
- 重新迁移
15_创建单表例子
class Post(models.Model):
pid = models.AutoField(primary_key=True)
title = models.CharField(max_length=30,unique=True,blank=False,null=False)
content = models.TextField()
access_count = models.PositiveIntegerField()
price = models.DecimalField(max_digits=5,decimal_places=2)
isdelete = models.BooleanField()
created = models.DateField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
img = models.ImageField(upload_to='upload/images')
file = models.FileField(upload_to='upload/files')
class Meta:
db_table='t_post'
# python 2 的写法,重写对象输出的方法
# def __unicode__(self):
# return u'Post:%s'%self.title
# python 3 的写法,重写对象输出的方法
def __str__(self):
return self.title