Django学习笔记 2

本文详细介绍了Django中的聚合查询,包括整表聚合与分组聚合的使用方法,以及如何通过annotate和values进行操作。同时,展示了Django原生SQL查询、模型管理器的自定义以及Meta类的应用。此外,还讲解了一对一、一对多和多对多关系映射的创建和查询技巧,帮助理解Django数据库操作的灵活性。
摘要由CSDN通过智能技术生成

聚合查询

聚合查询是指一个数据表中的一个字段的数据进行部分或者全部进行统计查询,查询book数据表中的全部书的平均价格,查询所有书的总数等都需要聚合查询。

  1. 整表聚合
    导入方式:from django.db.models import *
    聚合函数:Sum, Avg, Count, Max, Min
    语法:MyModel.objects.aggregate(结果变量名= 聚合函数(“列”))
    返回结果:结果变量名和值形成的字典,{‘结果变量名’:值}
>>> from django.db.models import *
>>> Book.objects.aggregate(Summary = Sum('price') )
{'Summary': Decimal('170.00')}
>>> Book.objects.aggregate(Summary = Avg('price') )
{'Summary': Decimal('56.666667')}
  1. 分组聚合
    分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值,即为查询集的每一项生成的聚合
    语法:QuerySet.annotate(结果变量名=聚合函数(‘列’))
    返回值:QuerySet
    步骤:
    • 通过先用查询结果MyModel.objects.values查找查询要分组的列,MyModel.objects.values(‘列1’,‘列2’),得到一个QuerySet
    • 通过返回结果的QuerySet.annotate方法分组聚合得到分组结果
