2010-09-16 38 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