我有一個列表Person
s每個有多個字段,我通常使用object_list通用視圖過濾的內容。每個人可以附加多個Comment
,每個人都有一個日期時間和一個文本字符串。我最終想要做的是可以根據日期過濾評論。Django join-like擴展queryset
class Person(models.Model):
name = models.CharField("Name", max_length=30)
## has ~30 other fields, usually filtered on as well
class Comment(models.Model):
date = models.DateTimeField()
person = models.ForeignKey(Person)
comment = models.TextField("Comment Text", max_length=1023)
我想要做的就是讓像
Person.objects.filter(comment__date__gt=date(2011,1,1)).order_by('comment__date')
一個QuerySet發送查詢集到object_list中,並能夠只看到日期,只有一個頁面上這麼多的對象命令的意見。如果「人A」有評論12/12/2010,1/2/2011,1/5/2011,「人B」沒有評論,並且人C對1/3/3評論有評論, 2010年,我會看到:
"Person A", 1/2 - comment
"Person C", 1/3 - comment
"Person A", 1/5 - comment
我強烈希望不要有切換到濾波基於Comments.objects.filter()
,因爲這將讓我有在很大程度上重複大段代碼的視圖和模板兩者。 (PersonA,PersonC,PersonA),但如果我嘗試在模板中渲染它,那麼每個人的comment_set將包含他們所有的評論,即使他們不是' t在日期範圍內。
理想情況下,會有某種功能,我可以將Person
查詢集的comment_set
擴展爲更大的查詢集,可以根據評論對其進行排序和排序,並放入object_list通用視圖中。這通常在SQL中使用JOIN很簡單,但我不想放棄在其他地方使用的ORM。
好的,我的解決方案基本上只是Comments.objects.filter();將模板分割爲一個單獨的文件,並以適當的方式包含,應用額外的上下文布爾值(如果comment_date_filter,在視圖中的所有人引用之前應用適當的前綴字符串(即''或'person__'):
{% if comment_date_filter %}
{% for obj in object_list %}
{% with obj.person as p %}
{% include "object_list_row.html" %}
{% endwith %}
{% endfor %}
{% else %}
{% for obj in object_list %}
{% with obj as p %}
{% include "object_list_row.html" %}
{% endwith %}
{% endfor %}
{% endif %}
它大多隻是加倍代碼在視圖和模板中,並試圖讓事情幹,並期待有一個簡單的解決方案,我只是忽略允許我實現聯接。 Django讓我根據評論日期(重複)命令醫生,但是不會讓我看到基於評論的評論嗎?這對我來說似乎很奇怪。我不想從Comment過濾的原因是,我的模板和視圖都是100行,並且做了一些我不想以兩種不同方式實現的奇特事情。 – 2011-01-06 06:21:30
我相信你原來的查詢是關閉的,'Person.objects.filter(comment__date__gt = date(2011,1,1))。order_by('comment__date')' 如果我對SQL的理解是正確的,這將通過他們的第一條評論來命令人們。 comment_date_filter而不是comment_date_filter有什麼不同。爲什麼過濾不同 比不過濾? 我的意思是,爲什麼不在視圖中這樣做: 'if filtered:objects = Comments.filter(...)。order_by(...)else:objects = Comments.order_by(... )' – milkypostman 2011-01-06 18:26:46
另請參見http://docs.djangoproject.com/en/1.2/ref/models/querysets/#values – milkypostman 2011-01-06 18:29:29