Django:Model系统
一、表结构
class Author(models.Model):
name=models.CharField(max_length=32)
age=models.IntegerField()
def __str__(self):
return self.name
class Publisher(models.Model):
name=models.CharField(max_length=32)
email=models.EmailField(unique=True)
def __str__(self):
return self.name
class Book(models.Model):
title=models.CharField(max_length=32)
author=models.ForeignKey("Author")
publisher=models.ForeignKey("Publisher")
content=models.TextField()
date=models.DateField(auto_now=True)
def __str__(self):
return self.title
什么鬼?没关系,让我给你仔细说说————
二、表结构设计
在你使用数据库时,一个个创建,很麻烦,所以django提供了ORM。然而,怎么用?先不说这个,先设计一下图书管理系统的表结构——

这是书表。那么有个问题——author_id是啥?直接写作者名不就OK了?注意了,我是用fk的方式(学过MySQL的应该知道,一对多关联)做的。在ORM里,可以自动帮你转换成一个对象。

这是Publisher表。没什么可说的,id字段就是默认的关联(存储id,ORM自动根据id查到Publisher的对象)

也没什么可说的。下面来说说细节问题吧:

这个你可以按照自己的喜好来确定这些细节。设计完了,你要再梳理一遍。
三、Model模型
Django ORM支持很多字段。

Django字段还支持很多参数。

Django的表里有一些存储在数据库里的元信息,可以在表里写Meta类。

