当前位置: 首页 > news >正文

网站更改备案主体大浪网站建设

网站更改备案主体,大浪网站建设,防封电销系统,棋牌软件挂脚本定制开发文章目录 一、表查询数据准备及测试环境搭建模型层前期准备测试环境搭建代码演示 二、ORM操作相关方法三、ORM常见的查询关键字四、ORM底层SQL语句五、双下划线查询数据查询#xff08;双下划线#xff09;双下划线小训练Django ORM __双下划线细解 六、ORM外键字段创建基础表… 文章目录 一、表查询数据准备及测试环境搭建模型层前期准备测试环境搭建代码演示 二、ORM操作相关方法三、ORM常见的查询关键字四、ORM底层SQL语句五、双下划线查询数据查询双下划线双下划线小训练Django ORM __双下划线细解 六、ORM外键字段创建基础表的准备模型表创建一对一、一对多和多对多的实例多对多三种创建方法的补充 七、外键字段的相关操作八、正反向概念九、ORM跨表查询基于对象的跨表查询子查询基于双下划线的跨表查询联表查询聚合查询分组查询F与Q查询 一、表查询数据准备及测试环境搭建 模型层前期准备 使用django ORM要注意 django自带的sqlite3数据可对时间字段不敏感有时候会展示错乱所以我们习惯切换成常见的数据库比如MySQL。 django ORM并不会自动帮我们创建库所以需要提前准备好’‘数据库’’ id字段是自动添加的如果想自定义主键只需要在其中一个字段指定primary_key True,如果Django发现你已经明确地设置了Field.primary_key它将不会添加自动ID列。 Django支持MySQL5.5及更高版本。 测试环境搭建 我们需要新建一个Django项目为了便于我们更加方便操作模型层有两种方式可以直接调用到模型层。 方式一在Django自带的测试环境 pycharm提供的python console临时保存不推荐使用 方式二在项目内的任意py文件内推荐在应用下面的一个tests.py文件进行 import osif __name__ __main__:# 注意mysite.settings修改成自己的项目名.settingsos.environ.setdefault(DJANGO_SETTINGS_MODULE, Ku.settings)import djangodjango.setup() # 以独立的方式运行Django程序# 以下编辑我们需要的代码代码演示 测试test.py import osif __name__ __main__:# 注意mysite.settings修改成自己的项目名.settingsos.environ.setdefault(DJANGO_SETTINGS_MODULE, Ku.settings)import djangodjango.setup() # 以独立的方式运行Django程序from app import modelsmodels.UserInfo.objects.all()models.py class UserInfo(models.Model):uid models.AutoField(primary_keyTrue)name models.CharField(max_length32,verbose_name用户名)age models.IntegerField(verbose_name年龄)register_time models.DateTimeField(verbose_name注册事件,auto_now_addTrue)DateField : 年月日DateTimeField : 年月日 时分秒两个重要参数auto_now : 每次操作数据的时候 该字段会自动将当前时间更新 auto_now_add : 在创建数据的时候会自动将当前创建时间记录下来 之后只要不人为的修改 那么就一直不变 def __str__(self):return self.name切换MySQL数据库 1.提前终端创建好库list_user2.将DATABASES的配置更改DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: list_user,USER:root,#PASSWORD:, 因为我的mysql用户没有设置密码所以这里就不需要写了HOST:127.0.0.1,PORT:3306,CHARSET:utf8}}3.连接MySQL库4.python38 manage.py makemigrations5.python38 manage.py migrate如何查看django ORM 底层原理 django ORM本质还是SQL语句。 1.如果有QuerySet对象那么可以直接点query查看SQL语句 res models.UserInfo.objects.filter(namejack)print(res)print(res.query)#SELECT app_userinfo.uid, app_userinfo.name, app_userinfo.age, app_userinfo.register_time FROM app_userinfo WHERE app_userinfo.name jack结论有些不是QuerySet对象就不能通过点query的形式点出来就只能使用通过的方法 2.如果想查看所有ORM底层的SQL语句也可以直接在配置文件添加日志记录 res1 models.User.objects.create(namejack,age18) print(res.query) # 会报错settings最后拷贝代码放在settingsLOGGING {version: 1,disable_existing_loggers: False,handlers: {console:{level:DEBUG,class:logging.StreamHandler,},},loggers: {django.db.backends: {handlers: [console],propagate: True,level:DEBUG,},} }二、ORM操作相关方法 模型层之ORM常见关键字 基础的增删改查 方法返回值create(字段名数据)刚创建的数据记录对象filter(筛选条件)QuerySet列表对象filter().update(修改内容)受影响的行数filter().delete()受影响的行数即各表受影响的行数 三、ORM常见的查询关键字 1.当需要查询数据主键字段值的时候 可以使用pk忽略掉数据字段真正的名字2.在模型类中可以定义一个__str__方法 便于后续数据对象被打印展示的是查看方便3.Queryset中如果是列表套对象那么直接for循环和索引取值但是索引不支持负数4.虽然queryset支持索引但是当queryset没有数据的时候索引会报错 推荐使用first1.create 创建数据并直接获取当前创建的数据对象 res models.UserInfo.objects.create(namejack,age18)print(res)res1 models.UserInfo.objects.create(nametom,age19)print(res1)res2 models.UserInfo.objects.create(nameoscar,age20)print(res2)res3 models.UserInfo.objects.create(nameankn,age22)print(res3)2.filter() 根据条件筛选数据 结果是QuerySet [数据对象1,数据对象2] res4 models.UserInfo.objects.filter() res5 models.UserInfo.objects.filter(namejack) res6 models.UserInfo.objects.filter(nametom,age19) print(res4) #QuerySet [UserInfo: jack, UserInfo: tom, UserInfo: oscar, UserInfo: ankn]print(res5) #QuerySet [UserInfo: jack]print(res6) #QuerySet [UserInfo: tom]3.first()/last() QuerySet支持索引取值但是只支持正数 并且orm不建议你使用索引 res7 models.UserInfo.objects.filter()[1] res10 models.UserInfo.objects.filter(uid100)[0] # 数据不存在索引取值会报错res8 models.UserInfo.objects.filter(uid100).filter() # 数据不存在不会报错而是返回Noneres9 models.UserInfo.objects.filter(uid99).last() # 数据不存在不会报错而是返回Noneprint(res7) # tomprint(res8) # Noneprint(res9) # None4.update() 更新数据(批量更新) models.UserInfo.objects.filter().update() # 批量更新models.UserInfo.objects.filter(uid4).update(9) # 单个删除5.delete() 删除数据(批量删除) models.UserInfo.objects.filter().delete() # 批量删除models.UserInfo.objects.filter(id1).delete() # 单个删除6.all() 查询所有数据 结果是QuerySet [数据对象1,数据对象2] res models.UserInfo.objects.all()print(res)#QuerySet [UserInfo: jack, UserInfo: tom, UserInfo: oscar, UserInfo: ankn]7.values() 根据指定字段获取数据 结果是QuerySet [{}},{},{},{}] res models.UserInfo.objects.all().values(name)print(res)#QuerySet [{name: jack}, {name: tom}, {name: oscar}, {name: ankn}]res1 models.UserInfo.objects.filter().values()print(res1)# QuerySet [{uid: 1, name: jack, age: 18, register_time: datetime.datetime(2023......res2 models.UserInfo.objects.values()print(res2)# QuerySet [{uid: 1, name: jack, age: 18, register_time: datetime.datetime(2023......8.values_list() 根据指定字段获取数据 结果是QuerySet [(),(),(),()] res models.UserInfo.objects.all().values_list(name,age)print(res) #QuerySet [(jack, 18), (tom, 19), (oscar, 20), (ankn, 22)]9.distinct() 去重 数据一定要一模一样才可以 如果有主键肯定不行 res models.UserInfo.objects.values(name,age).distinct()print(res)10.order_by() 根据指定条件排序 默认是升序 字段前面加负号就是降序 res models.UserInfo.objects.all().order_by(age)print(res)# QuerySet [UserInfo: jack, UserInfo: tom, UserInfo: oscar, UserInfo: ankn]11.get() 根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用 res models.UserInfo.objects.get(uid1)print(res) # jackres models.UserInfo.objects.get(uid100)print(res) # 报错12.exclude() 取反操作 res models.UserInfo.objects.exclude(uid2)print(res) # QuerySet [UserInfo: jack, UserInfo: oscar, UserInfo: ankn]13.reverse() 颠倒顺序(被操作的对象必须是已经排过序的才可以) res models.UserInfo.objects.all().order_by(age) # 升序res1 models.UserInfo.objects.all().order_by(age).reverse() # 返回升序之前print(res,res1)# QuerySet [UserInfo: jack, UserInfo: tom, UserInfo: oscar, UserInfo: ankn]# QuerySet [UserInfo: ankn, UserInfo: oscar, UserInfo: tom, UserInfo: jack]14.count() 统计结果集中数据的个数 res models.UserInfo.objects.all().count()print(res) # 415.exists() 判断结果集中是否含有数据 如果有则返回True 没有则返回False res models.UserInfo.objects.all().exists() # 报错res1 models.UserInfo.objects.filter(uid100).exists()print(res1) # False基础方法总结 1、返回QuerySet对象的方法有大多通过模型类.objects.方法调用 QuerySet对象形似存储了一个个记录对象的列表但拥有一些特殊的属性如query。 名称语法说明filterres1 models.User.objects.filter(name‘Like’, age20)筛选数据 返回值是一个QuerySet(可以看成是列表套数据对象)括号内不写查询条件 默认就是查询所有括号内可以填写条件 并且支持多个 逗号隔开 默认是and关系allres2 models.User.objects.all()查询所有数据 返回值是一个QuerySet(可以看成是列表套数据对象)firstres3 models.User.objects.first()获取Queryset中第一个数据对象 如果为空则返回Nonelastres4 models.User.objects.last()获取Queryset中最后一个数据对象 如果为空则返回Nonegetres5 models.User.objects.get(pk2)直接根据条件查询具体的数据对象 但是条件不存在直接报错 不推荐使用valuesres6 models.User.objects.values(‘name’, ‘age’)指定查询字段 结果是Queryset(可以看成是列表套字典数据)values_listres7 models.User.objects.values_list()指定全部字段 结果是Queryset(可以看成是列表套元组数据)order_byres8 models.User.objects.order_by(‘age’) 升序,res8_1 models.User.objects.order_by(‘-age’, ‘name’)降序指定字段排序 默认是升序 在字段前加负号则为降序 并且支持多个字段排序countres9 models.User.objects.count()统计orm查询之后结果集中的数据格式distinctres10 models.User.objects.values(‘name’, ‘age’).distinct()针对重复的数据集进行去重 一定要注意数据对象中的主键excluderes11 models.User.objects.exclude()针对括号内的条件取反进行数据查询 QuerySet(可以看成是列表套数据对象)reverseres12 models.User.objects.all().order_by(‘age’).reverse()针对已经排了序的结果集做颠倒existsres13 models.User.objects.exists()判断查询结果集是否有数据 返回布尔值 但是几乎不用因为所有数据自带布尔值rawres14 models.User.objects.raw(‘select * from app01_user’)执行SQL语句 四、ORM底层SQL语句 我们现在知道了怎么查询数据了但是它的底层语句逻辑是什么呢方式1:如果是Queryset对象 那么可以直接点Ctrl左键点击query查看SQL语句方式2:需要到配置文件Settings中找一个空白位置复制一下代码 主要作用打印所有ORM操作对应的SQL语句LOGGING {version: 1,disable_existing_loggers: False,handlers: {console:{level:DEBUG,class:logging.StreamHandler,},},loggers: {django.db.backends: {handlers: [console],propagate: True,level:DEBUG,},}}五、双下划线查询 结果对象还是query对象就可以无限制的点queryset对象的方法。 queryset.filter().values().filter().values_list().filter()....django中将字段后加上__条件的方式让关键字参数拥有除等号外的其他含义。 数据查询双下划线 __gt大于__lt小于__gte大于等于__lte小于等于__in类似于成员运算在…里面__range在什么范围之内__contains是否含有区分大小写 模糊查询__icontains是否含有不区分大小写 模糊查询__year查询年份__day查询日期天数__second/minute查看秒/分 双下划线小训练 数据表提前准备好 1.查询年龄大于18的用户数据 sql语句# select * form userinfo where age18;res models.UserInfo.objects.filter(age__gt18)print(res)# QuerySet [UserInfo: tom1, UserInfo: oscar, UserInfo: ankn, UserInfo: jason]2.查询年龄小于38的用户数据 sql语句# select * form userinfo where age38;res models.UserInfo.objects.filter(age__lt38)print(res)# QuerySet [UserInfo: jack, UserInfo: tom1, UserInfo: oscar, UserInfo: ankn]3.查询年龄大于等于38的用户数据 sql语句# select * form userinfo where age38;res models.UserInfo.objects.filter(age__gte38)print(res)# QuerySet [UserInfo: jason]4.查询年龄小于等于38的用户数据 sql语句# select * form userinfo where age38;res models.UserInfo.objects.filter(age__lte38)print(res)# QuerySet [UserInfo: jack, UserInfo: tom1, UserInfo: oscar, UserInfo: ankn]5.查询年龄是18或者20或者38的数据 sql语句# select * form userinfo where age18 or age20 or age38;res models.UserInfo.objects.filter(age__in[18,20,38])print(res)# QuerySet [UserInfo: jack, UserInfo: oscar]6.查询年龄在18到38范围之间的用户数据 sql语句# select * form userinfo where age18 and age38;res models.UserInfo.objects.filter(age__range[18,38])print(res)# QuerySet [UserInfo: jack, UserInfo: tom1, UserInfo: oscar, UserInfo: ankn]7.查询名字中含有字母j的用户数据 sql语句# select * form userinfo where name like %j%;1.区分大小写res models.UserInfo.objects.filter(name__containsj)print(res)# QuerySet [UserInfo: jack, UserInfo: jason]2.不区分大小写res models.UserInfo.objects.filter(name__icontainsj)8.查询注册年份是2022的数据 res models.UserInfo.objects.filter(register_time__year2022)print(res)# QuerySet [UserInfo: tom1, UserInfo: ankn]Django ORM __双下划线细解 exact精确匹配例如 Book.objects.filter(title__exactDjango) 将返回所有标题为 Django 的书籍。 iexact不区分大小写的精确匹配例如 Book.objects.filter(title__iexactdjango) 将返回所有标题为 django 或 Django 的书籍。 contains包含匹配例如 Book.objects.filter(title__containsDjango) 将返回所有标题中包含 Django 的书籍。 icontains不区分大小写的包含匹配例如 Book.objects.filter(title__icontainsdjango) 将返回所有标题中包含 django 或 Django 的书籍。 in范围匹配例如 Book.objects.filter(id__in[1, 2, 3]) 将返回 ID 为 1、2 或 3 的书籍。 gt大于匹配例如 Book.objects.filter(price__gt10) 将返回价格大于 10 的书籍。 lt小于匹配例如 Book.objects.filter(price__lt10) 将返回价格小于 10 的书籍。 gte大于等于匹配例如 Book.objects.filter(price__gte10) 将返回价格大于等于 10 的书籍。 lte小于等于匹配例如 Book.objects.filter(price__lte10) 将返回价格小于等于 10 的书籍。 startswith以指定字符串开头匹配例如 Book.objects.filter(title__startswithDjango) 将返回标题以 Django 开头的书籍。 istartswith不区分大小写的以指定字符串开头匹配例如 Book.objects.filter(title__istartswithdjango) 将返回标题以 django 或 Django 开头的书籍。 endswith以指定字符串结尾匹配例如 Book.objects.filter(title__endswithDjango) 将返回标题以 Django 结尾的书籍。 iendswith不区分大小写的以指定字符串结尾匹配例如 Book.objects.filter(title__iendswithdjango) 将返回标题以 django 或 Django 结尾的书籍。 range范围匹配例如 Book.objects.filter(price__range[10, 20]) 将返回价格在 10 到 20 之间的书籍。 date日期匹配例如 Book.objects.filter(publish_date__datedate(2021, 8, 1)) 将返回发行日期为 2021 年 8 月 1 日的书籍。 year年份匹配例如 Book.objects.filter(publish_date__year2021) 将返回发行日期为 2021 年的书籍。 month月份匹配例如 Book.objects.filter(publish_date__month8) 将返回发行日期为 8 月的书籍。 day日期匹配例如 Book.objects.filter(publish_date__day1) 将返回发行日期为 1 日的书籍。 hour小时匹配例如 Book.objects.filter(publish_time__hour10) 将返回发布时间为上午 10 点的书籍。 minute分钟匹配例如 Book.objects.filter(publish_time__minute30) 将返回发布时间为 30 分钟的书籍。 second秒匹配例如 Book.objects.filter(publish_time__second0) 将返回发布时间为整点的书籍。 isnull为空匹配例如 Book.objects.filter(author__isnullTrue) 将返回没有作者的书籍。六、ORM外键字段创建 跟MySQL外键关系一样的判断规律 1.一对多 外键字段建立在多的一方2.多对多 外键字段建立在第三张表中3.一对一 建立在任何一方都可以但是建议建立在操作频率高的一张表中注意目前关系的判断可以采用表与表之间换位思考原则基础表的准备 创建基础表书籍表、出版社表、作者表、作者详情表确定外键关系 一对一 ORM与MySQL一致外键字段建立在查询频率较高的一方一对多 ORM与MySQL一致外键建立在多的一方多对多 ORM比MySQL有更多的变化1.外键字段可以之间建在某张表中查询频率较高的内部会自动帮你创建第三张关系表2.自己创建的三张关系表并创建外键字段后续讲解ORM创建 针对一对多和一对一同步到表中之后自动 _id的后缀如book中建立的外键字段名publish会自动变成publish_id。 1.一对多关系publish models.ForeignKey(toPublish,on_deletemodels.CASCADE) 在多的表中建立外键字段会在表中产生一个实际的字段自动加_id后缀2.一对一author_detail models.OneToOneField(toAuthorDetail,on_deletemodels.CASCADE)在查询频率较高的表中建立外键字段会在表中产生一个实际的字段自动加_id后缀django1.x 针对外键的创建后的同步是无需级联更新级联删除的on_delete models.CASCADEdjango2.x 3.x则需要添加on_delete参数针对多对多不会在表中有展示而是自动创建第三张表 1.多对多authors models.ManyToManyField(toAuthor)在查询频率较高的表中建立外键字段ORM自动创建的也可自己创建不会在表中产生实际的字段而是告诉ORM创建第三张关系表。模型表创建一对一、一对多和多对多的实例 需要注意的事项 1.创建一对多关系 和sql语句一样外键建立到多的那张表上不同的是我们可以不讲究关联表和被关联表的建立顺序。字段类为ForeignKey在django2.x版本以上建立一对多关系时需要指定on_delete参数为CASCADE不加会报错不过也不一定就是CASCADE可能为其他实参这里不展开。建立外键时系统会自动加上_id后缀作为字段名。2.创建多对多关系 sql中是将两张表建立好后将外键字段创建在第三张表中而django为我们省去了这一步骤我们可以在多对多关系双方的一个模型表中直接建立一个虚拟外键ManyToManyField在底层sql依旧创建了第三张表来存储两表的多对多关系但是在orm操作中我们就可以将模型表中的外键当做实实在在的联系因为在查询时我们感受不到第三张的表的存在。多对多关系的外键没有on_delete关键字参数。3.创建一对多关系 一对一的字段类为OneToOneField,建议建立在查询频率高的一方。建立一对一关系时需要指定on_delete参数否则报错。多对多三种创建方法的补充 注意多对多关系这种虚拟外键才有add、set、clear、remove一对一和一对多的表是无法使用这些方法 1.全自动创建 class Book(models.Model):title models.CharField(max_length32)authorsmodels.ManyToManyField(toAuthor)class Author(models.Model):name models.CharField(max_length32)优势自动创建第三张表并且提供了add、remove、set、clear四种操作 劣势第三张表无法创建更多的字段扩展性较差。如果我们有一些业务逻辑就是在关系表上我们就无法通过第三张表完成了。 2.纯手动创建 class Book(models.Model):title models.CharField(max_length32)class Author(models.Model):name models.CharField(max_length32)class Book2Author(models.Model):bookmodels.ForeignKey(toBook)author models.ForeigKey(toAuthor)othersmodels.CharField(max_length32)join_time models.DataField(auto_now_addTrue)优势第三张表完全由自己创建扩展性强 劣势编写繁琐并不支持add、remove、set、clear以及正反向概念。 3.半自动创建 class Book(models.Model):title models.CharField(max_length32)authors models.ManyToManyField(toAuthor,throughBook2Author,through_fields(book,author)# 外键在哪个表就把book表放前面)class Author(models.Model):name models.CharField(max_length32)class Book2Author(models.Model):book models.ForeignKey(toBook, on_deletemodels.CASCADE)author models.ForeignKey(toAuthor, on_deletemodels.CASCADE)others models.CharField(max_length32)join_time models.DateField(auto_now_addTrue)优势第三张表完全由自己创建扩展性强正反向概念依然可以使用 劣势编写繁琐并不支持add、remove、set、clear。 七、外键字段的相关操作 数据的创建 基本数据提前将Publish,author以及authordetail三个表的数据信息录入Book以及关系的绑定在下面详细介绍 一对多和一对一实际外键字段的绑定 1.外键关联的实际字段 针对一对多插入数据可以直接填写表中的实际字段 先创建未存储外键字段的表数据# models.Publish.objects.create(name星海出版社,address澳门)# models.Publish.objects.create(name上海出版社,address上海)# models.Publish.objects.create(name北京出版社,address北京)models.Book.objects.create(titlePython从入门到放弃,price233.1,publish_id1)models.Book.objects.create(titlePython爬虫从入门到入狱,price666.6,publish_id1)models.Book.objects.create(titleMySQL从入门到删库跑路,price555.5,publish_id2)models.Book.objects.create(title论如何开启重启人生,price999.9,publish_id3)2.外键的关联对象 针对一对多插入数据也可以填写表中的类中字段名 publish_obj models.Publish.objects.filter(pk3).first()print(publish_obj)models.Book.objects.create(title老人与海,price111.1,publish_idpublish_obj.id)3.一对一与一对多插入数据的方式是一致的 关于多对多关系外键字段的绑定 多对多外键属于实际不在模型表中的虚拟字段多对多关系则需要django提供给我们的方法来实现增删改关系。拿到设立多对多外键的模型表的对象用它点出外键属性可以进行add、set、remove方法这些方法都是这条记录对象的操作。 数据的增加add 语法book_obj.authors.add() # 对象.外键.add()add可以通过关联的id或者关联的对象进行绑定关系book_obj models.Book.objects.filter(pk3).first()1.书与作者一对一绑定book_obj.authors.add(1) # 在第三张关系表中给当前书籍绑定作者2.书与作者一对多绑定book_obj.authors.add(2,3)3.作者对象与书对象的绑定book_obj models.Book.objects.filter(pk4).first()author_obj1 models.Author.objects.filter(pk2).first()author_obj2 models.Author.objects.filter(pk3).first()# book_obj.authors.add(author_obj1) # 可以添加一个作者对象book_obj.authors.add(author_obj1,author_obj2) # 也可同时添加两个作者对象总结add(1) add(1,2) add(obj1) add(obj1,obj2)数据的修改set 语法book_obj.authors.set() # 对象.外键.set()set可以通过关联的id或者关联的对象进行修改绑定关系4.绑定错误如何修改使用set修改关系 通过id修改的book_obj models.Book.objects.filter(pk4).first()book_obj.authors.set((1,3)) # set括号里面只能填写一个可跌倒对象()/[]或者对象 原本id4的书籍绑定的是作者2和作者3通过set修改数据信息后绑定的是作者1和作者3book_obj.authors.set([2,4])通过对象修改的book_obj models.Book.objects.filter(pk2).first()book_obj.authors.add(1,2,4) id2的书绑定了作者1,作者2和作者4book_obj models.Book.objects.filter(pk2).first()author_obj1models.Author.objects.filter(pk1).first()author_obj2models.Author.objects.filter(pk2).first()author_obj4models.Author.objects.filter(pk4).first()book_obj.authors.set((author_obj1,author_obj2)) id2的书由绑定的作者1作者2和作者4修改为作者1和作者4book_obj.authors.set((author_obj1,author_obj2,author_obj4)) 通过修改id2的书还是绑定了作者1,作者2和作者4总结set((1,)) set((1,2)) set((obj1,)) set((obj1,obj2))数据的删除remove 语法book_obj.authors.remove() # 对象.外键.remove()remove可以通过关联的id或者关联的对象进行移除绑定关系5.数据的删除book_obj models.Book.objects.filter(pk1).first()author_obj1 models.Author.objects.filter(pk1).first()author_obj2 models.Author.objects.filter(pk2).first() 通过id去删除book_obj.authors.remove(2) # 作者2#book_obj.authors.remove(1,3) 通过作者对象去删除book_obj.authors.remove(author_obj1) # 作者1#book_obj.authors.remove(author_obj1,author_obj2)总结remove(1) remove(1,2) remove(obj1) remove(obj1,obj2)add()\remove() 多个位置参数(数字 对象)set() 可迭代对象(元组 列表) 数字 对象 clear() 情况当前数据对象的关系 不需要传参数数据的清空 clear 语法book_obj.authors.clear() # 对象.外键.clear()clear() 直接清空与book的id为1关联的所有作者 清空主键为1的绑定关系book_obj models.Book.objects.filter(pk1).first()book_obj.authors.clear() 八、正反向概念 正反向的概念核心就在于外键字段在谁手上外键在自己手上则是正向查询外键在别人手上则是反向查询正向查询通过书查询出版社 外键字段在书表中反向查询通过出版社查询书 外键字段不在出版社表中ORM跨表查询口诀:正向查询按外键字段 反向查询按表名小写九、ORM跨表查询 MySQL跨表查询的思路 1.子查询分步操作:将一条SQL语句用括号括起来当做另外一条SQL语句的条件2.连表操作先整合多张表之后基于单表查询即可inner join 内连接left join 左连接right join 右连接基于对象的跨表查询子查询 数据准备 步骤 先根据条件获取数据对象判断正反向查询正向查询按外键反向查询按表名小写 1.查询书籍主键为3的出版社# 书查询出版社表 正向 按照外键字段book_obj models.Book.objects.filter(pk3).first()print(book_obj.publish.name)print(book_obj.publish.address)2.查询书籍主键为2的作者# 书查询作者 正向 按照外键字段res models.Book.objects.filter(pk5).first()print(res.title)print(res.authors)print(res.authors.all())3.查询作者李四的电话号码# 作者查询作者详情 正向 按照外键字段res models.Author.objects.filter(name李四).first()print(res.author_detail.phone)在书写orm语句的时候跟写sql语句一样的不要企图一次性将orm语句写完 如果比较复杂 就写一点看一点正向什么时候需要加.all()当你的结果可能有多个的时候就需要加.all()如果是一个则直接拿到数据对象book_obj.publishbook_obj.authors.all()author_obj.author_detail4.查询出版社是上海出版社出版的书# 出版社查询书 反向 表名小写res models.Publish.objects.filter(name上海出版社).values(book__title)print(res)5.查询作者是王五写过的书# 作者查询书 反向 按照表名小写res models.Author.objects.filter(name王五).values(book__title)print(res)6.查询手机号是110的作者姓名# 作者详情表查询作者 反向 按照表名小写res models.AuthorDetail.objects.filter(phone110).select_related(author)for i in res:print(i.author.name)基于对象 反向查询的时候当你的查询结果可以有多个的时候 就必须加_set.all()当你的结果只有一个的时候 不需要加_set.all()自己总结出 自己方便记忆的即可 每个人都可以不一样基于双下划线的跨表查询联表查询 1.查询李四的手机号和作者姓名res models.Author.objects.filter(name李四).values(author_detail__phone,name)print(res)反向查询res models.AuthorDetail.objects.filter(author__name李四).values(phone,author__name)print(res)2.查询书籍主键为4的出版社名称和书的名称# 书查询出版社 正向 外键字段res models.Book.objects.filter(pk4).values(publish__name,title)print(res)反向查询res models.Publish.objects.filter(book__pk4).values(book__title,name)print(res)3.查询书籍主键为3的作者姓名# 书查作者 正向 外键字段res models.Book.objects.filter(pk3).values(authors__name)print(res)反向查询res models.Author.objects.filter(book__id 3).values(name)print(res)查询书籍主键是5的作者的手机号res models.Book.objects.filter(pk5).values(authors__author_detail__phone)print(res)反向查询res models.Author.objects.filter(book__id5).values(author_detail__phone)print(res)你只要掌握了正反向的概念以及双下划线那么你就可以无限制的跨表聚合查询 函数名描述Max大于Min小于Sum求和Count统计某个数据Avg平均值 聚合查询通常情况下都是配合分组一起使用的只要是跟数据库相关的模块 基本上都在django.db.models里面如果上述没有那么应该在django.db里面如果我们在ORM中使用聚合函数ORM支持单独使用聚合函数步骤如下from django.db.models import Max,Min,Sum,Count,Avg使用关键字aggregate1 所有书的平均价格res models.Book.objects.aggregate(Avg(price))print(res)2.上述方法一次性使用res models.Book.objects.aggregate(Avg(price),Sum(price),Min(price),Max(price),Count(pk))print(res)分组查询 如果执行ORM分组查询报错并且又关键sql_mode / strict mode ,那么就去移除sql_mode中的only_full_group_by 1.统计每一本书的作者个数res models.Book.objects.annotate(num_authorCount(authors)).values(title,num_author)author_num是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数print(res)2.统计每个出版社卖的最便宜的书的价格res models.Publish.objects.annotate(min_priceMin(book__price)).values(name,min_price)print(res)3.统计不止一个作者的图书resmodels.Book.objects.annotate(author_numCount(authors)).filter(author_num__gt1).values(title,author_num)print(res)4.查询每个作者出的书的总价格res models.Author.objects.annotate(book_priceSum(book__price)).values(name,book_price)print(res)上述分组都是按照表来分组我们也可以按照表中的字段名来分组 1.按照表分组models.表名.objects.annotate()2.按照表中字段名来分组models.表名.objects.values(字段名).annotate()eg:res models.Book.objects.values(publish_id).annotate(count_pkCount(pk)).values(publish_id,count_pk)print(res)注意values在annotate前就是按照values()括号里面字段名来分组values()在annotate后就是按照前面的表名分组values就是拿值的F与Q查询 F查询 当查询条件不是很明确的也需要从数据库中获取就需要使用F查询。 简单理解 两个字段进行比较的筛选条件库存数大于卖出数在原来的数值字段增加数值500在原来的字段名后面加字爆款 在上述条件等我们只借助ORM操作是实现不了的我们需要在ORM中就需要借助F方法。 from django.db.models import F 导入模块1.查询卖出数大于库存数的书籍res models.Book.objects.filter(maichu__gtF(kucun)).values(title)print(res)2.将所有书籍的价格提升500块models.Book.objects.update(priceF(price)500)在操作字符类型的数据的时候 F不能够直接做到字符串的拼接3.将所有书的名称后面加上爆款两个字from django.db.models.functions import Concatfrom django.db.models import Value# models.Book.objects.update(titleF(title)爆款) # 使用F会让所有的名称变为空白models.Book.objects.update(titleConcat(Ftitle,Value(爆款)))Q查询 在ORM操作中筛选条件中存在或、非的关系需要借助Q方法来实现。 符号描述逗号and的关系|or的关系~not的关系 from django.db.models import Q1.查询卖出数大于1000或者价格小于800的书籍res models.Book.objects.filter(Q(maichu__gt1000),Q(price__lt800)).values(title)Q包裹逗号分割 还是and关系res models.Book.objects.filter(Q(maichu__gt1000)|Q(price__lt800)).values(title)| or关系res models.Book.objects.filter(~(Q(maichu__gt1000)|Q(price__lt800))).values(title)~ not关系# print(res)Q方法使用总结 两个条件是或关系Q(条件1) | Q(条件2)两个条件是非关系~Q(条件) Q查询的进阶操作 from django.db.models import QQ的高阶用法 能够将查询条件的左边也变成字符串的形式q Q() 产生一个Q对象q.connectoror 默认是多个条件的连接时and修改成orq.children.append((maichu__gt,1000)) 添加查询条件q.children.append(price__lt,800) 支持添加多个res models.Book.objects.filter(q) 查询文件直接填写Q对象print(res)
文章转载自:
http://www.morning.rxnl.cn.gov.cn.rxnl.cn
http://www.morning.mcjrf.cn.gov.cn.mcjrf.cn
http://www.morning.qnrpj.cn.gov.cn.qnrpj.cn
http://www.morning.sgbk.cn.gov.cn.sgbk.cn
http://www.morning.mbmtn.cn.gov.cn.mbmtn.cn
http://www.morning.qpsft.cn.gov.cn.qpsft.cn
http://www.morning.nmymn.cn.gov.cn.nmymn.cn
http://www.morning.bwttj.cn.gov.cn.bwttj.cn
http://www.morning.xqcbz.cn.gov.cn.xqcbz.cn
http://www.morning.djpgc.cn.gov.cn.djpgc.cn
http://www.morning.ksbmx.cn.gov.cn.ksbmx.cn
http://www.morning.wqpb.cn.gov.cn.wqpb.cn
http://www.morning.wrkcw.cn.gov.cn.wrkcw.cn
http://www.morning.xxwhz.cn.gov.cn.xxwhz.cn
http://www.morning.rbffj.cn.gov.cn.rbffj.cn
http://www.morning.mnwmj.cn.gov.cn.mnwmj.cn
http://www.morning.qttg.cn.gov.cn.qttg.cn
http://www.morning.npqps.cn.gov.cn.npqps.cn
http://www.morning.hqsnt.cn.gov.cn.hqsnt.cn
http://www.morning.xsfg.cn.gov.cn.xsfg.cn
http://www.morning.hyfrd.cn.gov.cn.hyfrd.cn
http://www.morning.dnydy.cn.gov.cn.dnydy.cn
http://www.morning.fkcjs.cn.gov.cn.fkcjs.cn
http://www.morning.mzwqt.cn.gov.cn.mzwqt.cn
http://www.morning.ycnqk.cn.gov.cn.ycnqk.cn
http://www.morning.grnhb.cn.gov.cn.grnhb.cn
http://www.morning.ykmg.cn.gov.cn.ykmg.cn
http://www.morning.ggnkt.cn.gov.cn.ggnkt.cn
http://www.morning.hwnnm.cn.gov.cn.hwnnm.cn
http://www.morning.tbrnl.cn.gov.cn.tbrnl.cn
http://www.morning.xqgh.cn.gov.cn.xqgh.cn
http://www.morning.xqnzn.cn.gov.cn.xqnzn.cn
http://www.morning.tnhg.cn.gov.cn.tnhg.cn
http://www.morning.fbccx.cn.gov.cn.fbccx.cn
http://www.morning.lfpzs.cn.gov.cn.lfpzs.cn
http://www.morning.nlysd.cn.gov.cn.nlysd.cn
http://www.morning.rbjth.cn.gov.cn.rbjth.cn
http://www.morning.zzqgc.cn.gov.cn.zzqgc.cn
http://www.morning.glxdk.cn.gov.cn.glxdk.cn
http://www.morning.sbczr.cn.gov.cn.sbczr.cn
http://www.morning.mjkqj.cn.gov.cn.mjkqj.cn
http://www.morning.tfkqc.cn.gov.cn.tfkqc.cn
http://www.morning.qydgk.cn.gov.cn.qydgk.cn
http://www.morning.ryxyz.cn.gov.cn.ryxyz.cn
http://www.morning.fdwlg.cn.gov.cn.fdwlg.cn
http://www.morning.gpnfg.cn.gov.cn.gpnfg.cn
http://www.morning.wqnc.cn.gov.cn.wqnc.cn
http://www.morning.dfhkh.cn.gov.cn.dfhkh.cn
http://www.morning.dyxlm.cn.gov.cn.dyxlm.cn
http://www.morning.jjhng.cn.gov.cn.jjhng.cn
http://www.morning.qnsmk.cn.gov.cn.qnsmk.cn
http://www.morning.nbmyg.cn.gov.cn.nbmyg.cn
http://www.morning.zypnt.cn.gov.cn.zypnt.cn
http://www.morning.bauul.com.gov.cn.bauul.com
http://www.morning.cmldr.cn.gov.cn.cmldr.cn
http://www.morning.mbmtn.cn.gov.cn.mbmtn.cn
http://www.morning.tpchy.cn.gov.cn.tpchy.cn
http://www.morning.wqcbr.cn.gov.cn.wqcbr.cn
http://www.morning.hytr.cn.gov.cn.hytr.cn
http://www.morning.yhywr.cn.gov.cn.yhywr.cn
http://www.morning.tbqdm.cn.gov.cn.tbqdm.cn
http://www.morning.xfwnk.cn.gov.cn.xfwnk.cn
http://www.morning.kfysh.com.gov.cn.kfysh.com
http://www.morning.wfyzs.cn.gov.cn.wfyzs.cn
http://www.morning.jfbgn.cn.gov.cn.jfbgn.cn
http://www.morning.znpyw.cn.gov.cn.znpyw.cn
http://www.morning.dtnjr.cn.gov.cn.dtnjr.cn
http://www.morning.gxcym.cn.gov.cn.gxcym.cn
http://www.morning.ynwdk.cn.gov.cn.ynwdk.cn
http://www.morning.sqnrz.cn.gov.cn.sqnrz.cn
http://www.morning.krnzm.cn.gov.cn.krnzm.cn
http://www.morning.qbdsx.cn.gov.cn.qbdsx.cn
http://www.morning.mlfmj.cn.gov.cn.mlfmj.cn
http://www.morning.tyklz.cn.gov.cn.tyklz.cn
http://www.morning.lxlzm.cn.gov.cn.lxlzm.cn
http://www.morning.fylsz.cn.gov.cn.fylsz.cn
http://www.morning.fwdln.cn.gov.cn.fwdln.cn
http://www.morning.smpmn.cn.gov.cn.smpmn.cn
http://www.morning.cpkcq.cn.gov.cn.cpkcq.cn
http://www.morning.dwmmf.cn.gov.cn.dwmmf.cn
http://www.tj-hxxt.cn/news/260638.html

