Django之models模型层1
一、测试环境的搭建
1、app应用中默认有一个tests.py的测试文件,拷贝manage.py的内容如下到tests.py中
此时这个测试文件就能使用django环境了
import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject222.settings')
import django
django.setup()
from app01 import models
二、models层中
1、.values()和.values_list()方法
默认查询所有的字段,也可以指定某一个字段
res = models.Userinfo.objects.values() # 默认查询所有的字段
# <QuerySet [{'id': 1, 'username': 'cc1', 'password': '123'}, {'id': 2, 'username': 'cc2', 'password': '123'}, {'id': 3, 'username': 'cc3', 'password': '123'}]>
res = models.Userinfo.objects.values('username')
# <QuerySet [{'username': 'cc1'}, {'username': 'cc2'}, {'username': 'cc3'}]>
res = models.Userinfo.objects.values_list()
# <QuerySet [(1, 'cc1', '123'), (2, 'cc2', '123'), (3, 'cc3', '123')]>
print(res)
2、排序
order by age asc/desc
res = models.User.objects.all().order_by('age') # 默认是升序排列
res = models.User.objects.all().order_by('-age') # 降序排列
res = models.User.objects.all().order_by('age', 'id') # 降序排列
res = models.User.objects.all().order_by('age', '-id', '') # 降序排列
3、去重,
每一条数据都要完全一样,如果说带主键,一定不会重复
res = models.User.objects.all().values('password', 'age').distinct()
print(res)
4、反转,先排序,数据要先有序才能反转
降序---> 升序
res=models.User.objects.all().order_by('-age').reverse()
print(res)
5、count
select count(*) from user res = models.User.objects.count() print(res)
6、exclude 排除
res=models.User.objects.exclude(username='kevin1') print(res)
7、exist 是否存在
res = models.UserInfo.objects.filter(pk=1).exist() print(res)
三、
1、方法一
print(res.query)
res = models.Userinfo.objects.values() # 默认查询所有的字段 print(res) print(res.query) ## 输出 SELECT "app01_userinfo"."id", "app01_userinfo"."username", "app01_userinfo"."password" FROM "app01_userinfo"
2、方法二
修改settings配置文件
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 年龄大于35岁的数据
# select * from user where age > 10
# res = models.User.objects.filter(age__gt=10).all()
# print(res)
# 2 年龄小于10岁的数据
# res = models.User.objects.filter(age__lt=10).all()
# print(res)
# 3 年龄大于等于10岁的数据 e---------->equal
# res = models.User.objects.filter(age__gte=10).all()
# res = models.User.objects.filter(age__lte=10).all()
# 4 年龄是11 或者 20 或者 23
# select * from user where age in (11, 20, 23)
# res = models.User.objects.filter(age__in=[11,20,23]).all()
# print(res)
# 5 年龄在18到40岁之间的 首尾都要
# select * from user where age between 18 and 40
# res = models.User.objects.filter(age__range=[11,40])
# print(res)
# 6 查询出名字里面含有s的数据 模糊查询
# select *from user where username like '%s%'
# 回头复习
# res = models.User.objects.filter(username__contains='s').all()
# print(res)
# 7 用户名以s开头的
res = models.User.objects.filter(username__startswith='s').all()
# res = models.User.objects.filter(username__endswith='s').all()
print(res)
# 8 查询出注册时间是 2023 5月
# select * from user where reg_time = '2023-05'
# select date_format(reg_time, '%Y-%m') from user where date_format(reg_time, '%Y-%m') = '2023-05'
# res= models.User.objects.filter(reg_time__month='5') # 查5月的
res= models.User.objects.filter(reg_time__month='5',reg_time__year='2023') # 查5月的
print(res)
补充:时间字段:DateField
其中两个参数:
auto_now:记录修改时间,一旦改动记录,自动修改为当前时间
auto_now_add:记录的创建时间,自动填写
-default=datatime.datatime:设置默认值,创建时自动添加时间
在django中修改亚洲上海时区,不修改的话,时间相差8小时。
class Userinfo(models.Model):
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
age = models.IntegerField(default=0)
reg_time = models.DateField(auto_now=True)
create_time = models.DateField(auto_now_add=True)
'''
auto_now = False, # 默认是False
auto_now_add = False
'''
def __str__(self):
return self.username
五、外键字段的查询
1、数据准备
注意:多对多建外键时不用on_delete参数
# 用图书表,出版社表,作者表,作者详情表
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)
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):
phone = models.BigIntegerField() # 电话号码用BigIntegerField或者直接用CharField
addr = models.CharField(max_length=64)
2、增删改
增加一本图书?
# 外键字段的查询和增加
# 增加一本图书
# models.Book.objects.create(title='洋哥自转', price=1000, publish_date='2023-08-01', publish_id=1)
# publish_obj = models.Publish.objects.filter(pk=20).first()
try:
publish_obj = models.Publish.objects.get(pk=20)
except:
pass
# models.Book.objects.create(title='洋哥自转2', price=2000, publish_date='2023-08-02', publish=publish_obj)
# print(publish_obj) # None
# 删除一本图书
# models.Book.objects.filter(pk=1).delete()
# 修改
# models.Book.objects.filter(pk=2).update(publish=publish_obj)
# models.Book.objects.filter(pk=2).update(publish_id=3)
3、多对多关系表的增删改查
通过对象点外键字段
add(增) remove(删) set(修改) clear(清空)
# 给图书id为2的添加一个作者id=1
book_obj = models.Book.objects.filter(pk=2).first()
# print(book_obj.authors) # app01.Author.None
# print(book_obj.authors.all()) # app01.Author.
# 添加
book_obj.authors.add(1)
# book_obj.authors.add(2, 3) # 同时添加多个作者
# 这里的数字也支持对象,但是不推荐
# author_obj = models.Author.objects.filter(pk=1).first()
# print(author_obj)
# book_obj.authors.add(author_obj)
# 删除
book_obj.authors.remove('3') # 也支持一次删除多个。一本书有多个作者,先查书的id,再删除指定作者ID的记录
# 修改
book_obj.authors.set([1, 3])
# 清空表
book_obj.authors.clear()
4、多表查询
子查询:一个sql语句的执行结果当成另一个sql语句的执行条件,分布操作
连表查询:把多个表关联在一起拼接成一个大的虚拟表,然后按照表单查询
inner join left join right join union
正反向概念
正向概念:
外键字段在己方,我查你就是正向查询
# 图书查出版社:外键字段在图书表中,正向查询
反向概念:
外键字段在己方,你查我就是正向查询
# 出版社查图书,外键字段在图书表中,反向查询
判断出来正向和反向之后有什么用?
正向查询按照字段查询(外键字段)
反向查询按照表名小写或者表名小写_set
查询案例
# 1、查询书籍主键为1的出版社
# 书籍查出版社 ----------> 正向查询 ------------> 按外键字段查询
res = models.Book.objects.filter(pk=1).first()
# print(res) # Book object (1)
# print(res.publish) # book对象点外键字段publish跳转到出版社表
print(res.publish.addr) # 接着可以点表里的字段查记录
# 2、查询书籍主键为2的作者
# 书籍查作者 ----------> 正向查询 ------------> 按外键字段查询
res = models.Book.objects.filter(pk=2).first()
# print(res.authors) # app01.Author.None
# print(res.authors.all())
# <QuerySet [<Author: Author object (2)>, <Author: Author object (3)>]>
print(res.authors.all()[1].name) # 由上可知查询对象有2条结果,按下标取name
# 循环取出所有的作者名
# for i in res.authors.all():
# print(i.name)
# 3、查询作者曹雪芹的电话号码
# 作者查询作者信息 ----------> 正向查询 ------------> 按外键字段查询
res = models.Author.objects.filter(name='曹雪芹').first()
print(res.author_detail.phone)
# 4、查询出版社是北京出版社的书
# 出版社查书籍----------> 反向查询 ------------> 按照表名小写或者拼接_set
res = models.Publish.objects.filter(name='北京出版社').first()
print(res.book_set) # app01.Book.None
print(res.book_set.all()[0].title)
# 5、查询作者是罗贯中写过的书
# 作者查书籍 ----------> 反向查询 ------------> 按照表名小写或者拼接_set
res = models.Author.objects.filter(name='罗贯中').first()
print(res.book_set.all())
for i in res.book_set.all():
print(i.title)
# 6、查询手机号是1209的作者姓名
# 作者详情查作者 ----------> 反向查询 ------------> 按照表名小写或者拼接_set
res = models.AuthorDetail.objects.filter(phone='1209').first()
print(res.author.name)
注意:反向查询按照表名小写或者表名小写+_set
只有在一对一表关系中才能使用小写表名的形式,即当查询的结果只有一条的时候,不能拼接_set

浙公网安备 33010602011771号