>>> books = Book.objects.values('pub','is_active')
>>> books
<QuerySet [{'pub': '清华大学出版社', 'is_active': True}, {'pub': '机械工业出版社', 'is_a
ctive': True}, {'pub': '清华大学出版社', 'is_active': True}]>

>>> books.annotate(myCount = Count('pub'))
<QuerySet [{'pub': '清华大学出版社', 'is_active': True, 'myCount': 2}, {'pub': '机械工业
出版社', 'is_active': True, 'myCount': 1}]>

>>> books.annotate(active_count = Count('is_active'))
<QuerySet [{'pub': '清华大学出版社', 'is_active': True, 'active_count': 2}, {'pub': '机
械工业出版社', 'is_active': True, 'active_count': 1}]>
>>> books.annotate(myCount = Count('pub')).filter(myCount__gt=1)
<QuerySet [{'pub': '清华大学出版社', 'is_active': True, 'myCount': 2}]>

原生数据库操作

Django也可以支持直接用sql语句的方式通信数据库
查询:使用MyModel.objects.raw()进行数据库查询操作查询
语法:MyModel.objects.raw(sql语句,拼接参数)
返回值:RawQuerySet集合对象【只支持基础操作,如循环】

>>> books = Book.objects.raw('select * from book')
>>> books
<RawQuerySet: select * from book>
>>> for book in books:
...     print(book)
...
Django_清华大学出版社_70.00_75.00
Linux_机械工业出版社_80.00_65.00
Python_清华大学出版社_20.00_25.00

完全跨过模型类操作数据库 - 查询/更新/删除

  1. 导入cursor所在的包
    from django.db import connection
  2. 用创建cursor类的构造函数创建cursor对象,再使用cursor对象,为保证在出现异常时能释放cursor资源,通常使用with语句进行创建操作
    语法:
    from django.db import connection
    with connection.cursor() as cur:
    cur.execute(‘执行sql语句’,‘拼接参数’)

admin管理后台

django提供了比较完善的后台管理数据库的接口,可供开发过程中的调试和测试使用
django会搜集所有已注册的模型类,为这些模型类提供数据管理界面,供开发者使用
创建后台管理账号python manage.py createsuperuser

注册自定义模型类

注册步骤:
1. 在应用app中的admin.py中导入注册要管理的模型models类
2. 调用admin.site.register方法进行注册,如admin.site.register(自定义模型类)

模型管理器类

作用:为后台管理界面添加便于操作的新功能
模型管理器类需要继承django.contrib.admin里的ModelAdmin类
使用方法:

  1. 在<应用app>/admin.py中定义模型管理器类
    class xxxManage(admin.ModelAdmin):

  2. 绑定注册管理器和模型类
    from django.contrib import admin
    from .models import *
    admin.site.register(YYYY , XXXXManager) # 绑定YYYY模型类 和 XXXXManager管理器类
    绑定前:按照Book模型类中__str__中定义的格式输出
    在这里插入图片描述
    绑定后:
    在这里插入图片描述

from django.contrib import admin
from .models import *


class BookManager(admin.ModelAdmin):
    # 列表页显示哪些字段的列
    list_display = ['id', 'title', 'pub', 'price', 'market_price', 'info']
    # 控制list_display中的字段,那些可以链接到修改页
    # 点击title就可以链接到修改页面
    list_display_links = ['title']
    # 添加过滤器
    list_filter = ['pub']
    # 添加搜索框【模糊查询】
    search_fields = ['title']
    # 添加可以在列表页编辑的字段
    list_editable = ['price']

class AuthorManager(admin.ModelAdmin):
    list_display = ['id', 'name', 'age', 'email']

# Register your models here.
admin.site.register(Book,BookManager)
admin.site.register(Author, AuthorManager)

  1. list_display 去控制哪些字段会显示在Admin的修改列表页面中
  2. list_display_links 可以控制list_display中的字段是否应该链接到对象的“修改”页面
  3. list_filter 设置激活Admin 修改列表页面右侧栏中的过滤器
  4. search_fields 设置启用Admin 更改列表页面上的搜索框
  5. list_editable 设置为模型上字段名称列表,将允许在更改列表页面上进行编辑
Meta类
class Book(models.Model):
    title = models.CharField("书名", max_length=50, default='', unique=True)
    pub = models.CharField("出版社", max_length=100, default='')
    price = models.DecimalField("图书定价", max_digits=7, decimal_places=2, default=0.0)
    market_price = models.DecimalField("图书零售价", max_digits=7, decimal_places=2, default=0.0)
    info = models.CharField("书籍信息", max_length=100, default='', blank=True)
    is_active = models.BooleanField("活跃",default=True)

    def __str__(self):
        return '%s_%s_%s_%s'%(self.title,self.pub,self.price,self.market_price)

    class Meta:
        db_table = 'book'
        # 给模型对象一个易于理解的名称(单数),用于显示在/admin管理界面中
        verbose_name = '图书'
        # 给模型对象一个易于理解的名称(复数),用于显示在/admin管理界面中
        verbose_name_plural = verbose_name

关系映射

一对一映射

一对一是表示现实事务间存在的一对一的对应关系
语法:OneToOneField(类名, on_delete= xxx)级联删除
class A(model.Model):

class B(model.Model):
属性 = models.OneToOneField(A, on_delete = xxx)

on_delete 级联删除选项

  1. models.CASCADE 级联删除。Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象
  2. models.PROTECT 抛出ProtectError以阻止被引用对象的删除;【等同于mysql默认的RESTRICT】
  3. SET_NULL设置ForeignKey null; 需要指定null = True
  4. SET_DEFAULT 将ForeignKey设置为其默认值,必须设置ForeignKey的默认值
// 创建数据
>>> from oto.models import *
>>> author = Author.objects.create(name = 'Wang')
// author 是外键的类,必须对应相同的类对象
>>> wife = Wife.objects.create(name = 'Wife Wang',author = author)
>>> author = Author.objects.create(name = 'Guo')
// author_id 是外键的类属性,必须对应正确的字段值
>>> wife = Wife.objects.create(name = 'Wife Guo',author_id = author.id)

查询:
① 正向查询:直接通过外键属性查询,称为正向查询

>>> wife = Wife.objects.get(name = 'Wife Guo')
>>> print(wife.name,'的老公是',wife.author.name)
Wife Guo 的老公是 Guo

② 反向查询:没有外键的一方,可以通过调用反向属性查询到关联的另一方
反向关联属性为“实例对象.引用类名(小写)”,当反向引用不存在时,会触发异常,若存在,则返回引用类的对象

>>> author = Author.objects.get(id = 1)
>>> author
<Author: Author object (1)>
>>> author.wife
<Wife: Wife object (1)>
>>> print(author.wife.name)
Wife Wang
一对多映射

一对多是表示现实十五之间存在的一对多的对应关系。
一对多需要明确出具体角色,在多表上设置外键。
创建:
class A(models.Model):

class B(models.Model):
属性 = models.ForeignKey("…"的模型类, on_delete = xx)
必须指定on_delete的模式

from django.db import models
# Create your models here.
class Publisher(models.Model):
    name = models.CharField('名称', max_length=11, unique=True)
class Book(models.Model):
    title = models.CharField('书名', max_length=11)
    price = models.DecimalField('价格', max_digits=7, decimal_places=2)
    pub = models.ForeignKey('Publisher', on_delete=models.CASCADE)
// 创建
>>> from otm.models import *
>>> publisher = Publisher.objects.create(name = '清华大学出版社')
>>> publisher = Publisher.objects.create(name = '北京大学出版社')
>>> book = Book.objects.create(title = 'HTML & CSS',price = 79.80,pub_id = 1)
>>> book = Book.objects.create(title = '数据结构',price = 35,pub_id = 1)

查询:
① 正向查询【通过Book查询Publisher】

>>> from otm.models import *
>>> book = Book.objects.get(id = 1)
>>> book.pub.name
'清华大学出版社'

② 反向查询【通过Publisher查询Book】
反向查询都有一个反向属性为‘多表’_set【小写】,来获得多表中所对应的多个数据对象

>>> pub1 = Publisher.objects.get(id =1)
>>> books = pub1.book_set.all() // 
>>> for book in books:
...     print(book.title)
...
HTML & CSS
数据结构
>>> books2 = Book.objects.filter(pub = pub1)
>>> for book in books2:
...     print(book.title)
...
HTML & CSS
数据结构
多对多映射

多对多表达对象之间多对多复杂关系,如:每个人都有不同的学校(小学,初中,高中),每个学校都有不同的学生
mysql中创建多对多关系需要依赖第三张表来实现
Django中无需手动创建第三张表,Django自动完成

from django.db import models
# Create your models here.
class Author(models.Model):
    name = models.CharField('姓名', max_length=11)
class Book(models.Model):
    title = models.CharField('书名', max_length=11)
    authors = models.ManyToManyField(Author)
// 创建
>>> author1 = Author.objects.get(id =1)
// 反向创建
>>> book11 = author1.book_set.create(title = "Python")
>>> author2 = Author.objects.get(id =2)
>>> author2.book_set.add(book11)
//  正向创建
>>> book = Book.objects.create(title = 'Java')
>>> book.authors.add(author1)
>>> author3 = book.authors.create(name = 'Season')

// 正向查询
>>> book.authors.all()
<QuerySet [<Author: Author object (1)>, <Author: Author object (3)>]>
>>> for author in book.authors.all():
...     print(author.name)
...
Ma Zhikai
Season

// 反向查询
>>> author = Author.objects.get(name = 'Ma Zhikai')
>>> books = author.book_set.all()
>>> for book in books:
...     print(book.title)
...
Python
Java
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Django时,使用PyCharm作为开发工具可以提高效率。PyCharm是一款功能强大的Python集成开发环境,它提供了丰富的功能和工具,可以帮助开发者更好地编写和调试Django应用程序。 在学习Django的过程中,可以使用PyCharm创建Django项目,并使用其内置的Django支持功能来简化开发过程。PyCharm可以自动识别Django项目的结构,并提供代码补全、语法检查、调试等功能,帮助开发者更快地编写和调试代码。 此外,PyCharm还提供了集成的版本控制系统,如Git,可以方便地管理和追踪代码的变化。它还支持自动化测试和部署,可以帮助开发者更好地进行项目管理和发布。 总之,使用PyCharm作为开发工具可以提高Django学习的效率和便利性。它的强大功能和友好的用户界面使得开发者可以更专注于代码的编写和项目的开发。\[1\] \[2\] \[3\] #### 引用[.reference_title] - *1* *3* [PyCharm平台下初学Django框架](https://blog.csdn.net/howard2005/article/details/93491364)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [pycharm平台下的Django教程](https://blog.csdn.net/Sunshine_ZCC/article/details/73918408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值