models.py 在models中模型建立 对应建立表关系(单表)
from django.db import models
Create your models here.
class User(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
register_time = models.DateField()
'''
datefield
datetimefield
两个重要参数
auto_now:每次操作数据的时候,该字段会自动将当前时间更新
auto_now_add:创建数据的时候会自动将当前创建时间记录下来
之后只要不人为修改就一直不变
'''
def __str__(self):
return self.name
test.py单表查询
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoday64.settings")
import django
django.setup()
from app01 import models
增(create)
方法一(对应user表对象.create方法)
res=models.User.objects.create(name='jason',age=18,register_time='2002-1-21')
print(res)
方法二(产生对象后.save方法)
import datetime
ctime =datetime.datetime.now()
user_obj =models.User(name ='egon',age=84,register_time=ctime)
user_obj.save()
删(先filter,后.delete方法)
res = models.User.objects.filter(pk=2).delete()
print(res)
'''
pk会自动查到到当前表的主键字段 指代的就是当前表的主键字段
用了pk之后 你就不需要知道当钱的主键字段叫什么了
因为是自动查找的
'''
(先产生对象,后对象.delete)
user_obj= models.User.objects.filter(pk=1).first()
user_obj.delete()
修改(先filter,后update方法)
models.User.objects.filter(pk=4).update(name='egonDSB')
user_obj = models.User.objects.get(pk=4)
get方法返回的直接就是当前数据对象
但是该方法不推荐使用,一旦数据不存在,方法会报错
而filter则不会,所以我们还是用filter
user_obj.name = 'egonPPP'
user_obj.save()
必会必知13条
1.all() 查询所有数据 queryset对象中字典套对象
2.filter() 带有过滤条件的查询
3.get() 直接拿数据对象 如果不存在直接报错
4.first() 拿queryset里面第一个元素
res = models.User.objects.all()
print(res)
5.last()
6.values() 可以指定获取数据的字段 列表套字典
res=models.User.objects.values('name','age')
print(res)
7.values_list()列表套元组 功能更强大 <QuerySet [('jason',), ('egonPPP',)]>
res = models.User.objects.values_list('name')
print(res.query) 查看内部分装的sql语句
'''
#查看内部封装的sql语句 有个配置文件复制过来可以查看SQL语句的执行
上述查看sql语句的方式,只能用于queryset对象
只有queryset对象才能够点击query查看内部的sql语句
'''
8.distinct()去重
res= models.User.objects.all().values('name','age').distinct()
print(res)
'''
一定要是一模一样的数据
如果带有主键那么肯定不一样 往后的查询中一定不要忽略主键
'''
9.order_by()
res = models.User.objects.order_by('age')
res = models.User.objects.order_by('-age') 降序
print(res)
10.reverse() 反转的前提是 数据已经排过序了
res= models.User.objects.all()
res1=models.User.objects.order_by('age').reverse()
print(res)
print(res1)
11.count() 统计当前数据个数
res =models.User.objects.count()
print(res)
12.exclude() 排除在外
res = models.User.objects.exclude()
13.exists() 基本用不到 因为数据本身就自带布尔值 根本用不到 返回布尔值
res = models.User.objects.filter(pk=10).exists()
print(res)
神奇的双下划线查询
1 年龄大于35岁的数据(__gt大于)
res= models.User.objects.filter(age__gt=35)
print(res)
2.年龄小于35岁的数据(__lt小于)
res= models.User.objects.filter(age__lt=35)
print(res)
大于等于(__gte)
res=models.User.objects.filter(age__gte=32)
print(res)
小于等于(__lte)
res=models.User.objects.filter(age__lte=32)
print(res)
年龄是18或者32或者是40(__in在列表中的单个)
res =models.User.objects.filter(age__in=[18,32,40])
print(res)
年龄在18到40岁之都要(__range在列表中的所有)
res=models.User.objects.filter(age__range=[18,40])
print(res)
查询出名字里含有n的数据 模糊查询(__contains)
res =models.User.objects.filter(name__contains='s')
print(res)
是否区分大小写 查询出名字里面含有p的数据 默认是区分大小写的
res =models.User.objects.filter(name__contains='s')
print(res)
忽略大小写 不区分大小写(__icontains)
res = models.User.objects.filter(name__icontains='p')
print(res)
__startswith __endswith 开始结束
res =models.User.objects.filter(name__startswith='j')
res1 =models.User.objects.filter(name__endswith='j')
print(res,res1)
查询出注册时间是2020-01 月份 年份 __month __year
res=models.User.objects.filter(register_time__month='1')
res=models.User.objects.filter(register_time__year='2020')
print(res)
models.py 在models中模型建立 对应建立表关系(多表)
from django.db import models
Create your models here.
class Book(models.Model):图书表建立:book表
title = models.CharField(max_length=32)名称:字段charField,最大长度:32位
price = models.DecimalField(max_digits=8, decimal_places=2)价格:小数字段DecimalField,最大8位,小数位数2位
publish_data = models.DateField(auto_now_add=True)出版时间:DateField auto_now_add=True:以当前图书表注册时间记录
publish = models.ForeignKey(to='Publish')
ForeignKey:图书和出版社关系 :一对多,一个出版社对多个图书,一本书一个出版社,字段建在多的那一方
authors = models.ManyToManyField(to='Author')
ManyToManyField:图书和作者关系 :多对多,多个作者对多个图书,字段建在查询频率多的那一方
class Publish(models.Model):出版社表建立:Publish表
name = models.CharField(max_length=32) 出版社名字_字段:name CharField字段类型,最大长度32位
addr = models.CharField(max_length=64) 出版社地址_字段:addr CharField字段类型,最大长度64位
email = models.EmailField() 本质还是varchar(254)出版社邮箱_字段
该字段类型不是给models看的 而是给我们后面会学到的校验性组件看的
class Author(models.Model):作者表建立:Author表
name = models.CharField(max_length=32) 作者名字 字段:name CharField 字段类型,最大长度32位
age = models.IntegerField() 作者年龄 字段:age IntegerField 字段类型
auther_detail = models.OneToOneField(to='AuthorDetail') OneToOneField:作者表和作者明细表关系 一对一
class AuthorDetail(models.Model):作者明细表建立:AuthorDetail表
phone = models.BigIntegerField() 电话号码 字段:电话号码用Bigint或者用charfield
addr = models.CharField(max_length=64) 作者地址:地址 CharField 最大长度64位
一对多外键增删改查
增 (create方法)
1.直接写实际字段 id (book书增加出版社)
models.Book.objects.create(title='三国演义', price=123.23, publish_id=1)
2 虚拟字段 对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦', price=666.23, publish=publish_obj)
删(delete方法)
models.Publish.objects.filter(pk=1).delete()
修改(update方法)
方法一:
models.Book.objects.filter(pk=1).update(publish_id=2)
方法二:
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)
多对多 增删改查 就是在操作第三张关系表
models.Book.objects.create(title='论语', price=899.23, publish_id=1)
models.Book.objects.create(title='聊斋', price=444.23, publish_id=2)
models.Book.objects.create(title='老子', price=333.66, publish_id=1)
如何给书籍添加作者?
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.authors) 就类似于你已经到了第三张关系表了
book_obj.authors.add(1) 书籍id为1的书籍绑定一个主键为1的作者
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
book_obj.authors.add(author_obj,author_obj2)
'''
add给第三张关系表添加数据
括号内既可以传数字也可以传对象 并且都支持多个
'''
删(remove)
book_obj.authors.remove(1)
括号内既可以传对象 又可以传数字 并且支持多个
修改(set)
book_obj.authors.set([1,2])
括号内既可以传对象 又可以传数字 并且支持多个 括号内必须传一个可迭代对象
先删除 后新增
在第三张关系表中清空某个书籍与作者的绑定关系
清除所有关系
book_obj.authors.clear()
'''
clear
括号内不要加任何参数
'''
基于对象的跨表查询
'''
正向查询按字段
反向查询按表名小写_set.all()
'''
1.查询书籍主键为1的出版社
book_obj = models.Book.objects.filter(pk=1).first()
书查出版社 正向
res = book_obj.publish
print(res)
print(res.name)
print(res.addr)
2.查询书籍主键为1的作者(一对多)
book_obj = models.Book.objects.filter(pk=1).first()
书查作者 正向
res= book_obj.authors
res= book_obj.authors.all()
print(res)
3.查询作者jason的电话号码
author_obj = models.Author.objects.filter(name='jason').first()
res =author_obj.auther_detail
print(res)
'''
在书写orm语句的时候跟写sql语句是一样的
不要企图一次性将ORM语句写完 如果比较复杂 就写一点 看一点
正向什么时候需要加.all()
当你的结果可能有多个的时候就需要加.all()
如果是一个则直接拿到数据对象
'''
4.查询出版社是东方出版的书(多对多)
publish_obj =models.Publish.objects.filter(name='东方出版社').first()
res =publish_obj.book_set.all() 反向查询按表名小写_set.all()
print(res)
5.查询作者是jason写过的书
author_obj = models.Author.objects.filter(name='jason').first()
res = author_obj.book_set.all() 反向查询按表名小写_set.all()
print(res)
6.查询手机号是110的作者姓名
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res)
print(res.name)
print(res.addr)
'''
基于对象
反向查询的时候:
当你的查询结果可以有多个的时候 就必须加_set.all()
当你的结果只有一个的时候 不需要加_set.all()
自己总结出自己方便记忆的即可 每个人可以不同
'''
基于双下划线的跨表查询
1.查询jason的手机号(一行代码搞定)
res = models.Author.objects.filter(name='jason').values('auther_detail__phone')
print(res)
反向
res = models.AuthorDetail.objects.filter(author__name ='jason')
res = models.AuthorDetail.objects.filter(author__name='jason').values('phone', 'author__name')
print(res)
2.查询书籍主键为1的出版社和书的名称
res = models.Book.objects.filter(pk=1).values('title','publish__name')
print(res)
反向
res = models.Publish.objects.filter(book__pk=1).values('name', 'book__title')
print(res)
3.查询书籍主键为1的作者姓名
res= models.Book.objects.filter(pk=1).values('authors__name')
print(res)
反向
models.Author.objects.filter(book__id=1).values('name')
4. 查询书籍主键是1的作者的手机号
res = models.Book.objects.filter(pk=1).values('authors__auther_detail__phone')
print(res)
'''
只要掌握了正反向的概念
以及双下划线
你就可以无限制的跨表查询
'''