gpt4 book ai didi

python - Django formset,查询每个表单的关系字段

转载 作者:太空狗 更新时间:2023-10-29 17:08:16 26 4
gpt4 key购买 nike

模型.py

class Material(BaseModelClass):
material = models.CharField(max_length=25, verbose_name='Material')
def __str__(self):
return self.material

class PurOrder(BaseModelClass):
order_number = models.CharField(max_length=25)

class PurOrderItem(BaseModelClass):
order = models.ForeignKey(PurOrder, on_delete=models.CASCADE)
material = models.ForeignKey(Material, on_delete=models.PROTECT)

我创建了一个 PurOrder 表单和 PurOrderItem 表单集

PurOrderForm = modelform_factory(PurOrder, fields=('order_number',))
PurOrderFormset = inlineformset_factory(PurOrder, PurOrderItem,fields=('material',))

初始化如下。

form = PurOrderForm(instance=order_instance)
queryset = order_instance.purorderitem_set.all().select_related('material',)
formset = PurOrderFormset(instance=order_instance, queryset=queryset)

如果所选采购订单有 20 个 PurOrderItem,此设置会花费我 22 个查询。

  • 1 个用于 PurOrder 实例,
  • 1 个用于 PurOrderItem 实例
  • 20 个 PurOrderItem 的选定 Material 。

想想看,如果有1000个PurOrderItem

使用提供的 select_related,它将 Material 添加到 PurOrderItemselect,但我认为在显示它时,它会再次查询。

我使用 django-autocomplete-light,所以它使我免于查询所有 Material 实例,但它会不断查询选定的 Material ,即使我选择了相关 Material 也会显示它。

理想情况下,我会选择带有预取 purorderitem 和相关 Material 的 PurOrder 实例,这意味着 3 个查询。轮到他们时,将使用预取的 purorderitem 和 Material 。

请告诉我一种避免选择查询的方法。

注意:我尽量避免在这里缓存。

更新

在我创建这个问题很久之后,我尝试了提供的解决方案。问题是,formset 的表单彼此不了解。因此,前提是查询集的 selected_related 或 prefetch_related 查找未传递到表单集表单。

最佳答案

你很好。此代码仅花费您 3 次查询。正如您在 select_related() 中看到的那样文档:

Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query. This is a performance booster which results in a single more complex query but means later use of foreign-key relationships won’t require database queries.

这意味着您的代码将执行 mysql join 并将生成包含所有数据的数据集。因此,我可以看出您的代码非常好。

我建议您使用某种分析,例如 django-silk查看生成了多少查询。

脚注:

正如您在 prefetch_related() 中看到的那样文档中,prefetch_related()select_related() 之间的区别在于它们执行连接的方式:

This (prefetch_related) has a similar purpose to select_related, in that both are designed to stop the deluge of database queries that is caused by accessing related objects, but the strategy is quite different.

...

select_related works by creating an SQL join and including the fields of the related object in the SELECT statement. For this reason, select_related gets the related objects in the same database query.

...

prefetch_related, on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python.

所以只要你需要一对一关系,select_related是查询关系最高效的方式。

关于python - Django formset,查询每个表单的关系字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48767853/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com