django join-like expansion of queryset
I have a list of Person
s each which have multiple fields that I usually filter what's upon, using the object_list generic view. Each person can have multiple Comment
s attached to them, each with a datetime and a text string. What I ultimately want to do is have the option to filter comments based on dates.
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)
What I want to do is get a queryset like
Person.objects.filter(comment__date__gt=date(2011,1,1)).order_by('comment__date')
send that queryset to object_list and be able to only see the comments ordered by date with only so many objects on a page.
E.g., if "Person A" has comments 12/12/2010, 1/2/2011, 1/5/2011, "Person B" has no comments, and person C has a comment on 1/3/2010, I would see:
"Person A", 1/2 - comment
"Person C", 1/3 - comment
"Person A", 1/5 - comment
I would strongly prefer not to have to switch to filtering based on Comments.objects.filter()
, as that would make me have to largely repeat large sections of code in the both the view and template.
Right now if I tried executing the following command, I will get a queryset returning (PersonA, PersonC, PersonA), but if I try rendering that in a template each persons comment_set will contain all their comments even if they aren't in the date range.
Ideally there would be some sort of functionality where I could expand out a Person
queryset's comment_set
into a larger queryset that can be sorted and ordered based on the comment and put into a object_list generic view. This normally is fairly simple to do in SQL with a JOIN, but I don't want to abandon the ORM, which I use everywhere else.
OK, my solution was basically just Comments.objects.filter(); split the template into a separate file that is included in the appropriate fashion开发者_如何学JAVA, apply extra context boolean (if comment_date_filter, apply an appropriate prefix string before all person references in the view (that's either '', or '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 %}
The other option you have is to pull all objects out as (Person, Date, Comment)
tuples and sort them in Python.
However, I don't know what your reason for not wanting to use Comment.objects.filter(). This is likely going to be fairly fast, especially if your date field is indexed.
精彩评论