聚合查询
对一个数据表的中的某个字段 数据进行部分或者全部进行统计查询,如查询book数据表中的全部书籍的平均价格,查询书籍的总数,等都要用到聚合查询
整表聚合,对整个表进行聚合查询
- 导入方法
from django.db.models import *
,其中聚合函数有Sum,Max,Min,Avg,Count等 - 语法:
MyModel.objects.aggregate(结果变量名= 聚合函数(‘列’))
- 返回值:
{’结果变量名’: 值}
In [10]: Book.objects.aggregate(Count_index=Count('title'))
Out[10]: {'Count_index': 5}
In [11]: Book.objects.aggregate(Max_index=Max('price'))
Out[11]: {'Max_index': Decimal('151.00')}
分组聚合,通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值,即为查询集的每一项生成聚合
- 先进行分组
obj = MyModel.objects.values(’列1')
返回值为QuerySet - 然后再进行分组聚合
语法:
QuerySet.annotate(结果变量名=聚合函数(‘列’))
返回值:QuerySet
In [12]: obj = Book.objects.values('pub')
In [13]: obj
Out[13]: <QuerySet [{'pub': '清华大学出版社'}, {'pub': '清华大学出版社'}, {'pub': '机械工业出版社'}, {'pub': '机械工业出版社'}, {'pub': '清华大学出版社'}]>
In [14]: re = obj.annotate(count=Count('title'))
In [15]: re
Out[15]: <QuerySet [{'pub': '清华大学出版社', 'count': 3}, {'pub': '机械工业出版社', 'count': 2}]>
将整个表通过pub进行分组,在根据分组进行求书籍的总数
原生数据库操作
django支持直接用sql语句方式来操作数据库
语法:MyModel.objects.raw(sql语句,拼接参数)
返回值RawQuerySet集合对象,只支持简单操作,比如循环,不支持继续添加django语句
admin管理后台
django提供了比较完善的后台数据库数据管理接口,可供开发过程中的调用和测试使用
django会搜集已经注册的模型类,为这些类提供数据管理页面,供开发者使用
配置步骤
创建一个最高权限的用户
python manage.py createsuperuser
回车后会提示输入用户名,邮箱,密码(密码不要设置太简单,长度要高于8位
创建好之后,进入http://127.0.0.1:8000/admin/网址,就可以登录超级账号了
在超级账号中可以创建组和用户
注册自定义模型类
如要自己定义的类也能在admin后台管理界面中显示和管理,需要将自己的类注册到后台管理页面
在应用中的admin.py 中导入我们要注册的模型类from .models improt Book
调用admin.site.register(自定义的模型类)
from django.contrib import admin
from .models import Book
# Register your models here.
admin.site.register(Book)
显示样式是根据类中的__str__()来显示的
模型管理器类
作用:
为后台界面添加便于操作的新功能
说明:
后台管理器需要继承django.contrib.admin中的ModelAdmin类
在app/admin.py中创建类class xxx(admin.ModelAdmin):
from django.contrib import admin
from .models import Book
from .models import Author
# Register your models here.
admin.site.register(Author)
class BookMange(admin.ModelAdmin):
list_display = ['id', 'title', 'pub', 'price', 'mark_price']
admin.site.register(Book, BookMange)
添加第一行的列属性
列的名称为当初创建属性时传递的参数
修改第一行的显示的列属性 list_display = ['id', 'title', 'pub', 'price', 'mark_price','is_active'] 修改可点击的属性进入修改页 list_display_links = ['id','title'] 过滤器 list_filter = ['pub'] 添加搜索框 search_fields = ['title'] 可编辑列表,在列表页就可以对数据进行修改 list_editable = ['price','mark_price'] 还有很多数据可以进行修改
官方网站
https://docs.djangoproject.com/en/2.2/ref/contrib/admin/
Meta类
就是models中的meta类
可以在其中再添加属性,更改后台数据表单的显示
如
在前段的显示以前这个表为Books,经过修改后Books变更为图书库
关系映射
在关系型数据库中一般不会把所有数据放在一张表当中,一般会放在多张表当中,这样就会产生表与表之间的联系,也会产生映射关系
1.一对一映射
一个身份证对应一个人
语法:
OneToOneFiled(类名,on_delete=xxx)
class A (models.Model) :
… class B (models.Model) :
属性 = OneToOneField(A,on_delete=xxx)
两者进行联系时,会在数据库中新添加一个属性为:属性_id
例如 :
author = OneToOneField(Author,on_delete=models.CASEADE)
则在数据库中wife这个表中的属性会添加一个新的数据为author_id
特殊字段选项
models.CASEADE,共生死,删除其中一个,所有表和这个数据有关的数据全部都要删除
models.PROTECT,抛出ERROR来阻止共生死的删除 SET_NULL
,删除后,与其有关联的数据都会被置成null,但是前提在创建属性的时候要定义其null为True创建数据
无外键模型类[Author]类
author1 = Author.objects.create(name=‘张三’),
有外键的模型类创建[wife]类
wife1 = Wife.objects.create(name=‘张夫人’,author=author1)
(这里的author为创建外键联系中的属性
关联外键
wife1 = Wife.objects.create(name=‘张夫人’,author_id=1)
class Author(models.Model):
name = models.CharField('姓名',max_length=11)
class Wife(models.Model):
name = models.CharField('姓名',max_length=11)
author = models.OneToOneField(Author,on_delete=models.CASCADE)
执行makemigrations,migrate之后
数据库中的oto_wife中会多出author_id的字段,这是一对一的外键联系
下面创建一条映射数据
In [1]: from oto.models import *
In [2]: a1 = Author.objects.create(name='张三')
In [3]: w1 = Wife.objects.create(name='张夫人',author=a1)
查询:
正向查询
知道绑定了外键的属性
语法:object.绑定的外键属性名称.属性名
In [1]: wife = Wife.objects.get(name='张夫人')
In [2]: print('{}的丈夫为{}'.format(wife.name,wife.author.name))
张夫人的丈夫为张三
反向查询
知道了被绑定外键的属性
语法:
object.外键名称小写.属性名
In [3]: author = Author.objects.get(name='张三')
In [4]: author.wife.name
Out[5]: '张夫人'
2.一对多映射
一个班级中有多个学生
语法:
ForeignKey(类名,on_delete=xxx)
class A(models.Model):
…
class B(models.Model):
…
b = models.ForeignKey(A, on_delete=xxx)
class Publish(models.Model):
name = models.CharField('出版社', max_length=20)
class Book(models.Model):
name = models.CharField('书名', max_length=20)
publish = models.ForeignKey(Publish, on_delete=models.CASCADE)
查询:
正向查询
绑定了外键的属性
通过.外键的方式即可
In [5]: b1 = Book.objects.get(name='Java')
In [6]: b1
Out[6]: <Book: Book object (2)>
In [7]: b1.publish.name
Out[7]: '清华大学出版社'
反向查询
=被绑定外键的类有一个绑定外键名称的小写+_set的属性,通过.all()的方法,可以获取全部的绑定数据
语法:
object.类名小写_set_all()
In [12]: books = p1.book_set.all()
In [13]: for i in books:
...: print(i.name)
...:
...:
Pytho
Java
C++
Django
3.多对多映射
一个学生能报多门课程,一个课程能有多个学生报名
语法:在两个关联的类中的任意一个加上该语法即可
models.ManyToManyField(MyModel)
class A(models.Model):
…
class B(models.Model):
…
a = models.ManyToManyField(A)
class Book(models.Model):
name = models.CharField('书名',max_length=20)
class Author(models.Model):
name = models.CharField('姓名',max_length=11)
book = models.ManyToManyField(Book)
Author中含有book的外键属性
创建两个表,会生成三个表,其中一个是关联两个表的表内容为
插入数据
1.先创建book类
In [10]: b1 = Book.objects.create(name='Python')
In [11]: b2 = Book.objects.create(name='完美世界')
In [12]: b3 = Book.objects.create(name='诡秘之主')
再创建Author类关联数据
1.创建一个author类
In [13]: a1 = Author.objects.create(name='张三')
In [14]: b1.author_set.add(a1)
2.直接创建,并关联
In [15]: a2 = b1.author_set.create(name='李四')
这样就可以将张三和李四共同关联到Python这本书上了
2.先创建Author
In [25]: a4 = Author.objects.create(name='y小伙')
在创建book类,将他们进行关联
1.先创建book类
In [27]: b5 = Book.objects.create(name='十口棺材')
In [28]: a4.book.add(b5)
2.直接创建,并关联
In [29]: b6 = a4.book.create(name='环界')
查询
正向查询
因为Author中有book属性,所有其是正向查询
object.book.all()
反向查询
object.author_set.all()