我有2个型号,公司和产品。
class Product(Meta):
company = models.ForeignKey(Company, related_name='products', on_delete=models.CASCADE)
形成数据库我试图获取公司数据和相应的产品。
从产品中我只想获得名称,并按照updated_at,created_at降序排序。
我正在使用Prefetch
对象和prefetch_related
,并且最终我有多种误解,他们是如何工作的。
def get_queryset(self):
qs = Company.objects.prefetch_related(
Prefetch('products', queryset=Product.objects.only('name').order_by('-updated_at', '-created_at'))).get()
return qs
我收到的错误是:
get() returned more than one Company
因为我使用prefetch_related
关闭了)))
方法/功能:
我认为get()
将对公司对象采取行动并使用来自网址的pk / slug来获取它(默认情况下在DetailView中执行)。似乎并非如此。
我已经在使用'产品' Prefetch对象中的相关名称,为什么在queryset中需要再次告诉模型queryset=Product.objects....
?
我在django文档中查看以下示例:
Question.objects.prefetch_related(Prefetch('choice_set')).get().choice_set.all()
如果有' choice_set'在Prefetch
对象中为什么在最后choice_set.all()
调用?
不是Django在prefetch中将问题集附加到查询集中的问题集(question.choice_set)吗?
我认为我的问题在于我不了解执行的顺序,而且我对方法的链接方式感到困惑,即使这些方法已经被关闭了#);'
答案 0 :(得分:1)
queryset.get()
仅在查询集具有单个对象时才有效。如果它包含零个或多个对象,则会出现错误。
您应该从get_queryset
对象返回一个查询集。在基于类的视图中,在pk / slug上过滤的代码位于get_object
。
如果您想要为多个国家/地区提取产品,prefetch_related
方法非常有用。 Django docs使用get()
的方式在我看来令人困惑 - 如果查询集中有一个项目,则prefetch_related
过于复杂。
如果您有一家公司,那么没有任何优势,如果您单独取用国家/地区,代码会更简单,例如在get_context_data
。
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
context['products'] = Product.objects.filter(company=self.object).Product.objects.only('name').order_by('-updated_at', '-created_at')))
return context
我已删除only('name')
电话。这是您可能不需要的优化。
如果您确实想使用prefetch_related
,请删除get()
。
qs = Company.objects.prefetch_related(
Prefetch('products', queryset=Product.objects.order_by('-updated_at', '-created_at')))
通过指定上面的查询集,您可以更改顺序(如果愿意,可以过滤它)。如果您不想自定义查询集,则可以执行以下操作:
Company.objects.prefetch_related('products')
当您使用Question.objects.prefetch_related(...)
时,查询集仍然是一个问题列表。您需要在各个实例上调用choice_set.all()
来访问他们的选择。这不会导致任何其他查询,因为Django已经预先选择了这些选项。
queryset = Question.objects.prefetch_related(Prefetch('choice_set'))
for question in queryset:
print(question) # the question
print(question.choice_set.all()) # the related choices