Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从queryset获取所有多对多对象的有效方法_Python_Django_Pandas - Fatal编程技术网

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(..)
不是一个好主意。只有在某些情况下,比如根据某个值创建一个组,这才是一个好主意。通常最好使用模型对象,因为它们添加了额外的逻辑层