怎么备份网站,深圳 网站制作需要多少钱 网络服务,广告推广营销网站,wordpress怎么社交分享模型层
与数据库相关的#xff0c;用于定义数据模型和数据库表结构。 在Django应用程序中#xff0c;模型层是数据库和应用程序之间的接口#xff0c;它负责处理所有与数据库相关的操作#xff0c;例如创建、读取、更新和删除记录。Django的模型层还提供了一些高级功能 首…模型层
与数据库相关的用于定义数据模型和数据库表结构。 在Django应用程序中模型层是数据库和应用程序之间的接口它负责处理所有与数据库相关的操作例如创建、读取、更新和删除记录。Django的模型层还提供了一些高级功能 首先准备工作切换mysql数据库
DATABASES {default: {# ENGINE: django.db.backends.sqlite3,ENGINE: django.db.backends.mysql,NAME: db2,USER: root,PASSWORD: 12345,HOST: 127.0.0.1,PORT: 3306,CHARSET: utf8}
测试脚本
接下来我们可以使用测试脚本来直接运行注意后面的Django代码必须写在测试脚本下面
把测试脚本放进一个py文件即可
import os
import sys
import django
if __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, 项目名称.settings)import djangodjango.setup()django.setup()from app01 import models 常用的关键字
create描述filter创建数据并直接获取当前创建的数据对象first/last根据条件筛选数据 结果是QuerySet [数据对象1,数据对象2]update拿queryset里面第一个元素/拿queryset里面最后一个元素delete删除数据(批量删除)all查询所有数据 结果是QuerySet [数据对象1,数据对象2]values根据指定字段获取数据 结果是QuerySet [{}},{},{},{}]values_list根据指定字段获取数据 结果是QuerySet [(),(),(),()]distinct去重 数据一定要一模一样才可以 如果有主键肯定不行order_by根据指定条件排序 默认是升序 字段前面加负号就是降序get根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用exclude取反操作reverse颠倒顺序(被操作的对象必须是已经排过序的才可以)count统计结果集中数据的个数exists 判断结果集中是否含有数据 如果有则返回True 没有则返回False 示例
如果使用get建议加上try
if __name__ __main__:os.environ.setdefault(DJANGO_SETTINGS_MODULE, djangoProject.settings)import djangodjango.setup()from app01 import modelstry:res models.Userinfo.objects.filter(pk1).get()except Exception as f:print(f)
value与value_list
res models.Userinfo.objects.values(id, username, password)for i in res:print(i.get(id)) # QuerySet [{id: 1, username: kk, password: 1234}, {id: 2, username: cc, password: 232}, {id: 3, username: rer, password: 323}]# 1 2 3 索引0为id1为usernameprint(res) # QuerySet [(1, kk, 1234), (2, cc, 232), (3, rer, 323)]
查看内部sql语句
只有返回的结果是queryset对时才能用query查看
res models.Userinfo.objects.values(id, username, password)for i in res:print(i.get(id)) print(res.query)SELECT app01_userinfo.id, app01_userinfo.username, app01_userinfo.password FROM app01_userinfo
distinct 去重 res models.Userinfo.objects.all().values(password).distinct()print(res)order_by 排序 res1 models.Userinfo.objects.all().order_by(username) # QuerySet [Userinfo: Userinfo object (2), Userinfo: Userinfo object (1), Userinfo: Userinfo object (3)]print(res1)
默认升序 基于双下划线的查询 查询年龄大于xx
查看年龄大于或小于32的数据res models.Userinfo.objects.filter(age__gt32)\(age__lt32)print(res)查看大于等于或小于等于32的数据res models.Userinfo.objects.filter(age__gte32)\(age__lte32)print(res)查看18-32之间的数据收尾都要res models.Userinfo.objects.filter(age__range[18, 32])print(res)查看带s字段的数据res models.Userinfo.objects.filter(username__containss)print(res) # QuerySet [Userinfo: Userinfo object (2)]姓名以c开头或结尾startwith\endwithres models.Userinfo.objects.filter(username__startswithc)print(res)查看注册时间两个参数auto_now false 当我们更新数据时只要更新就会更新时间auto_add False 当auto_addTrue时添加数据时会自动添加当前时间register_time models.DateTimeField(auto_nowTrue, auto_now_addTrue) 多表查询跨表查询 orm外键字段的创建
和mysql外键关系一样的判断规律
1.一对多 外键字段建在多的一方2.多对多 外键字段统一建在第三张关系表3.一对一 建在任何一方都可以但是建议建在查询频率较高的表中注意目前关系的判断可以采用表与表之间换位思考原则 基础表的准备 创建基础表书籍表、出版社表、作者表、作者详情) 确定外键关系 orm的创建 一对一 ORM与MySQL一致 外键字段建在查询较高的一方 一对多 ORM与MySQL一致 外键建在多的一方多对多 ORM比MySQL有更多的变化1.外键字段可以直接建在某张表中查询频率较高的内部会自动帮你创建第三张关系表2.自己创建第三张关系表并创建外键字段 4. 针对一对多和一对一同步到表中之后自动_id的后缀,如book中的外键字段publish,会自动变成publish_id。
建表
class Book(models.Model):name models.CharField(max_length32) # 书名price models.DecimalField(max_digits8, decimal_places2) # 价格publish_date models.DateField(auto_now_addTrue) # 出版日期maichu models.IntegerField(2000) # 卖出数量kucun models.IntegerField(3000) # 库存建立外键# 一对多publish models.ForeignKey(toPublish, on_deleteTrue) # publish不需要加_id当为外键时自动会加# 多对多authors models.ManyToManyField(toAuthor)class Publish(models.Model):name models.CharField(max_length32) # 出版社名称addr models.CharField(max_length32) # 出版社def __str__(self):return self.nameclass Author(models.Model): #作者表name models.CharField(max_length32)age models.IntegerField()# 一对一author_list models.OneToOneField(toAuthorList, on_deleteTrue)class AuthorList(models.Model): # 作者详情表phone models.CharField(max_length32)addr models.CharField(max_length32)
注意事项
1.创建一对多关系和sql语句一样外键建立到多的那张表上不同的是我们可以不讲究关联表和被关联表的建立顺序。字段类为ForeignKey在django2.x版本以上建立一对多关系时需要指定on_delete参数为CASCADE不加会报错不过也不一定就是CASCADE可能为其他实参这里不展开。建立外键时系统会自动加上_id后缀作为字段名。2.创建多对多关系sql中是将两张表建立好后将外键字段创建在第三张表中而django为我们省去了这一步骤我们可以在多对多关系双方的一个模型表中直接建立一个虚拟外键ManyToManyField在底层sql依旧创建了第三张表来存储两表的多对多关系但是在orm操作中我们就可以将模型表中的外键当做实实在在的联系因为在查询时我们感受不到第三张的表的存在。多对多关系的外键没有on_delete关键字参数。3.创建一对多关系一对一的字段类为OneToOneField,建议建立在查询频率高的一方。建立一对一关系时需要指定on_delete参数否则报错。 一对多的外键增删改查
增加
models.Book.objects.create(name三味书屋, price1500, publish_date2022-1-1, maichu3500, kucun2000, publish_id1)第二种方式通过对象来添加publish_obj models.Publish.objects.filter(pk1).first()models.Book.objects.create(name三味书屋, price1500, publish_date2022-1-1, maichu3500, kucun2000,publishpublish_obj)
删除 删除models.Publish.objects.filter(pk1).delete() # 级联删除时会删除出版社里所有的书籍所以不建议这样删除models.Book.objects.filter(pk1).delete() # 只删除图书即可
修改 修改models.Book.objects.filter(pk1).update(publish_id3)第二种方式publish_obj models.Publish.objects.filter(pk1).first()models.Book.objects.filter(pk1).update(publish_idpublish_obj) 多对多的外键增删改查
增加add
book_obj models.Book.objects.filter(pk3).first()
print(book_obj.authors) # 打印结果为dj5.Author.None说明已经跳转到第三张表了
book_obj.authors.add(1)使用对象添加book_objmodels.Book.objects.filter(pk2).first()authors_obj models.Author.objects.filter(pk3).filter()
authors_obj1 models.Author.objects.filter(pk4).filter()
book_obj.authors.add(authors_obj,authors_obj1)
修改set
修改作者
修改
book_obj.authors.set([2, 4]) # 将d为2的书籍绑定给主键为2,4的作者
使用对象修改book_obj.authors.set(authors_obj)
删除remove
删除
book_obj.authors.remove(1,2,3) # 删除主键id为1,2,3的书籍使用对象删除
book_obj.authors.remove(authors_obj)
清空(creal)
清空i书籍id为1 的所有作者
使用clear清空直接清理即可
book_obj.authors.clear()
直接清空所有id 查询之正反向
正向外键字段在我这边那么我查询你就是正向
反向外键字段不在我这边那么我查询你就是反向
图书与出版社比较图书为多出版社为一那么外键字段就在我这边使用图书查询出版社就是正向查询 book------外键字段再我这正向查询--------publish按(外键)字段 publish-----外键字段不在我这反向查询------book按表名小写
或加上_set
出版社查询图书出版社为一图书为多那么外接字段就不在我这边使用出版社查询图书就是反向查询 子查询例题
查询书籍主键为3的出版社
res models.Book.objects.filter(pk3).first()
1.首先筛选出id3的书籍2.判断正反向图书差出版社一对多为正向3.直接打印出结果如果需要地址则可以使用。addrprint(res.publish)
print(res.publish.addr)查询书籍主键为3的作者
# 查询书籍主键为3的作者
res models.Book.objects.filter(pk3).first()
print(res.authors.all()) 查询作者鲁迅的电话号码 # 3.查询作者鲁迅的电话号码
res models.Author.objects.filter(name鲁迅).first()
print(res.author_list.phone)
查询出版社是浓浓出版社出版的书
查询出版社是东方出版社出版的书
publish_obj models.Publish.objects.filter(name浓浓出版社).first()
res publish_obj.book_set
print(res.all())# QuerySet [Book: Book object (3), Book: Book object (4)]
查询作者是鲁迅写过的书
publish_obj models.Author.objects.filter(name鲁迅).first()
res publish_obj.book_set.all()
print(res)
查询手机号是110的作者姓名
查询手机号是110的作者姓名
publish_obj models.AuthorList.objects.filter(phone110).first()
res publish_obj.author
print(res.name) 联表查询
基于双下划线的查询
1.查询鲁迅的手机号和作者姓名
res models.Author.objects.filter(name鲁迅).values(author_list__phone, name)
print(res)
2.查询书籍主键为3的出版社名称和书的名称
查询书籍主键为3的出版社名称和书的名称
res models.Book.objects.filter(pk3).values(publish__name, name)
print(res) # QuerySet [{publish__name: 浓浓出版社, name: 三味书屋}]
3.查询书籍主键为1的作者姓名
查询书籍主键为3的作者姓名
res models.Book.objects.filter(pk3).values(authors__name)
print(res)
查询书籍主键为3的作者手机号
查询书籍主键是3的作者的手机号
res models.Book.objects.filter(pk3).values(authors__author_list__phone)
print(res) 聚合查询
通常聚合都是通过分组使用只要和数据库相关的模块基本都在Django.db.models里如果没有可能在Django.db中
在orm中聚合函数的关键字aggregate
from django.db.models import Avg, Sum, Max, Min, Count
res models.Book.objects.aggregate()
查询所有书籍的金额
sql语句
select avgpricefrom bookorm语句from django.db.models import Avg, Sum, Max, Min, Count
res models.Book.objects.aggregate(agv_priceAvg(price), sum_priceSum(price)) 分组查询 严格模式ONLY_FULL_GROUP_BY set global sql_modeONLY_FULL_GROUP_BY
案例
1.统计每一本书的作者个数
# 统计每个书的作者
res models.Book.objects.annotate(authors_numCount(authors)).values(name, authors__name)
print(res) 事物
事物是mysql数据库中一个重要的概念
目的是为了保证多sql语句执行成功或执行失败前后保持一致保证数据安全
开启事物