四、连表操作
连表操作之fk
连表操作之o2o
连表操作之m2m五、创建表结构
python manage.py makemigrations python manage.py migrate
六、Model操作
需求1:创建苹果出版社
################第一种方式############
models.Publisher.objects.create(
id=1,
name="苹果出版社",
email="apple@126.com"
)
############### 第二种方式##############
obj = models.Publisher(
id=1,
name="苹果出版社",
email="apple@126.com"
)
obj.save()
需求二、删除苹果出版社
obj = models.Publisher.objects.get(id=1) # 获取苹果出版社的对象 obj.delete() # 删除对象
需求三、查看苹果出版社的邮箱
#########第一种####### obj=models.Publisher.objects.filter(id=1) # 获取所有id=1的对象,如果没有则为空 print(obj.first().email) # 所有对象的第一个的邮箱 #########第二种####### obj=models.Publisher.objects.get(id=1) # 获取一个id=1的对象,如果没有则报错 print(obj.email)
需求四、更改苹果出版社的邮箱
########第一种######## obj=models.Publisher.objects.get(name="苹果出版社") obj.email = "apple@163.com" obj.save() ########第二种(支持批量修改)## obj=models.Publisher.objects.filter(name="苹果出版社") obj.update(email="apple@163.com")
需求五、创建《跟老男孩学Linux》书
Author.objects.create(id=1,name='老男孩',age=100) Book.objects.create(id=1,title='跟老男孩 Linux',author_id=1,publisher_id=1,content="112233",date="2019-07-12") # 用 字段_id 设置fk的id
需求六、查询《跟老男孩学Linux》的出版社的邮箱
obj=Book.objects.get(title="跟老男孩学Linux") # filter or get print(obj.publisher.email)
需求七、根据出版社邮箱查所有的书
obj=Book.objects.filter(publisher__email="apple@163.com")
需求八、查表的数据库里的名字
models.Book._meta.db_table
需求九、执行原生SQL拿到全部的书
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from book """)
row = cursor.fetchone()
需求10、前几天,老男孩过了生日,现在要你在不知道他年龄的情况下改他的年龄
from django.db.models import F
models.Author.objects.update(age=F('age')+1)
需求11、排序
orderby_id_all = Author.objects.all().order_by("id")
# 全部根据id排序
orderby_name_all = Author.objects.all().order_by("name")
# 全都根据name排序
需求12、多字段搜索
######### 写法1(不支持多字段,仅支持查询) ###########
from django.db.models import Q
q = Q(name="苹果出版社")
filterby_q = models.Publisher.objects.filter(q)
######### 写法2(支持多字段,可以搜索了) #############
from django.db.models import Q
q = Q()
q.connector = "OR"
q.children.append("name",'苹果出版社')
q.children.append("email","苹果出版社")
filterby_q = models.Publisher.objects.filter(q)
需求13、查苹果出版社出版的所有书籍
publisher=models.Publisher.objects.filter(name="苹果出版社") books=publisher.book_set # fk的反向查询
需求14、o2o反向查询(与项目无关)
o = models.Tb.objects.get(fff="111") o.tb2 # 直接obj.表名小写
需求15、m2m正向查询(与项目无关)
ttt = models.Tb.objects.get(fff="222") ttt.sdf.all() # 字段是ManyToManyRel # ManyToManyRel().count() 有多少个数据 # ManyToManyRel().all() 数据列表
需求16、取到所有书本(id小于3)的数量
a=Author.objects.all().extra(select={"n",'select count(1) from cmdb_book where id<3'},select_params=[1])
for obj in a:
print(obj.id,obj.name,obj.n)
需求17、分组(annotate)
from django.db.models import Count, Sum, Max, Min
v = Author.objects.values("name","id").annotate(xxxx=Count(5)) # group by 加聚合函数
print(v.query) # sql语句
需求18、annotate having
from django.db.models import Count, Sum, Max, Min
v = Author.objects.values("name","id").annotate(xxxx=Count(5)).filter(xxxx__gt=18) # group by 加聚合函数 filter在前是where filter在后是having
print(v.query) # sql语句
需求19、复杂条件过滤
Author.objects.filter(id__gt=1) # 大于 Author.objects.filter(id__lt=1) # 小于 Author.objects.filter(id__gte=1) # 大于等于 Author.objects.filter(id__lte=1) # 小于等于 Author.objects.filter(id__in=[1,2,3]) # 在谁里面(必须传列表) Author.objects.filter(id__startswith="老男") # 从什么开始 Author.objects.filter(id__endswith="老男") Author.objects.filter(id__contains="男孩") # 包含 Author.objects.exclude(id__gt=1) # 排除,不等于
需求20、查一本书的名字和作者
#######第一种######
Book.objects.values('name','author') # 列表套字典
#######第二种######
Book.objects.all().only('name','author') # 对象
# 注意:想拿什么取什么
需求21、查一本书除了出版社以外的信息
Book.objects.all().defer('publisher')
七、QuerySet操作
在前面我们讲的一大堆需求里面,取到的数据大都是QuerySets。所以,你必须要会操作QuerySets,因为他比values好用。
1 ################################# 2 querysets = models.Book.objects.all() 3 for row in querysets: # 可以循环拿到字段的数据 4 print(row.title,row.publisher.name,row.author.name) 5 6 ################################# 7 querysets = models.Book.objects.all().order_by("id") # 排序 8 9 ################################## 10 v = models.Book.objects.all().values() # 换成列表套字典的格式
八、作业
作业需求:
1. 图书管理系统
a. 表结构课上
b. 列出所有图书,作者,出版社
c. 可以增删改查
九、练习题
0. 创建博客表结构,自己设计,并且完成下面练习题:
- 创建5条account和5条新tag纪录
- 创建5条article信息,关联上面的不同的用户和tag
- 在account表里找到用户名包含al的纪录,然后把密码改掉
- 在article表找到文章内容包含“电影”2个字的,把这些文章加上”大文娱”tag
- 把用户elina发表的文章找出来,并且把作者都改成alex
- 找到用户表里注册日期在2018-04月,并且signature为空的纪录
- 打到文章中标签为“投资”的所有文章
- 找到每个月8号注册的用户
- 找到每年5月发表的文章
- 找到2015-2017年5月发表的文章
- 找到文章作者以’a’或’k’开头的文章

浙公网安备 33010602011771号