电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Django多層嵌套ManyToMany字段ORM操作詳解

瀏覽:5日期:2024-10-04 18:22:36

在用django寫項(xiàng)目時(shí),遇到了許多場(chǎng)景,關(guān)于ORM操作獲取數(shù)據(jù)的,但是不好描述出來,百度搜索關(guān)鍵詞都不知道該怎么搜,導(dǎo)致一個(gè)人鼓搗了好久。這里細(xì)化下問題,還原場(chǎng)景,記錄踩下的坑

首先先列舉model,我舉些生活中的例子,更方便理解問題

# 習(xí)題class Problem(models.Model): desc = models.CharField() answer = models.TextField() is_pass = models.BooleanField(default=False, verbose_name='是否通過')# 章節(jié)class Chapter(models.Model): _id = models.IntegerField(verbose_name='編號(hào)') title = models.CharField() problem = models.ManyToManyField(Problem) pass_rate = models.IntegerField(verbose_name='通關(guān)率')# 書籍 class Book(models.Model): title = models.CharField() desc = models.TextField() chapter = models.ManyToManyField(Chapter,verbose_name='章節(jié)') speed = models.IntegerField(verbose_name='學(xué)習(xí)進(jìn)度', default=0)

假設(shè)是一本數(shù)學(xué)書,有5個(gè)章節(jié),每個(gè)章節(jié)里有數(shù)量不等的習(xí)題,

即book與chapter是多對(duì)多,chapter與problem也是多對(duì)多

場(chǎng)景一: 書籍下的所有習(xí)題

# 按我的理解是取問題非空的章節(jié)數(shù)# 類似于問爺爺有幾個(gè)孫子,沒辦法跨輩,就按一個(gè)孫子對(duì)應(yīng)一個(gè)爸爸來?。ㄓ兄貜?fù))book.chapter.filter(problem___id__isnull=False).count()

場(chǎng)景二:書籍下所有通過的習(xí)題

book.chapter.filter(problem__is_pass=True).count()

場(chǎng)景三: 判斷某個(gè)問題是否在這本書里

def problem_in_ladder(book, problem): for i in book.chapter.all(): if problem in i.problem.all():return True return False

盡可能的減少view中對(duì)models的取值操作,所以把上面幾個(gè)場(chǎng)景方法寫在models類中

最終的models

# 習(xí)題class Problem(models.Model): desc = models.CharField() answer = models.TextField() is_pass = models.BooleanField(default=False, verbose_name='是否通過')# 章節(jié)class Chapter(models.Model): _id = models.IntegerField(verbose_name='編號(hào)') title = models.CharField() problem = models.ManyToManyField(Problem) pass_rate = models.IntegerField(verbose_name='通關(guān)率') @property def items(self): return self.problem.count() @property def pass_problem(self): return self.problem.filter(is_pass=True).count() # 書籍 class Book(models.Model): title = models.CharField() desc = models.TextField() chapter = models.ManyToManyField(Chapter,verbose_name='章節(jié)') speed = models.IntegerField(verbose_name='學(xué)習(xí)進(jìn)度', default=0) @property def chapters(self): return self.chapter.count() @property def pass_count(self): return self.chapter.filter(problem__is_pass=True).count() @property def items(self): return self.chapter.filter(problem___id__isnull=False).count()

補(bǔ)充知識(shí):django中當(dāng)model設(shè)置了ordering后,使用distinct()和annotate()問題記錄

model類如下,我在class Meta中設(shè)置了ordering = [’-date_create’],即模型對(duì)象返回的記錄結(jié)果集是按照這個(gè)字段排序的。

class SystemUserPushHistory(models.Model): id = models.UUIDField(default=uuid.uuid4, primary_key=True) host_name = models.CharField(max_length=128, null=False) system_username = models.CharField(max_length=128, null=False) method = models.CharField(max_length=32, null=False) is_success = models.BooleanField(default=False) date_create = models.DateTimeField(auto_now_add=True, editable=False) message = models.CharField(max_length=4096, null=True) class Meta: db_table = 'assets_systemuser_push_history' ordering = [’-date_create’] def __str__(self): ret = self.system_username + ' => ' + self.host_name return ret

當(dāng)業(yè)務(wù)有需求如對(duì)host_name進(jìn)行分組顯示,在代碼中用到了annotate,如下。

>>> from django.db.models import Count >>> from assets.models import SystemUserPushHistory>>> p = SystemUserPushHistory.objects.values('host_name').annotate(dcount=Count(1))>>> p<QuerySet [{’host_name’: ’點(diǎn)2’, ’dcount’: 1}, {’host_name’: ’點(diǎn)3’, ’dcount’: 2}, {’host_name’: ’點(diǎn)2’, ’dcount’: 1}, {’host_name’: ’點(diǎn)3’, ’dcount’: 1}]>>>> print(p.query)SELECT `assets_systemuser_push_history`.`host_name`, COUNT(1) AS `dcount` FROM `assets_systemuser_push_history` GROUP BY `assets_systemuser_push_history`.`host_name`, `assets_systemuser_push_history`.`date_create` ORDER BY `assets_systemuser_push_history`.`date_create` DESC

