Opened 18 years ago

Closed 18 years ago

#2351 closed defect (fixed)

MySQL syntax error on object.all().count(), when called from template

Reported by: gumuz Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version:
Severity: normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a blogpost model which is referenced by a Comment class. Thus, the Blogpost model has a comment_set attribute.

I gave the Blogpost model a method like this:

def comments(self):
    return self.comment_set.all()

When i access it from the shell and use the .count() method on the QuerySet, everything is fine:

>>> from devlog.weblog.models import Post
>>> p = Post.objects.all()[4]
>>> p.comments()
[<Comment: gumuz - 2006-07-12 07:10:30>, <Comment: gumuz - 2006-07-12 07:09:56>]
>>> p.comments().count()
2L

When i do the same from my template:

{{ object.comments.count }}

I get the following error:

Exception Type:  	ProgrammingError
Exception Value: 	(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'count,1' at line 1")
Exception Location: 	/usr/lib/python2.4/site-packages/MySQLdb/connections.py in defaulterrorhandler, line 33

The length-filter works fine though:

{{ object.comments|length }}

Attachments (3)

diff_fix_queryset_getitem.txt (756 bytes ) - added by marcin@… 18 years ago.
backtrace_short.txt (1.4 KB ) - added by marcin@… 18 years ago.
backtrace_detailed.txt (12.9 KB ) - added by marcin@… 18 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 by racter@…, 18 years ago

this error only happens for me when nesting -- ie if i try:

{% for object in category.object_set.all %}
{{ object.subobject_set.count }}
{% endfor %}

i get the same error.

comment:2 by Jonas von Poser, 18 years ago

I get the same error. count fails from template but |length works fine.

comment:3 by Michael Radziej <mir@…>, 18 years ago

Please, send the full bracktrace.

by marcin@…, 18 years ago

comment:4 by marcin@…, 18 years ago

Has patch: set

I just ran into the same problem with Postgresql.

The cause is a bug in QuerySet.getitem: it assumes that the parameter it gets is either a slice or an integer, but does not really check the latter. When you put {{ somequeryset.qwe }} in your template and template.resolve_variable tries to resolve it using a dictionary lookup, QuerySet.getitem treats qwe like an integer index, which results in queries ending with "limit 1 offset qwe".

The attached patch fixes the problem.

comment:5 by mir@…, 18 years ago

It would be rather nice if someone posts the full backtrace. I personally refuse to triage a bug report without the full information, and it's rather tedious to reconstruct the problem when you're dealing with a lot of tickets.

by marcin@…, 18 years ago

Attachment: backtrace_short.txt added

by marcin@…, 18 years ago

Attachment: backtrace_detailed.txt added

comment:6 by marcin@…, 18 years ago

mir: here you are. Note the resulting SQL query at the end.

All the interesting parts of code:

models.py:

    class Article(models.Model):
        text = models.TextField()

urls.py:

    urlpatterns = patterns('',
        (r'^$', 'django.views.generic.simple.direct_to_template',
         {'extra_context': {'object_list': Article.objects.all()},
          'template': 'index.html'}),
    )

index.html:

{{ object_list.count }}

I tried to attach the detailed backtrace in HTML, but Akismet said it was spam.

comment:7 by Chris Beaven, 18 years ago

Needs tests: set
Triage Stage: UnreviewedAccepted

I'll accept. Probably could do with some tests showing the failure.

comment:8 by Noah Slater <nslater@…>, 18 years ago

I can confirm identical behaviour.

comment:9 by James Bennett, 18 years ago

#2945 was a duplicate of this one.

comment:10 by James Bennett, 18 years ago

And for the record, #2945 has a full traceback of this bug. And I've seen it happen on SQLite as well.

comment:11 by Malcolm Tredinnick, 18 years ago

Resolution: fixed
Status: newclosed

(In [4772]) Fixed #2351 -- Fixed problem with using ".count" attribute of QuerySets in
templates.

Note: See TracTickets for help on using tickets.
Back to Top