python - django - 只预取最新的记录?
问题描述
我正在尝试仅针对父记录预取最新记录。
我的模型就是这样
class LinkTargets(models.Model):
device_circuit_subnet = models.ForeignKey(DeviceCircuitSubnets, verbose_name="Device", on_delete=models.PROTECT)
interface_index = models.CharField(max_length=100, verbose_name='Interface index (SNMP)', blank=True, null=True)
get_bgp = models.BooleanField(default=False, verbose_name="get BGP Data?")
dashboard = models.BooleanField(default=False, verbose_name="Display on monitoring dashboard?")
class LinkData(models.Model):
link_target = models.ForeignKey(LinkTargets, verbose_name="Link Target", on_delete=models.PROTECT)
interface_description = models.CharField(max_length=200, verbose_name='Interface Description', blank=True, null=True)
...
以下查询失败并出现错误
AttributeError: 'LinkData' object has no attribute '_iterable_class'
询问:
link_data = LinkTargets.objects.filter(dashboard=True) \
.prefetch_related(
Prefetch(
'linkdata_set',
queryset=LinkData.objects.all().order_by('-id')[0]
)
)
我考虑过获取 LinkData 并进行相关选择,但我不知道如何为每个 link_target_id 仅获取 1 条记录
link_data = LinkData.objects.filter(link_target__dashboard=True) \
.select_related('link_target')..?
编辑:
使用 rtindru 的解决方案,预取的似乎是空的。目前有 6 条记录,为 3 个 LinkTargets 中的每一个测试 1 条记录
>>> link_data[0]
<LinkTargets: LinkTargets object>
>>> link_data[0].linkdata_set.all()
<QuerySet []>
>>>
解决方案
原因是Prefetch
需要一个 DjangoQueryset
作为queryset
参数,而您正在提供一个对象的实例。
更改您的查询如下:
link_data = LinkTargets.objects.filter(dashboard=True) \
.prefetch_related(
Prefetch(
'linkdata_set',
queryset=LinkData.objects.filter(pk=LinkData.objects.latest('id').pk)
)
)
Prefetch
这确实具有在很大程度上破坏目的的不幸效果。
更新
这会在全局范围内预取一条记录;不是最新的LinkData
记录LinkTarget
。
要为每个 LinkTarget 预取最大 LinkData,您应该从 LinkData 开始:您可以按如下方式实现:
LinkData.objects.filter(link_target__dashboard=True).values('link_target').annotate(max_id=Max('id'))
这将返回 { link_target
: 12, max_id
: 3223}的字典
然后,您可以使用它返回正确的对象集;也许过滤 LinkData 基于max_id
.
这看起来像这样:
latest_link_data_pks = LinkData.objects.filter(link_target__dashboard=True).values('link_target').annotate(max_id=Max('id')).values_list('max_id', flat=True)
link_data = LinkTargets.objects.filter(dashboard=True) \
.prefetch_related(
Prefetch(
'linkdata_set',
queryset=LinkData.objects.filter(pk__in=latest_link_data_pks)
)
)
推荐阅读
- wpf - 如何将多个着色器效果应用于 DrawingVisual?
- php - Symfony docker 配置中的两个服务
- python - 从一个图中的坐标列表中绘制多条线
- javascript - Vue Js在select2中没有得到select选项值
- javascript - Redsys 问题(MVC .net 项目) - 不显示付款消息
- angular - LoginPage 是 2 个模块声明的一部分
- azure - Azure 日志分析休息 API 调用错误 403
- android - Android-如何在本地存储和检索 SecretKey 对象并检索它
- javascript - Javascript 阻止或减慢浏览器的速度。如何防止警报或加速脚本
- c++ - 逆平方根内在函数