标签:方便 移除 rem dig min 数据库 field 个数 使用
先创建一个数据库,做前期准备
为了方便测试,不再进行urls对应关系和views的书写,直接测试的单个文件
那么如何只单独测试Django中的某个py文件,有以下方法
在任意一个py文件中书写以下代码
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test53.settings")
import django
django.setup()
通过models.py创建一个表
from django.db import models
class Movie(models.Model):
title = models.CharField(max_length=64)
price = models.DecimalField(max_digits=8, decimal_places=2)
publish_time = models.DateField()
导入tests.py文件
from app01 import models
models.Movie.objects.all()
"""
必知必会16条
1.create()
2.all()
3.filter()
4.update()
5.delete()
6.first()
7.last()
8.get()
9.values()
10.values_list()
11.order_by()
12.count()
13.exclude()
14.exists()
15.reverse()
16.distinct()
"""
# creat() 返回值就是当前被创建数据的对象本身
models.Movie.objects.create(title='三国演义', price=199.99, publish_time='2010-1-1')
# 直接传日期对象也可以
from datetime import date
ctime = date.today()
models.Movie.objects.create(title='西游记', price=88.88, publish_time=ctime)
# all() 返回queryset对象
res = models.Movie.objects.all()
print(res)
# 3.filter() 返回queryset对象
res = models.Movie.objects.filter(pk=1) # pk就是主键
res = models.Movie.objects.filter(pk=1, title='三国演义')
print(res)
# 4. get() 直接获取对象本身
res = models.Movie.objects.get(pk=2)
print(res.title, res.price, res.publish_time)
# 5.values() 返回queryset对象[{},{}]
res = models.Movie.objects.values('title', 'price')
print(res)
# 6. values_list() 返回queryset对象[(),()]
res = models.Movie.objects.values_list('title', 'price')
print(res)
# 7.first() 返回数据对象
res = models.Movie.objects.filter().first()
print(res)
# 8.last() 返回数据对象
res = models.Movie.objects.filter().last()
print(res)
# 9.update() 返回受影响的行数
res = models.Movie.objects.filter(pk=1).update(title='水浒传', price=77.77)
print(res)
# 10.delete() 返回受影响的表及行数
res = models.Movie.objects.filter(pk=1).delete()
print(res) # (1, {'app01.Movie': 1})
# 11.count() 返回数据条数
res = models.Movie.objects.count()
print(res) # 1
# 12.order_by() 默认是升序, -号就是降序
# res = models.Movie.objects.order_by('price')
res = models.Movie.objects.order_by('-price')
print(res)
# 13.exclude()
res = models.Movie.objects.exclude(pk=2)
print(res)
# 14.exists()
res = models.Movie.objects.filter(pk=999).exists()
print(res) # False
# 15.reverse()
res = models.Movie.objects.order_by('price').reverse()
print(res)
# 16.distinct()
res = models.Movie.objects.values('title', 'price').distinct()
print(res)
例题
res = models.Movie.objects.filter(price__gt=70)
print(res)
res = models.Movie.objects.filter(price__lt=80)
print(res)
res = models.Movie.objects.filter(price__gte=88.88)
print(res)
res = models.Movie.objects.filter(price__lte=77.77)
print(res)
res = models.Movie.objects.filter(price__in=[66, 77, 88])
print(res)
res = models.Movie.objects.filter(price__range=(77,99))
print(res) # 这里的range顾头也顾尾
res = models.Movie.objects.filter(title__contains='DDY')
# 默认区分大小写
res = models.Movie.objects.filter(title__icontains='DDY') # i 忽略大小写
print(res)
res = models.Movie.objects.filter(publish_time__year=2010)
print(res)
res = models.Movie.objects.filter(publish_time__month=1)
print(res)
先在models.py中创建几张表,作为前期准备
外键字段在
class Book(models.Model):
title = models.CharField(max_length=64)
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')
# 库存数
kucun = models.BigIntegerField(default=1000)
# 售出数
maichu = models.BigIntegerField(default=500)
class Publish(models.Model):
name = models.CharField(max_length=64)
addr = models.CharField(max_length=64)
class Author(models.Model):
name = models.CharField(max_length=64)
age = models.IntegerField()
# 作者详情 一对一,外键字段建在任意一方,推荐查询频率高的一方
author_detail = models.OneToOneField(to='AuthorDetail')
class AuthorDetail(models.Model):
phone = models.BigIntegerField()
addr = models.CharField(max_length=64)
增
# 1.增 直接写实际的表字段,publish_id
models.Book.objects.create(title='三国演义', price=199, publish_id=2)
# 2.增 虚拟字段 直接给对象
publish_obj = models.Publish.objects.get(pk=1)
models.Book.objects.create(title='水浒传', price=188, publish=publish_obj)
改
# 1.改 同上
models.Book.objects.filter(pk=1).update(publish_id=3)
# 2.改
publish_obj = models.Publish.objects.get(pk=4)
models.Book.objects.filter(pk=1).update(publish=publish_obj)
book_obj = models.Book.objects.filter(pk=1).first()
# 书籍和作者的关系是第三张表决定的
# print(book_obj.authors) # 书籍对象.虚拟字段authors就类似于已经跨到书籍和作者的第三张表了
book_obj.authors.add(1) # 给书籍绑定一个主键为1的作者
book_obj.authors.add(2, 3) # 给书籍绑定一个主键为2,3的作者
add是专门给第三张关系表添加数据,括号内即可传入数字,也可传入对象,支持传入多个
book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(2)
book_obj.authors.remove(1, 3)
author_obj = models.Author.objects.get(pk=2)
book_obj.authors.remove(author_obj)
remove是专门给第三张关系表移除数据,括号内即可传入数字,也可传入对象,支持传入多个
book_obj = models.Book.objects.filter(pk=2).first()
book_obj.authors.set((2,))
book_obj.authors.set((2, 3))
set 修改书籍与作者的关系,括号内支持传数字和对象 但是需要是可迭代对象
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.clear()
clear() 清空关系,不需要任何的参数
跨表查询的方式
正反向的概念
这里有个口诀
基于对象的跨表查询(子查询)
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.publish.name) # 北方出版社
print(book_obj.publish.addr) # 北京
book_obj = models.Book.objects.filter(pk=2).first()
print(book_obj.authors) # app01.Author.None
author_list = book_obj.authors.all()
for author_obj in author_list:
print(author_obj.name)
author_obj = models.Author.objects.filter(pk=1).first()
print(author_obj.author_detail.phone)
注意:以上为正向查询,当外键字段对应的数据可以有多个的时候,需要加.all(),否则点外键字典即可获取到对应的数据对象
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set) # app01.Book.None
book_list = publish_obj.book_set.all()
for book_obj in book_list:
print(book_obj.title)
author_obj = models.Author.objects.filter(name='jason').first()
book_list = author_obj.book_set.all()
for book_obj in book_list:
print(book_obj.title)
author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
print(author_detail_obj.author.name)
注意:基于对象的反向查询,表名小写是否需要加_set.all()
一对多和多对多的时候需要添加,一对一不需要添加
基于双下划线跨表查询(链表查询)
# 正向:
res = models.Book.objects.filter(pk=1).values('publish__name')
print(res)
# 反向:
res = models.Publish.objects.filter(book__pk=1).values('name')
print(res)
# 正向
res = models.Book.objects.filter(pk=1).values('authors__name', 'authors__age', 'title')
print(res)
# 反向
res = models.Author.objects.filter(book__pk=1).values('name', 'age', 'book__title')
print(res)
# 正向
res = models.Author.objects.filter(name='jason').values('age', 'author_detail__phone')
print(res)
# 反向
res = models.AuthorDetail.objects.filter(author__name='jason').values('author__age', 'phone')
print(res)
# 正向
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)
# 反向
res = models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
print(res)
注意:只要表与表之间有关系,就可以通过正向的外键字段或者反向的表名小写连续跨表操作
关键字是 aggregate
聚合查询需要导入几个功能
from django.db.models import Max, Min, Avg, Sum, Count
res = models.Book.objects.aggregate(avg_price=Avg('price'))
print(res)
res = models.Book.objects.aggregate(max_price=Max('price'))
print(res)
res = models.Book.objects.aggregate(Avg('price'), Max('price'), Min('price'), Sum('price'), Count('price'))
print(res)
关键字是 annotate
res = models.Book.objects.annotate(author_num=Count('authors')).values('title', 'author_num')
print(res)
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
print(res)
res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title')
print(res)
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name', 'sum_price')
print(res)
如何按照表中的某一个指定字段分组
model.Book.objects.values('price').annotate()
# 这样就是以书表中价格分组
需要导入
from django.db.models import F, Q
F:
book_list = models.Book.objects.filter(kucun__gt=F('maichu'))
for book_obj in book_list:
print(book_obj.title)
res = models.Book.objects.update(price=F('price')+100)
print(res) # 5 返回影响的数据条数
F可以帮我们获取表中某个字段对应的值
Q:
Q可以改变查询的条件关系 与或非 (and、or、not)
res = models.Book.objects.filter(Q(title='三国演义'), Q(price=400)) # 逗号,是and关系
res1 = models.Book.objects.filter(Q(title='三国演义')|Q(price=400)) # | 管道符是 or关系
res2 = models.Book.objects.filter(~Q(title='三国演义')|Q(price=400)) # ~是not关系
Q的用法:想要
res = models.Book.objects.filter(‘title‘=‘三国演义‘)
title和三国演义都可以成为字符串,这样可以让用户自己选择想要的条件
q = Q()默
q.connector = 'or' # q对象认也是and关系,可以通过connector改变or
q.children.append(('title', '三国演义'))
q.children.append(('price', 1000))
res = models.Book.objects.filter(q)
print(res)
标签:方便 移除 rem dig min 数据库 field 个数 使用
原文地址:https://www.cnblogs.com/YGZICO/p/12198736.html