2010-09-16 37 views
2

我有安装像这样(变简单)处理相关模型在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值(因此,如果请求是针对特定资源的,我可以提供更多详细信息)。

所以我想我的问题有三个方面:

  1. 有没有一种方法来过滤或以某种方式限制记录的子记录(即过滤documents每个author.documents
  2. 如果没有,是什么这样做的功能还可以与Django-piston一起使用吗?
  3. 是否有一些更容易,更好的方法来做我想做的事情(如果没有给出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的内容。这似乎应该是可能的,但也许它不是?

回答

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个匹配所有条件)。

如果您使用的字典(.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 
+0

这只过滤作者的记录,这是不想要的效果。 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

+0

@Jordan,对于没有缺失匹配的作者是真的(它是一个过滤器,所以它们当然会被删除),但文档计数不起作用,因为您没有使用查询集来查找文档计数。由于评论太长且需要代码,我编辑了答案。 – laurent 2010-09-21 04:17:00

+0

@Jordan,'author.documents.count()'将始终返回100,除非您修改数据,因为它是一个新的查询而没有过滤 – laurent 2010-09-21 13:25:24