Google Groups Home
Help | Sign in
Callable context variables do not get called during resolution.
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  9 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
Peter Rowell  
View profile
 More options May 9, 8:12 pm
From: Peter Rowell <hedron...@gmail.com>
Date: Fri, 9 May 2008 17:12:52 -0700 (PDT)
Local: Fri, May 9 2008 8:12 pm
Subject: Callable context variables do not get called during resolution.
Short version:

Callable context variables do not get called during resolution. If
invoked as a simple variable they return something like  <function foo
at 0x8c454fc>. If used in a for loop, they blow up the template. I'm
running trunk:7374

Longer version:

In order to delay a *very* expensive DB operation, I decided to put it
in a function and pass the function as a context variable. The
template uses fragment caching with vary_on, so only if the template
fragment is stale would the function be called and invoke the heavy
lifting.

Sounded great to me ... but it blows up with a 500 error.

Simple example:
=========================
def some_view(request):
   def foo():
      return [1, 2, 3]
   return render_to_response('some_template.html',  {'foo':   foo, })

some_template.html:
   {{foo}} ==>> yields <function foo at 0x8c454fc>
   {% for x in foo %}{{x}}{% endif %} ==>> 500 error

=========================

The problem seems to be in (or is related to)
template.__init__.Variable._resolve_lookup.

[...]
        current = context
        for bit in self.lookups:
            try: # dictionary lookup
                current = current[bit]
## the following fixed the problem (but needs error handling?)
                if callable(current):
                    current = current()
##
            except (TypeError, AttributeError, KeyError):
                try: # attribute lookup
                    current = getattr(current, bit)
                    if callable(current):
                        if getattr(current, 'alters_data', False):
                            current =
settings.TEMPLATE_STRING_IF_INVALID
                        else:
                            try: # method call (assuming no args
required)
                                current = current()
[...]

Note there is a check for callable, but only if it's a method. Is
there some reason why callability is OK in some context variables/
expressions and not others?


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Rowell  
View profile
 More options May 9, 8:23 pm
From: Peter Rowell <hedron...@gmail.com>
Date: Fri, 9 May 2008 17:23:39 -0700 (PDT)
Local: Fri, May 9 2008 8:23 pm
Subject: Re: Callable context variables do not get called during resolution.
BTW, I tried to add a comment on this to http://code.djangoproject.com/ticket/7153,
but got "Internal Server Error (Submission rejected as potential
spam)", which struck me as rather rude. :-)

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ionut Ciocirlan  
View profile
 More options May 9, 8:43 pm
From: Ionut Ciocirlan <ionut.ciocir...@gmail.com>
Date: Sat, 10 May 2008 03:43:40 +0300
Local: Fri, May 9 2008 8:43 pm
Subject: Re: Callable context variables do not get called during resolution.
On Saturday 10 May 2008 03:23:39 Peter Rowell wrote:
> BTW, I tried to add a comment on this to
> http://code.djangoproject.com/ticket/7153, but got "Internal Server Error
> (Submission rejected as potential
> spam)", which struck me as rather rude. :-)

I was just gonna point you to #7153.

I don't know why it was decided only object methods should be called. I'm
waiting for the review of the patch.

Regards


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Waylan Limberg  
View profile
 More options May 9, 8:44 pm
From: "Waylan Limberg" <way...@gmail.com>
Date: Fri, 9 May 2008 20:44:00 -0400
Subject: Re: Callable context variables do not get called during resolution.
On Fri, May 9, 2008 at 8:12 PM, Peter Rowell <hedron...@gmail.com> wrote:

[snip]
>  In order to delay a *very* expensive DB operation, I decided to put it
>  in a function and pass the function as a context variable. The
>  template uses fragment caching with vary_on, so only if the template
>  fragment is stale would the function be called and invoke the heavy
>  lifting.

[snip]

QuearySets are lazy and, as I understand it, don't get evaluated until
they are called in the template. Therefore, if a quearyset call is
wrapped in an if statement in the template that evaluates to false,
the query should never happen. What are you trying to accomplish that
is any different?

On Fri, May 9, 2008 at 8:23 PM, Peter Rowell <hedron...@gmail.com> wrote:

>  BTW, I tried to add a comment on this to http://code.djangoproject.com/ticket/7153,
>  but got "Internal Server Error (Submission rejected as potential
>  spam)", which struck me as rather rude. :-)

Well, spam littered tickets would be worse. It's the lesser of two
evils. You can register [1] for an account and bypass the spam filter
-- Or, if you don't what to register, create a session [2] to get the
spam filter to go easy on you.

