处理相关模型在Django用于Django的活塞
我有安装像这样(变简单)处理相关模型在Django用于Django的活塞
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-产生活塞,如果你返回一个QuerySet对象,它似乎是最快乐的(特别是如果你正在定义你自己的领域!)。
部分原因可能是因为我对基本django活塞代码进行了更改。基本上,这里的current version of the code覆盖了fields
的值。我更改了这段代码,以便根据请求更改处理程序的fields
值(因此,如果请求是针对特定资源的,我可以提供更多详细信息)。
所以我想我的问题有三个方面:
- 有没有一种方法来过滤或以某种方式限制记录的子记录(即过滤
documents
每个author.documents
) - 如果没有,是什么这样做的功能还可以与Django-piston一起使用吗?
- 是否有一些更容易,更好的方法来做我想做的事情(如果没有给出id,显示所有作者没有他们的文档,但显示子记录,如果过滤到只有一个作者)?
澄清
好了,仅仅是明确的,这里是我想要的伪代码:
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
的内容。这似乎应该是可能的,但也许它不是?
编辑...或更好...取代! :)
这是真的没有文件匹配的作者不会在查询集中,所以你将不得不将它们添加回来(我找不到更好的方法,但也许有人知道如何不删除它们而不使用原始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个匹配所有条件)。
如果您使用的字典(.values()),而不是查询集在上面的步骤,你不能这样做,(我认为),因为字典不会有文件字段,以便:
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将在第一列中列出<authors>
列表和第二列中匹配的文件数。
我知道这是远远不够完善......但如果你有兴趣只在每相匹配创作文档的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,您需要筛选每个类别i的查询而不是使用__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
这只过滤作者的记录,这是不想要的效果。 John,Sally和Maria各写了100个文档,John有10个匹配文档,Sally 8,Maria 0.随着你的查询,只有John和Sally会出现,并且对于每个'author.documents.count()'仍然是100.我想让John,Sally和Maria出现,'author.documents.count()'应该分别为10,8和0。我怀疑是否存在一种黑客,如果您愿意惹恼QuerySet对象的内部组件,那么您可以设置此项。 – 2010-09-20 15:56:55
@Jordan,对于没有缺失匹配的作者是真的(它是一个过滤器,所以它们当然会被删除),但文档计数不起作用,因为您没有使用查询集来查找文档计数。由于评论太长且需要代码,我编辑了答案。 – laurent 2010-09-21 04:17:00
@Jordan,'author.documents.count()'将始终返回100,除非您修改数据,因为它是一个新的查询而没有过滤 – laurent 2010-09-21 13:25:24