gpt4 book ai didi

python - 从查询集中获取所有多对多对象的有效方法

转载 作者:行者123 更新时间:2023-12-01 07:00:43 25 4
gpt4 key购买 nike

我有类似于以下的模型:

class Tag(models.Model):
text = models.CharField(max_length=30)

class Post(models.Model):
title = models.CharField(max_length=30)
tags = models.ManyToManyField(Tag)

一个帖子可以有许多标签,并且标签可以与许多帖子关联。

我需要的是获取所有帖子的列表以及与每个帖子关联的所有标签。然后,我根据该数据创建一个 Pandas DataFrame。这是我目前的做法:

qs = Post.objects.all().prefetch_related('tags')

tag_df = pd.DataFrame(columns=["post_id", "tags"])
for q in qs:
tag_df = tag_df.append(
{
"post_id": q.pk,
"tags": list(q.tags.all().values_list("text", flat=True)),
},
ignore_index=True,
)

post_df = pd.DataFrame(qs.values("id", "title"))
final_df = post_df.merge(tag_df, left_on="id", right_on="post_id")

就我需要的数据而言,结果是正确的。问题在于它的效率低得令人难以置信,而且即使我使用的是 prefetch_lated,运行的查询数量也是如此。看起来循环的每次迭代都会有一个查询访问数据库。

有没有更好、更有效的方法来做到这一点(可能没有循环)?最后我需要的是一个包含所有帖子的数据框以及一个包含每个帖子的标签列表的列。

最佳答案

通过使用.values_list(..),您将在每次迭代中进行额外的查询。所以这不是很有效。您可以简单地使用已经预取的 Tag 对象,并获取 .text 属性:

qs = Post.objects.prefetch_related('tags')

tag_df = pd.DataFrame(columns=['post_id', 'tags'])
for q in qs:
tag_df = tag_df.append(
{
'post_id': q.pk,
'tags': <b>[t.text for t in q.tags.all()]</b>,
},
ignore_index=True,
)

post_df = pd.DataFrame(qs.values('id', 'title'))
final_df = post_df.merge(tag_df, left_on='id', right_on='post_id')

但是,首先创建一个字典列表,然后将它们加载到数据框中一次可能会更有效:

qs = Post.objects.prefetch_related('tags')

data = [
{'id': q.pk, 'title': q.title, 'tags': [t.text for t in q.tags.all()]}
for q in qs
]
final_df= <b>pd.DataFrame(data, columns=['id', 'title', 'tags'])</b>

请注意,使用 .values(..).values_list(..) 不是一个好主意。仅在某些情况下,例如对某个值进行 GROUP BY,这是一个好主意。通常最好使用模型对象,因为它们添加了额外的逻辑层。

关于python - 从查询集中获取所有多对多对象的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58640568/

25 4 0
文章推荐: jquery - 使用 jQuery 为
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com