Python 从queryset获取所有多对多对象的有效方法
我有以下类似的型号:Python 从queryset获取所有多对多对象的有效方法,python,django,pandas,Python,Django,Pandas,我有以下类似的型号: 类标记(models.Model): text=models.CharField(最大长度=30) 班级职务(models.Model): title=models.CharField(最大长度=30) 标记=型号。ManyToManyField(标记) 一篇Post可以有许多标签,标签可以与许多帖子关联 我需要的是获得所有帖子的列表以及与每个帖子相关联的所有标签。然后,我从该数据创建一个数据帧。以下是我目前的做法: qs=Post.objects.all().prefe
类标记(models.Model):
text=models.CharField(最大长度=30)
班级职务(models.Model):
title=models.CharField(最大长度=30)
标记=型号。ManyToManyField(标记)
一篇Post
可以有许多标签
,标签
可以与许多帖子
关联
我需要的是获得所有帖子的列表以及与每个帖子相关联的所有标签。然后,我从该数据创建一个数据帧。以下是我目前的做法:
qs=Post.objects.all().prefetch_相关('tags'))
tag_df=pd.DataFrame(列=[“post_id”,“tags”])
对于qs中的q:
tag_df=tag_df.append(
{
“post_id”:q.pk,
“标记”:列表(q.tags.all().values_列表(“text”,flat=True)),
},
忽略_index=True,
)
post_df=pd.DataFrame(qs.values(“id”、“title”))
final_-df=post_-df.merge(标记_-df,left_-on=“id”,right_-on=“post\u-id”)
就我需要的数据而言,结果是正确的。问题在于它的效率有多低,以及即使我使用的是预回迁相关的
也会运行多少查询。对于循环的每次迭代,查询似乎都会命中数据库
有没有更好、更有效的方法(可能没有循环)?最后我只需要一个包含所有帖子的数据框,以及一个列,该列包含每个帖子的标签列表。通过使用
.values\u list(…)
您将在每次迭代中进行额外的查询。所以这不是很有效。只需使用已预取的标记
对象,即可获得.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': [t.text for t in q.tags.all()],
},
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_相关('tags'))
tag_df=pd.DataFrame(列=['post_id','tags'])
对于qs中的q:
tag_df=tag_df.append(
{
“post_id”:q.pk,
'tags':[t.text代表q.tags.all()中的t,
},
忽略_index=True,
)
post_df=pd.DataFrame(qs.values('id','title'))
final_-df=post_-df.merge(标记_-df,左在'id'上,右在'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= pd.DataFrame(data, columns=['id', 'title', 'tags'])
qs=Post.objects.prefetch_相关('tags'))
数据=[
{'id':q.pk,'title':q.title,'tags':[t.text代表q.tags.all()中的t]
对于qs中的q
]
final_df=pd.DataFrame(数据,列=['id','title','tags'])
请注意,使用.values(..)
或.values\u list(..)
不是一个好主意。只有在某些情况下,比如根据某个值创建一个组,这才是一个好主意。通常最好使用模型对象,因为它们添加了额外的逻辑层