django怎么获取每个分组中的最新记录对应的那些项

来源:10-10 我的收藏功能2

桂圆

2024-01-09

模型是

"""
原料名:原料类型、原料名、原料号(用于显示排序) 
"""
class Material_name(models.Model):
    material_type = models.CharField(max_length=20, verbose_name='原料类型')
    material_name = models.CharField(max_length=20, verbose_name='原料名')
    material_number = models.IntegerField(verbose_name='原料号',default=0)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    start_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    state = models.BooleanField(default=True, verbose_name='是否启用')

    def __str__(self):
        return self.material_name

""" 
原料:原料类型、原料名、不含税价格
"""
class Material(models.Model):
    material_name = models.ForeignKey(Material_name,on_delete=models.DO_NOTHING ,verbose_name='原料名')
    material_price = models.FloatField(verbose_name='不含税价格',default=0)
    update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    start_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    def __str__(self):
        return self.material_name.material_name

我想查询Material_name中启用状态(state)是true的,对应在Material表中的,各个原料的update_time 是最近时间的一条记录
我的查询语句是

latest_update_times = Material.objects.filter(material_name__state=True).values('material_name').annotate(latest_time=Max('update_time')).values('material_name__material_name','latest_time','material_price')


但只要加上后面的 .values(‘material_name__material_name’,‘latest_time’,‘material_price’) 记录查到的就不是最近的一条,而是所有记录都取出来了,应该怎么做啊。
如果数据量大的话,表要怎么优化?

写回答

1回答

bobby

2024-01-10

要获取每个分组中的最新记录,你可以使用SubqueryOuterRef来编写子查询。以下是一种在 Django 中实现的方法:

from django.db.models import OuterRef, Subquery# 使用 Subquery 和 OuterRef 获取每个 Material_name 对应的最新记录的 idlatest_material_id = Material.objects.filter(
    material_name=OuterRef('pk')
).order_by('-update_time').values('id')[:1]# 查询 Material_name 中启用状态的记录,并将最新记录的相关字段获取出来latest_update_times = Material_name.objects.filter(
    state=True).annotate(
    latest_id=Subquery(latest_material_id),
    latest_time=Subquery(
        Material.objects.filter(id=OuterRef('latest_id')).values('update_time')[:1]
    ),
    material_price=Subquery(
        Material.objects.filter(id=OuterRef('latest_id')).values('material_price')[:1]
    )
).values('material_name', 'latest_time', 'material_price')

在这里,Subquery用于嵌套查询,OuterRef用于引用外部查询的字段。上述查询首先找到每个 Material_name 对应的最新记录的 id,然后再根据这些 id 获取相应的字段。


关于数据量大的问题,可以考虑在数据库中为相关字段添加适当的索引,以提高查询性能。另外,可以通过数据库分表或分区等技术来优化数据库结构,具体的优化策略需要根据具体情况来定。


0
0

Python3.6+django+xadmin,打造在线教育平台

【毕设】Python 2.7到3.6 完美适配,Django升级2.0

3677 学习 · 4038 问题

查看课程