[1]: http://www.djangoproject.com/accounts/register/
[2]: http://code.djangoproject.com/settings

--
----
Waylan Limberg
way...@gmail.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Rowell  
View profile
 More options May 9, 10:01 pm
From: Peter Rowell <hedron...@gmail.com>
Date: Fri, 9 May 2008 19:01:04 -0700 (PDT)
Local: Fri, May 9 2008 10:01 pm
Subject: Re: Callable context variables do not get called during resolution.

> QuerySets are lazy [...] What are you trying to accomplish that is any different?

I'm working around the fact that Django's templates can't take
arguments. So I'm calling formatting functions which *do* take
arguments, one of which is a QuerySet. Of course, I can't pass args to
a function in the template system, so to avoid premature evaluation of
the expensive large-query/format I'm currying the function and trying
to pass *that* as a context variable. And that's when it hit the fan.

<rant>

After this site I swear I'm going with either Jinja2 or Mako
templates. I'm all for not confusing non-programming designers with
nasty programming concepts, but my very good designer runs screaming
from the room when I try to teach her the simplest template things.
Therefore, I'm the one having to deal with the crippled templating
system. It's great to keep app-logic out of the templates, but Django
makes a lot of *presentation logic* almost impossible (or extremely
clumsy) to implement. "ifequal foo bar" instead of "if foo == bar"?
With a different end tag? Can't combine and's and or's in a single if?
Give me a break.

Now that Malcolm has subclassable models working, my number one
complaint is the templating system. Number two is single DB, but I can
work around that more easily.

</rant>


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Bennett  
View profile
 More options May 9, 10:05 pm
From: "James Bennett" <ubernost...@gmail.com>
Date: Fri, 9 May 2008 21:05:06 -0500
Local: Fri, May 9 2008 10:05 pm
Subject: Re: Callable context variables do not get called during resolution.

On Fri, May 9, 2008 at 9:01 PM, Peter Rowell <hedron...@gmail.com> wrote:
> Now that Malcolm has subclassable models working, my number one
> complaint is the templating system. Number two is single DB, but I can
> work around that more easily.

You probably should take a look at the ORM code.

--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Rowell  
View profile
 More options May 9, 10:27 pm
From: Peter Rowell <hedron...@gmail.com>
Date: Fri, 9 May 2008 19:27:41 -0700 (PDT)
Local: Fri, May 9 2008 10:27 pm
Subject: Re: Callable context variables do not get called during resolution.

> You probably should take a look at the ORM code.

OK, I'll bite. I kind of doubt he rewrote the templating system in the
ORM, so you must be inferring that multiple database support was part
of the qs-refactoring. I just checked out trunk and I'll admit I'm
working with a one-beer-handicap at the moment, but nothing jumped out
and said "MULTIPLE DATABASE SUPPORT!!!"

Please, make my day.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Bennett  
View profile
 More options May 9, 10:47 pm
From: "James Bennett" <ubernost...@gmail.com>
Date: Fri, 9 May 2008 21:47:15 -0500
Local: Fri, May 9 2008 10:47 pm
Subject: Re: Callable context variables do not get called during resolution.

On Fri, May 9, 2008 at 9:27 PM, Peter Rowell <hedron...@gmail.com> wrote:
> OK, I'll bite. I kind of doubt he rewrote the templating system in the
> ORM, so you must be inferring that multiple database support was part
> of the qs-refactoring. I just checked out trunk and I'll admit I'm
> working with a one-beer-handicap at the moment, but nothing jumped out
> and said "MULTIPLE DATABASE SUPPORT!!!"

Once again, there's no high-level support, but qsrf added some
infrastructure which will make an eventual high-level implementation
easier, and which makes writing a manual implementation right now a
bit less tedious. Look at the constructor of
django.db.models.sql.query.Query for the "connection" argument.

--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Peter Rowell  
View profile
 More options May 9, 11:39 pm
From: Peter Rowell <hedron...@gmail.com>
Date: Fri, 9 May 2008 20:39:52 -0700 (PDT)
Local: Fri, May 9 2008 11:39 pm
Subject: Re: Callable context variables do not get called during resolution.

> Look at the constructor of django.db.models.sql.query.Query for the "connection" argument.

You know, I grepped on that but didn't see anything interesting. Now
with a two-beer-handicap, I'll go with Blanche DuBois -- Tomorrow is
another day.

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2008 Google