使用Django实现把两个模型类的数据聚合在一起


Posted in Python onMarch 28, 2020

Django中想要把模型类聚合得到想要的数据可以用F对象。

比如有模型类A和B,A和B之间有外键关联在一起,A是子表,B是父表(反过来没试过。。因为大部分数据都是用子表的,我想是可以的),那么可以这样查:

A.objects.filter(userid=3,bookid=F(bid))

其中userid,bookid是模型类A的字段,bid是模型类B的字段。

这样操作的结果就是可以查询到userid为3且模型类A字段bookid等于模型类B字段bid的集合数据了。

F对象是可以比较两个关联模型类的字段数据的。

我看到网上有说F对象可以这样用F('b__id') ==>F('模型类名小写__字段名'),此处是双下划线。

但是我用Django2.0时会报错。。真是搞不懂,后来我直接使用字段名居然可以,醉了。

反正都可以试试吧

A.objects.filter(userid=3,bookid=F(bid))

A.objects.filter(userid=3,bookid=F('b__bid'))

补充知识:Django Admin页面显示父表,编辑子表

默认情况下,ModelAdmin只允许您管理模型“本身”字段,而不是相关模型.以下方法将实现,在应用类的列表管理显示页面,显示父表的字段;在编辑页面,父表对子表进行编辑.

models.py如下

class Level(models.Model):
 # l_num = models.IntegerField(default=0, verbose_name='序号')
 name = models.CharField(max_length=20)
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  return self.name

class Grades(models.Model):
 name = models.CharField(max_length=20, verbose_name='班级')
 # 外键,这里关联模型Level与模型名称一样,不是全小写。
 level = models.ForeignKey('Level', on_delete=models.DO_NOTHING)
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  return '%s%s' % (self.level, self.name)

class Students(models.Model):
 name = models.CharField(max_length=20, db_index=True, verbose_name='姓名')
 age = models.IntegerField(verbose_name='年龄')

 # 需要先提供一个二维的二元元组,第一个元素表示存在数据库内真实的值,第二个表示页面上显示的具体内容
 SEX_CHOICE = (
  ('男', '男'),
  ('女', '女'),
 )
 sex = models.CharField(max_length=10, choices=SEX_CHOICE, verbose_name='性别', default='男')
 grade = models.ForeignKey('Grades', on_delete=models.DO_NOTHING, verbose_name="班级")
 img_student = models.ImageField(upload_to='img_student', default='img_student/default.png', verbose_name='头像')
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 last_update_time = models.DateTimeField(auto_now=True, verbose_name='上次更新时间')
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  return self.name

在admin.py代码如下:

@admin.register(Students)
class StudentsAdmin(admin.ModelAdmin):
 list_display = ('name', 'age', 'sex', 'grade', 'create_time', 'last_update_time', 'is_delete')

做完之后,显示的效果如下:

使用Django实现把两个模型类的数据聚合在一起

在应用类的列表管理显示页面,显示父表的字段

可以让Students,显示父表Grades的父表Level字段

在models.py里的Students类里,写上如下代码:

class Students(models.Model):

# 写一个方法,定义在管理页面上能够显示的外键字段字段
  # grade为Students模型的外检表,level为Grades模型的外检表,那么为Level模型的字段
  def dis_level(self):
   return self.grade.level.name

  # 定义该字段在管理后台显示的名称
  dis_level.short_description = '年级'
  
 # 定义该字段在管理后台显示的名称
 dis_level.short_description = '年级'
 # 方法列是不能排序的,如果需要排序需要为方法指定排序依据。添加的是'模型类字段'
 # 如果是外键需要遵循这样的语法:本表外键字段__(双下划线)外检表字段或外检表的外键字段__最终外键表要显示的字段。
 dis_level.admin_order_field = 'grade__level__name'

在admin.py里,把Students类里的方法,加入到list_display里:

@admin.register(Students)
class StudentsAdmin(admin.ModelAdmin):
 list_display = ('name', 'age', 'sex', 'grade', 'dis_level', 'create_time', 'last_update_time', 'is_delete')

写完之后,显示的结果如下,多了年级,以及点击年级可以进行排序:

使用Django实现把两个模型类的数据聚合在一起

在编辑页面,父表对子表进行编辑.

默认对学生编辑时,无法在编辑页面直接编辑相关联的子表,例如:

models.py代码:

class Students(models.Model):
 name = models.CharField(max_length=20, db_index=True, verbose_name='姓名')
 age = models.IntegerField(verbose_name='年龄')

 # 需要先提供一个二维的二元元组,第一个元素表示存在数据库内真实的值,第二个表示页面上显示的具体内容
 SEX_CHOICE = (
  ('男', '男'),
  ('女', '女'),
 )
 sex = models.CharField(max_length=10, choices=SEX_CHOICE, verbose_name='性别', default='男')
 grade = models.ForeignKey('Grades', on_delete=models.DO_NOTHING, verbose_name="班级")
 img_student = models.ImageField(upload_to='img_student', default='img_student/default.png', verbose_name='头像')
 create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
 last_update_time = models.DateTimeField(auto_now=True, verbose_name='上次更新时间')
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  return self.name