可以看到,所得到的結(jié)果并不像我們預(yù)期的一樣,之后把執(zhí)行的sql輸出出來可以看到在group by的時(shí)候是對(duì)host_name和date_create進(jìn)行分組,原因就是因?yàn)槲覀冊(cè)趍odel類中設(shè)置了ordering,去掉之后代碼運(yùn)行正常。

使用distinct和上面的情況類似,就不列出來了。

以上這篇Django多層嵌套ManyToMany字段ORM操作詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Django
相關(guān)文章:
主站蜘蛛池模板: 全自动包装秤_全自动上袋机_全自动套袋机_高位码垛机_全自动包装码垛系统生产线-三维汉界机器(山东)股份有限公司 | 语料库-提供经典范文,文案句子,常用文书,您的写作得力助手 | 电车线(用于供电给电车的输电线路)-百科 | 粘度计,数显粘度计,指针旋转粘度计 | 碳钢法兰厂家,非标法兰,定制异型,法兰生产厂家-河北九瑞管道 | 家用净水器代理批发加盟_净水机招商代理_全屋净水器定制品牌_【劳伦斯官网】 | 长沙印刷厂-包装印刷-画册印刷厂家-湖南省日大彩色印务有限公司 青州搬家公司电话_青州搬家公司哪家好「鸿喜」青州搬家 | 硫化罐-电加热蒸汽硫化罐生产厂家-山东鑫泰鑫智能装备有限公司 | 云南丰泰挖掘机修理厂-挖掘机维修,翻新,再制造的大型企业-云南丰泰工程机械维修有限公司 | 工业插头-工业插头插座【厂家】-温州罗曼电气 | 微信小程序定制,广州app公众号商城网站开发公司-广东锋火 | 多功能真空滤油机_润滑油全自动滤油机_高效真空滤油机价格-重庆润华通驰 | 实验室隔膜泵-无油防腐蚀隔膜泵-耐腐蚀隔膜真空泵-杭州景程仪器 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 动库网动库商城-体育用品专卖店:羽毛球,乒乓球拍,网球,户外装备,运动鞋,运动包,运动服饰专卖店-正品运动品网上商城动库商城网 - 动库商城 | 精密五金加工厂-CNC数控车床加工_冲压件|蜗杆|螺杆加工「新锦泰」 | 油冷式_微型_TDY电动滚筒_外装_外置式电动滚筒厂家-淄博秉泓机械有限公司 | 餐饮小吃技术培训-火锅串串香培训「何小胖培训」_成都点石成金[官网] | 中医治疗皮肤病_潍坊银康医院「山东」重症皮肤病救治平台 | 密度电子天平-内校-外校电子天平-沈阳龙腾电子有限公司 | 自动钻孔机-全自动数控钻孔机生产厂家-多米(广东)智能装备有限公司 | 振动筛,震动筛,圆形振动筛,振动筛价格,振动筛厂家-新乡巨宝机电 蒸汽热收缩机_蒸汽发生器_塑封机_包膜机_封切收缩机_热收缩包装机_真空机_全自动打包机_捆扎机_封箱机-东莞市中堡智能科技有限公司 | 自清洗过滤器-全自动自清洗过反冲洗过滤器 - 中乂(北京)科技有限公司 | led全彩屏-室内|学校|展厅|p3|户外|会议室|圆柱|p2.5LED显示屏-LED显示屏价格-LED互动地砖屏_蕙宇屏科技 | 超声波反应釜【百科】-以马内利仪器 | 翻斗式矿车|固定式矿车|曲轨侧卸式矿车|梭式矿车|矿车配件-山东卓力矿车生产厂家 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 空冷器|空气冷却器|空水冷却器-无锡赛迪森机械有限公司[官网] | 艺术漆十大品牌_艺术涂料加盟代理_蒙太奇艺术涂料厂家品牌|艺术漆|微水泥|硅藻泥|乳胶漆 | 华禹护栏|锌钢护栏_阳台护栏_护栏厂家-华禹专注阳台护栏、楼梯栏杆、百叶窗、空调架、基坑护栏、道路护栏等锌钢护栏产品的生产销售。 | 塑料检查井_双扣聚氯乙烯增强管_双壁波纹管-河南中盈塑料制品有限公司 | 混合生育酚_醋酸生育酚粉_琥珀酸生育酚-山东新元素生物科技 | 创绿家招商加盟网-除甲醛加盟-甲醛治理加盟-室内除甲醛加盟-创绿家招商官网 | 吉林污水处理公司,长春工业污水处理设备,净水设备-长春易洁环保科技有限公司 | 振动筛-交叉筛-螺旋筛-滚轴筛-正弦筛-方形摇摆筛「新乡振动筛厂家」 | 锤式粉碎机,医药粉碎机,锥式粉碎机-无锡市迪麦森机械制造有限公司 | 冷藏车-东风吸污车-纯电动环卫车-污水净化车-应急特勤保障车-程力专汽厂家-程力专用汽车股份有限公司销售二十一分公司 | 深圳市万色印象美业有限公司 | 北京自然绿环境科技发展有限公司专业生产【洗车机_加油站洗车机-全自动洗车机】 | 上海宿田自动化设备有限公司-双面/平面/单面贴标机 | 分轨 | 上传文件,即刻分离人声和伴奏 | 消电检公司,消电检价格,北京消电检报告-北京设施检测公司-亿杰(北京)消防工程有限公司 |