我的设置是这样的(为简单而改变)
class Author(models.Model)
name = models.CharField(max_length=100)
...
class Document(models.Model):
title = models.CharField(max_length=200)
content - models.TextField()
author = models.ForeignKey("Author", related_name="documents")
date_published = models.DateTimeField()
categories = models.ManyToManyField("Category")
class Category(models.Model):
name = models.CharField(max_length=100)
我正在提取作者记录,但我只想为每个符合特定条件的作者提供相关的文档记录 - 例如,date_published和category。
我知道这样做的简单方法是使用Author.objects.values()
将记录作为字典列表引入,循环遍历每条记录并运行:
author['documents']=Document.objects.filter(categories__in=[category_list], date_published__year=year)`
然而,这是为django-piston生成的,如果你返回一个QuerySet对象,它似乎最开心(特别是如果你定义自己的字段!)。
部分原因可能是因为我对基础django-piston代码进行了更改。基本上,此处current version of the code会覆盖fields
值。我更改了此代码,以便根据请求更改Handler的fields
值(因此,如果请求是针对特定资源,我可以提供更多详细信息)。
所以我想我的问题有三个方面:
documents
的过滤器author.documents
)好的,为了清楚,这是我想要的伪代码:
def perhaps_impossible_view(request, categories=None, year=None):
authors = Author.objects.all()
authors.something_magical_happens_to_documents(category__in=[categories], date_published__year=year)
return render_to_response('blar.html', locals(), RequestContext(request))
因此,如果我 将其放入模板中,这将无需任何修改即可使用:
{% for a in authors %}
{% for d in authors.documents.all %}
{{ d.title }} is almost certainly in one of these categories: {{ categories }} and was absolutely published in {{ year }}. If not, .something_magical_happens_to_documents didn't work.
{% endfor %}
{% endfor %}
something_magical_happens_to_documents
必须为每个作者记录运行并实际更改documents
的内容。看起来这应该是可能的,但也许不是吗?
答案 0 :(得分:0)
已编辑...或更好......已被替换! :)
没有文档匹配的作者不会在查询集中,所以你必须在之后添加它们(我找不到更好的方法,但也许有人知道如何不使用原始sql删除它们)。
您可以获得作者的完整文档数,因为您不使用查询集来获取文档计数:
qryset = Author.objects.all()
qryset = qryset.filter(documents__categories__name__in = category_list).distinct()
qryset = qryset.filter(documents__date_published__year=year)
print(qryset)
提供[<Author: Author object>]
(如果只有1位作者与所有类别匹配),qryset[0].documents.count()
将只返回匹配的文档数(并非所有文档都来自作者 - 在我测试的情况下2,作者有4个但只有2个符合所有条件。)
如果在上面的步骤中使用dict(.values())而不是查询集,则不能这样做(我认为)因为dict没有文档字段所以:
qryset_dict = Author.objects.values()
qryset_dict = qryset_dict.filter(documents__categories__name__in = category_list).distinct().values()
qryset_dict = qryset_dict.filter(documents__date_published__year=year).values()
当您发出qryset_dict[0].documents.count()
时,您收到错误消息:
AttributeError: 'dict' object has no attribute 'documents'
现在要添加已过滤的作者,您可以执行以下操作:
res = []
for a in Author.objects.all():
if a in qryset:
res.append([a,a.documents.count()])
else:
res.append([a,0])
和res将是第1列中<authors>
的列表和第2列中匹配的文档数。
我知道这远非完美......但如果您只对每位作者的count()
匹配文档感兴趣,我认为您可以找到一种更好的方法来使用django aggregation and annotation或者可能使用它使用从作者到文档的left join
的原始sql。
def possible_view(request, categories=None, year=None):
# you will pass these as parmeters of course
category_list = ['c2', 'c3']
year = 2010
qryset = Document.objects.filter(categories__name__in = category_list).distinct()
qryset = qryset.filter(date_published__year=year)
authors = Author.objects.all()
return render_to_response('blar.html', { 'result': qryset, 'authors': authors, 'categories': category_list, 'year': year }, RequestContext(request))
模板blar.html
:
{% for a in authors %}
<b>{{a.name}}</b><br />
{% for d in result %}
{% if d.author.name == a.name %}
{{ d.title }} is almost certainly in one of these categories: {{ categories }} and was absolutely published in {{ year }}. If not, .something_magical_happens_to_documents didn't work.<br />
{% endif %}
{% endfor %}<br />
{% endfor %}
这会给你一些不太漂亮的东西,但是对于所有作者和每个作者之下,他们的文档列表属于category_list
之一(OR条件,对于AND,你需要过滤查询每个类别而不是使用__in
)。
如果作者在category_list
中没有文档,则会在其下方没有文档的情况下列出。
类似的东西:
aut1
tit2 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely published in 2010. If not, .something_magical_happens_to_documents didn't work.
tit1 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely published in 2010. If not, .something_magical_happens_to_documents didn't work.
aut2
tit3 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely published in 2010. If not, .something_magical_happens_to_documents didn't work.
aut3