Alter the list of fields returned by a queryset without turning them into strings?

7 views
Skip to first unread message

Joshua Russo

unread,
Sep 12, 2011, 9:41:49 PM9/12/11
to django...@googlegroups.com
I have 2 tables, document and event. I want to retrieve the document url and the event date but it seems like I can't do this in a single query set and that is then used directly in a template. This was my first thought:

context = {
        'minutes': Document.objects.filter(documentType=1, event__eventType=1).values('documentFile', 'event__start_date').order_by('event__start_date')
    }

with the template looking like 

{% for scm in minutes %}
    &sdot; <a target="belldocument" href="{{ scm.documentFile.url }}">{{ scm.event__start_date|optTimeShort }}</a><br>
{% endfor %}

The problem is that the values() command turns the FileField into a string.

If I remove the values() command I can access the event through event_set but it's not clear to me how to access the one and only event in the set within the template.

Do I just need to do a little more pre-processing in the view or can I accomplish what I'm trying to do?

Jacob Kaplan-Moss

unread,
Sep 12, 2011, 9:52:44 PM9/12/11
to django...@googlegroups.com
On Mon, Sep 12, 2011 at 8:41 PM, Joshua Russo <josh.r...@gmail.com> wrote:
> Do I just need to do a little more pre-processing in the view or can I
> accomplish what I'm trying to do?

The method you're looking for is ``only()`` (or perhaps its cousin,
``defer``): https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.only.

``only()`` takes a list of fields like ``values()``, and constrains
the SELECT clause similarly, but instead of returning a dictionary
returns a model instance, so things like the FileFile objects work
correctly.

Do note that if you use ``defer()``/``only()`` and the access a field
*not* in the select list Django will go perform another query for you,
thus making things less efficient. So only reach for ``only()`` when
you know you're only accessing the specific named fields (as it looks
like you are in your example).

Good luck,

Jacob

Joshua Russo

unread,
Sep 13, 2011, 10:18:29 PM9/13/11
to django...@googlegroups.com
So, how I actually solved it was even a bit different:

Document.objects.filter(documentType=1, event__eventType=1).annotate(Max('event__start_date')).order_by('event__start_date__max')

I had to use the Max function because the relationship is actually a many to many. Even if it was just a standard foreign key this is still an option, and it eliminates the problem of re-querying if you later decide to use other fields. 

Joshua Russo

unread,
Sep 13, 2011, 10:21:38 PM9/13/11
to django...@googlegroups.com
I had previously typed (but obviously not sent) a thank you ... so, thank you. That was what I was looking for and did lead me to my ultimate solution.
Reply all
Reply to author
Forward
0 new messages