相关文章:

  • 常州低价网站建设公司做推广网站需要商标吗
  • 动易网站开发的主要技术企业网站模板 免费
  • wordpress企业网站cms下载wordpress建站程序
  • 网站备案是一年一次吗网站代理加盟
  • 做dhl底单的网站是 什么网站建设案例咨询
  • 优惠网站代理怎么做免费的会员卡管理软件
  • 建立网站有哪些步骤?WordPress网易云外链音
  • 网上购物网站开发开题报告外贸营销信模板
  • 网站建设文章官网萌导航
  • 手机网站 app建设网站50m数据库
  • 做ic芯片的要去哪个网站常用网站设计缩略图
  • 佛山制作做网站苏州新区网站建设
  • 一流的做pc端网站网页关键词优化难度
  • 备案的域名拿来做别的网站优秀网站设计作品
  • 英文企业网站源码 asph5端是手机端吗
  • 电子商务网站建设考题网站做抽奖活动
  • 创建网站的各项费用贵州seo学校
  • 网站开发工程师证书商务网站开发技术
  • wordpress 仿站思路湖南省建筑信息网
  • 好看的网站界面设计泸州网站建设
  • asp.net mvc 网站开发jsp做网站
  • 山西住房和城乡建设部网站天津网站公司
  • 电脑版网站转手机版怎么做华为云和wordpress
  • 企业网站推广方法有哪些做证券考试的网站
  • 萍乡网站开发公司互联网技术岗位校园招聘
  • 阜阳网站是wordpress 注册 填写密码
  • 网站建设发布教程网络查询网站
  • 建设网站那个平台好重庆网上注册公司流程
  • 建设银行官方网站客户资料修改技术支持 郑州做网站
  • 在哪些网站能接到活做网站备案要营业执照吗