class Course(models.Model):
 name = models.CharField(max_length=20, verbose_name='课名')
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  return self.name


class Score(models.Model):
 s_score = models.IntegerField(default=0, verbose_name='分数')
 s_course = models.ForeignKey('Course', on_delete=models.DO_NOTHING, verbose_name='课程')
 s_student = models.ForeignKey('Students', on_delete=models.DO_NOTHING, verbose_name='学生姓名')
 is_delete = models.BooleanField(default=False)
 
 def __str__(self):
  # 要把s_score转换为字符串,否则会报下面的错误。
  """
   Exception Type:TypeError
   Exception Value:
   __str__ returned non-string (type int)
   :return:
  """
  return '%s%s%s' % (self.s_student, self.s_course, str(self.s_score))

打开学生的编辑页面,是这样子的:

使用Django实现把两个模型类的数据聚合在一起

要给学生添加分数,只能进入Score管理页面,一个个添加,非常麻烦.

使用Django的TabularInline,可以解决这个问题,在父表里对子表进行编辑:

所有代码都在admin.py里写,具体如下:

# 一对多关联表编辑,让父表管理配置页面能同时编辑子表,以下的Score为子表(有外键所在的表)
class ScoreInline(admin.TabularInline):
 # Score 必须是models.py中的模型名称,大小写必须要匹配.这个模型为子表,以便可以被父表编辑
 model = Score
 # 默认显示条目的数量
 # extra = 5
 
class StudentsAdmin(admin.ModelAdmin):
 # Inline把ScoreInline关联进来,让父表管理配置页面能同时编辑子表.
 inlines = [ScoreInline, ]

做完之后,效果如下:

使用Django实现把两个模型类的数据聚合在一起

以上这篇使用Django实现把两个模型类的数据聚合在一起就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python sqlobject(mysql)中文乱码解决方法
Nov 14 Python
Python中利用原始套接字进行网络编程的示例
May 04 Python
Python 3.x 判断 dict 是否包含某键值的实例讲解
Jul 06 Python
python实现简单http服务器功能
Sep 17 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
Apr 11 Python
python3 pygame实现接小球游戏
May 14 Python
Django 表单模型选择框如何使用分组
May 16 Python
python安装scipy的步骤解析
Sep 28 Python
检测tensorflow是否使用gpu进行计算的方式
Feb 03 Python
Python尾递归优化实现代码及原理详解
Oct 09 Python
Python实例教程之检索输出月份日历表
Dec 16 Python
python 实现德洛内三角剖分的操作
Apr 22 Python
使用python客户端访问impala的操作方式
Mar 28 #Python
python 安装impala包步骤
Mar 28 #Python
django 链接多个数据库 并使用原生sql实现
Mar 28 #Python
Django多数据库配置及逆向生成model教程
Mar 28 #Python
后端开发使用pycharm的技巧(推荐)
Mar 27 #Python
如何基于python3和Vue实现AES数据加密
Mar 27 #Python
python小程序基于Jupyter实现天气查询的方法
Mar 27 #Python
You might like
php中cookie的作用域
2008/03/27 PHP
php cout<<的一点看法
2010/01/24 PHP
Php获取金书网的书名的实现代码
2010/06/11 PHP
php判断是否为json格式的方法
2014/03/04 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
php命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
php简单复制文件的方法
2016/05/09 PHP
Yii框架日志操作图文与实例详解
2019/09/09 PHP
DWR Ext 加载数据
2009/03/22 Javascript
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
javascript中input中readonly和disabled区别介绍
2012/10/23 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
不得不分享的JavaScript常用方法函数集(上)
2015/12/23 Javascript
前端js文件合并的三种方式推荐
2016/05/19 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
2018/11/20 Javascript
详解nuxt路由鉴权(express模板)
2018/11/21 Javascript
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
JS实现秒杀倒计时特效
2020/01/02 Javascript
JavaScript实现4位随机验证码的生成
2021/01/28 Javascript
Python+Wordpress制作小说站
2017/04/14 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
智利最大的网上商店:Linio智利
2016/11/24 全球购物
Nili Lotan官网:Nili Lotan同名品牌
2018/01/07 全球购物
粗加工管理制度
2014/02/04 职场文书
人力资源部经理的岗位职责
2014/03/04 职场文书
党的群众路线教育实践活动心得体会900字
2014/03/07 职场文书
法制报告会主持词
2014/04/02 职场文书
教师党员个人自我剖析材料
2014/09/29 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
2014年工程部工作总结
2014/11/25 职场文书
科技活动总结范文
2015/05/11 职场文书
团队执行力培训心得体会
2015/08/15 职场文书
2016年质量月活动总结报告
2016/04/05 职场文书
如何搭建 MySQL 高可用高性能集群
2021/06/21 MySQL
关于python中模块和重载的问题
2021/11/02 Python