Python 获取值()内反向外键关系的多个对象
我有两个django型号,如下所示:Python 获取值()内反向外键关系的多个对象,python,django,django-models,django-orm,Python,Django,Django Models,Django Orm,我有两个django型号,如下所示: class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() class Entry(models.Model): entry_id = models.Autofield(primary_key=True) blog = models.ForeignKey(Blog, on_delete=mode
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
class Entry(models.Model):
entry_id = models.Autofield(primary_key=True)
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name='blog')
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
我正在尝试使用相关的名称获取反向关系。我想通过使用相关的_名称“blog”获取“Entry”的全部数据
每个博客都有多个条目
如何实现以下输出:
{'name': '', 'tagline': '', 'all_blogs':[{'blog': '','headline': '','body_text': '','pub_date': '', 'mod_date': ''},]}
我试过这个:
response = Blog.objects.filter(
name=name,
blog__pub_date=date
).values(
'name',
'tagline',
all_blogs=Entry.objects.filter(entry_id=F(blog__entry_id)).values()
)
return response
但它抛出了一个字段错误,表示我不能在F()表达式中使用“blog”字段
感谢您的回复。我必须说,如果将外键从
条目
发送到博客
相关名称博客,以后可能会让您有点头疼。因为这个原因,我不确定我的答案是否正确。使用相关的名称条目可能更容易
无论如何,我都会尝试给出一些有用的例子。(
Edit:
如果要使用psql)与ArrayAg一起使用,您可以选择获取指向此当前条目的多个外键列表。这将为您提供一个相关条目的列表
ID,这些ID并不完全是您想要的。但这是一个相当简单的Django查询解决方案,可以让您开始使用所需的结果格式
from django.contrib.postgres.aggregates import ArrayAgg
response = Blog.objects.filter(
name=name,
blog__pub_date=date
).annotate(
all_blogs=ArrayAgg('blog')
).values(
'name',
'tagline',
'all_blogs'
)
return response
蟒蛇之道更少的是Django查询和基于sql的,更多的是面向Python的解决方案,它实际上为您提供了数据结构和所需的所有信息。可以通过循环您手头的查询集,并在运行中创建字典列表来实现 使用此解决方案,您当然可以自由设置响应结构的格式
注意代码> Python循环与SQL生成数据的效率几乎不一样,因此您需要考虑它是否是您可以使用的选项。
queryset = Blog.objects.filter(
name=name,
blog__pub_date=date
).prefetch_related(
'blog_set'
)
response = [
{
'name': blog.name,
'tagline': blog.tagline,
'all_blogs': blog.blog_set.all().values()
} for blog in queryset
]
return response
编辑:
关于数据库查询计数的说明
与预取_相关,可以将反向外键或许多字段连接到原始查询集。实际上,这是用python完成的,而不是用sql。这意味着我们要两次访问数据库:
- 一次用于原始查询
- 一次用于相关查询,然后使用python将其“连接”到原始查询集
之后,我们不再对循环中的数据库进行更多查询
下面是一个关于预取相关工作原理(以及选择相关工作原理)的极好解释:
我不得不说,通过将ForeignKey fromEntry
赋予Blog
一个相关名称Blog,以后可能会让你有点头疼。因为这个原因,我不确定我的答案是否正确。使用相关的名称条目可能更容易
无论如何,我都会尝试给出一些有用的例子。
(Edit:
如果要使用psql)与ArrayAg一起使用,您可以选择获取指向此当前条目的多个外键列表。这将为您提供一个相关条目的列表
ID,这些ID并不完全是您想要的。但这是一个相当简单的Django查询解决方案,可以让您开始使用所需的结果格式
from django.contrib.postgres.aggregates import ArrayAgg
response = Blog.objects.filter(
name=name,
blog__pub_date=date
).annotate(
all_blogs=ArrayAgg('blog')
).values(
'name',
'tagline',
'all_blogs'
)
return response
蟒蛇之道
更少的是Django查询和基于sql的,更多的是面向Python的解决方案,它实际上为您提供了数据结构和所需的所有信息。可以通过循环您手头的查询集,并在运行中创建字典列表来实现
使用此解决方案,您当然可以自由设置响应结构的格式
注意代码> Python循环与SQL生成数据的效率几乎不一样,因此您需要考虑它是否是您可以使用的选项。
queryset = Blog.objects.filter(
name=name,
blog__pub_date=date
).prefetch_related(
'blog_set'
)
response = [
{
'name': blog.name,
'tagline': blog.tagline,
'all_blogs': blog.blog_set.all().values()
} for blog in queryset
]
return response
编辑:
关于数据库查询计数的说明
与预取_相关,可以将反向外键或许多字段连接到原始查询集。实际上,这是用python完成的,而不是用sql。这意味着我们要两次访问数据库:
- 一次用于原始查询
- 一次用于相关查询,然后使用python将其“连接”到原始查询集
之后,我们不再对循环中的数据库进行更多查询
下面是一个关于预取相关工作原理(以及选择相关工作原理)的极好解释:
我认为,给一个与您的一个模型(博客和博客)的名称相同(除了大写)的相关名称是一种糟糕的做法,这甚至可能是给您带来问题的原因。即使这不是原因,这种命名也会导致代码中的许多歧义。此外,行:all_blogs=Entry.objects.filter(…)没有意义:在Entry表上查询将返回Entry对象,而不是Blog对象,那么为什么要将结果分配给一个名为“all_blogs”的键呢?我认为,给一个与某个模型的名称相同(除了大写)的相关_名称是一种不好的做法(Blog和Blog),这甚至可能是给您带来问题的原因。即使不是原因,这种命名也会导致代码中的许多歧义。此外,行:all_blogs=Entry.objects.filter(…)没有意义:在Entry表上查询将返回Entry对象,而不是Blog对象,那么为什么要将结果分配给一个名为“all_blogs”的键呢?谢谢你的回答。我使用mysql作为后端。因此,第一个选项不合适。关于第二个选项,我对数据库被命中的次数感到困惑。它是一次命中还是每次在循环内命中?@Manohar:与预回迁相关,我们命中数据库两次。一次用于博客对象,第二次用于条目objects(related_name blog)。这个“连接”是用python而不是sql构建的,这就是为什么有两个单独的数据库查询。循环本身不会再访问数据库。谢谢你的回答。我使用mysql作为后端。因此,第一个选项不合适。关于第二个选项,