app01models:
from django.db import models
class MyCharField(models.Field):
"""
自定义的char类型的字段类
"""
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super(MyCharField, self).__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
"""
限定生成数据库表的字段类型为char,长度为max_length指定的值
"""
return 'char(%s)' % self.max_length
class Person(models.Model):
pid = models.BigAutoField(primary_key=True) # pid 主键
name = models.CharField('姓名', max_length=32, db_column='username') # varchar(32)
age = models.IntegerField(blank=True, null=True) # 整数类型 -21亿 —— 21亿 10位 null=True 数据库可以为空
sex = models.CharField(max_length=32, choices=[('male', '男'), ('female', '女'), ('buxiang', '未知')])
birth = models.DateTimeField(auto_now=True)
profile = models.TextField(default='', blank=True)
phone = MyCharField(11)
# auto_now_add 新增数据时 填写上当前的时间
# auto_now = True 新增或者修改数据时 填写上当前的时间
def __str__(self):
return "< Person object: {} - {} - {} >".format(self.pid, self.name, self.age)
__repr__ = __str__
class Meta:
# 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
db_table = "person"
# # admin中显示的表名称
verbose_name = '个人信息'
# verbose_name加s
verbose_name_plural = '所有用户信息'
# 联合索引
# index_together = [
# ("name", "age"), # 应为两个存在的字段
# ]
#
# # 联合唯一索引
unique_together = (("name", "age"),) # 应为两个存在的字段
class Publisher(models.Model):
name = models.CharField(max_length=32, verbose_name="名称")
def __str__(self):
return self.name
class Book(models.Model):
name = models.CharField(max_length=32, verbose_name="书名")
price = models.DecimalField(max_digits=5,decimal_places=2) #最大是99999.99元
pub = models.ForeignKey(Publisher, null=True, on_delete=models.CASCADE, related_name='books',
related_query_name='book')
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=32, verbose_name="姓名")
books = models.ManyToManyField(Book, )
def __str__(self):
return self.name
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE","about_orm.settings")
import django
django.setup()
from app01 import models
from django.db.models import Max,Min,Avg,Sum,Count
聚合:求整本书id大于等于3的最高价格、最低价格、:
ret = models.Book.objects.filter(id__gt=3).aggregate(max = Max("price"),min = Min("price"))
结果:{'max': Decimal('90.00'), 'min': Decimal('50.00')}
统计每一本书的作者个数、按照book进行分组、统计作者的个数:
ret = models.Book.objects.annotate(Count("author")).values()
for i in ret:
print(i)
结果: {'id': 1, 'name': '没有页码的python ', 'price': Decimal('60.00'), 'pub_id': None, 'author__id__count': 0}
{'id': 2, 'name': '跟太白学美容美发', 'price': Decimal('50.00'), 'pub_id': None, 'author__id__count': 0}
{'id': 3, 'name': '跟宝元学外语', 'price': Decimal('70.00'), 'pub_id': None, 'author__id__count': 1}
{'id': 4, 'name': '跟和尚学合气道', 'price': Decimal('90.00'), 'pub_id': None, 'author__id__count': 0}
{'id': 5, 'name': '跟帮主学当乞丐', 'price': Decimal('50.00'), 'pub_id': None, 'author__id__count': 2}
统计出每个出版社的最便宜的书的价格:
ret = models.Publisher.objects.annotate(Min("book__price")).values() #方式一:
ret = models.Book.objects.values("pub","pub__name").annotate(Min("price")) #方式二:
结果:<QuerySet [{'pub': 1, 'pub__name': '清华出版社', 'price__min': Decimal('50.00')}, {'pub': 2, 'pub__name': '老男孩出版社', 'price__min': Decimal('50.00')}]>
统计作者的图书的个数:
ret = models.Author.objects.annotate(Count("books")).values() #方式一:
ret = models.Book.objects.values("author").annotate(Count("id"))#方式二:
结果:<QuerySet [{'author': None, 'id__count': 3}, {'author': 2, 'id__count': 2}, {'author': 1, 'id__count': 1}]>
统计不止一个作者的图书的个数:
ret = models.Book.objects.annotate(count = Count("author")).filter(count__gt=1)
结果:<QuerySet [<Book: 跟帮主学当乞丐>]>
统计一本图书作者数量的多少对查询集Queryset进行排序:
ret = models.Book.objects.annotate(count=Count("author")).order_by("count")
结果:<QuerySet [<Book: 跟和尚学合气道>, <Book: 跟太白学美容美发>, <Book: 没有页码的python >, <Book: 跟宝元学外语>, <Book: 跟帮主学当乞丐>]>
查询各个作者出的书的总价格:
ret = models.Author.objects.annotate(Sum("books__price")).values() #方式一:
ret = models.Book.objects.values("author").annotate(Sum("price")) #方式二:
结果:<QuerySet [{'id': 1, 'name': 'alex', 'books__price__sum': Decimal('50.00')}, {'id': 2, 'name': 'bigbao', 'books__price__sum': Decimal('120.00')}, {'id': 3, 'name': '和尚', 'books__price__sum': None}]>