How to pass url parameters to template url tag

7,927 views
Skip to first unread message

Kayode Odeyemi

unread,
Aug 10, 2011, 10:17:30 AM8/10/11
to django-users
Hello friends,

I need some help on how to pass url parameters to template url tag.

Something like this:

<a href="{% url reverse-url-fn request.GET.get('page', '')%}">my page</a>

page is the url parameter I want to get

Thank you

--
Odeyemi 'Kayode O.
http://www.sinati.com. t: @charyorde

Tom Evans

unread,
Aug 10, 2011, 10:30:08 AM8/10/11
to django...@googlegroups.com
On Wed, Aug 10, 2011 at 3:17 PM, Kayode Odeyemi <dre...@gmail.com> wrote:
> Hello friends,
> I need some help on how to pass url parameters to template url tag.
> Something like this:
> <a href="{% url reverse-url-fn request.GET.get('page', '')%}">my page</a>
> page is the url parameter I want to get
> Thank you

You have two options:

you can extract the value in the view, and put it into the context
that is used to render the template.

you can access it using dot notation [1], which is used in templates
(templates are not python, you cannot write python in templates). Eg:
{% url url-name request.GET.page %}

Cheers

Tom

[1] https://docs.djangoproject.com/en/1.3/topics/templates/#variables

Reinout van Rees

unread,
Aug 10, 2011, 10:35:45 AM8/10/11
to django...@googlegroups.com
On 10-08-11 16:17, Kayode Odeyemi wrote:
> I need some help on how to pass url parameters to template url tag.
>
> Something like this:
>
> <a href="{% url reverse-url-fn request.GET.get('page', '')%}">my page</a>
>
> page is the url parameter I want to get

Best solution: calculate that url in your python view code and just pass
it along in the context.

The generic rule is that most processing should happen in python code,
not in your template.

Reinout

--
Reinout van Rees http://reinout.vanrees.org/
rei...@vanrees.org http://www.nelen-schuurmans.nl/
"If you're not sure what to do, make something. -- Paul Graham"

bruno desthuilliers

unread,
Aug 10, 2011, 1:57:52 PM8/10/11
to Django users
On 10 août, 16:30, Tom Evans <tevans...@googlemail.com> wrote:
>
> You have two options:

Actually, three.

> you can extract the value in the view, and put it into the context
> that is used to render the template.

Simple but totally unpractical for most projects, as it requires
making ALL views duplicating this behavior.

> you can access it using dot notation [1], which is used in templates
> (templates are not python, you cannot write python in templates). Eg:
> {% url url-name request.GET.page %}

Probably the most cost-effective solution - until you have to parse
all your templates when there's any change. As a side note:
1/ you can use the "default" template filter to handle the case when
there's no 'page' key in request.GET
2/ you can use request.REQUEST if you want to work as well with GET
and POST.


Now for the third solution: write your own template tag. Not
necessarily required, but that's often the best solution wrt/
decoupling / flexibility / maintainability / reusability.

bruno desthuilliers

unread,
Aug 10, 2011, 2:06:07 PM8/10/11
to Django users
On 10 août, 16:35, Reinout van Rees <rein...@vanrees.org> wrote:
>
> Best solution: calculate that url in your python view code and just pass
> it along in the context.

Definitly not the best solution if this has to work for more than
exactly ONE view.

> The generic rule is that most processing should happen in python code,
> not in your template.

Indeed. But in Django, Python code is not restricted to views, and
another generic rule is that a view should NOT have to deal with
orthogonal concerns - IOW, it should do the very minimal possible
thing and nothing else. Template code is where the integration
between different (preferably well decoupled) apps happens - it's
really the "glue" layer of your project - so whatever is part of your
project but none of the concern of a specific view should happen. NB :
when I say "template code", this includes template tags and filters,
context processors and eventually middlewares...

Kayode Odeyemi

unread,
Aug 10, 2011, 3:52:13 PM8/10/11
to django...@googlegroups.com
I've been considering using custom template tag. Yeah, it is standard and pretty. I guess
this might take me a while to implement.

However, can this concept also be used to pass page objects (e.g model data 
passed to a template from a view) from one view to another. 

For instance, I have a request model dynamic data saved in a session. I'm passing this
data to another view and I want it to change based on the value of a url parameter?

 

bruno desthuilliers

unread,
Aug 10, 2011, 5:37:39 PM8/10/11
to Django users
On 10 août, 21:52, Kayode Odeyemi <drey...@gmail.com> wrote:
> On Wed, Aug 10, 2011 at 6:57 PM, bruno desthuilliers <
>
> bruno.desthuilli...@gmail.com> wrote:
> > On 10 août, 16:30, Tom Evans <tevans...@googlemail.com> wrote:
>
> > Now for the third solution: write your own template tag. Not
> > necessarily required, but that's often the best solution wrt/
> > decoupling / flexibility / maintainability / reusability.
>
> I've been considering using custom template tag. Yeah, it is standard and
> pretty. I guess
> this might take me a while to implement.

Well, the first time, yes, possibly. But that's not rocket science
neither, and that's something anyone whishing to make proper use of
Django should learn.

> However, can this concept also be used to pass page objects (e.g model data
> passed to a template from a view) from one view to another.

You don't pass anything from "one view to another". You eventually
pass data from a request to another, using either request params
(querystring, post...), cookies, or sessions (and of course the parts
of your urls that become view args).

> For instance, I have a request model dynamic data

Sorry, but I don't know what a "request model dynamic data" is
supposed to be. Care to explain more clearly ?

Tom Evans

unread,
Aug 11, 2011, 4:52:07 AM8/11/11
to django...@googlegroups.com
On Wed, Aug 10, 2011 at 7:06 PM, bruno desthuilliers
<bruno.des...@gmail.com> wrote:
> On 10 août, 16:35, Reinout van Rees <rein...@vanrees.org> wrote:
>>
>> Best solution: calculate that url in your python view code and just pass
>> it along in the context.
>
> Definitly not the best solution if this has to work for more than
> exactly ONE view.
>

So instead of typing this in multiple views:

context['some_var'] = request.GET.get('name')

is somehow more effort than typing this in multiple templates:

{% url foo request.POST|mycustomattrgetter:"name" %}

The template code could be inherited, but then placing the variable in
a context could also be done by a template context processor. Where
you have many views that require the same context variables, this is
easier imo.

Remember that you can pass a custom list of template context
processors to a render_to_foo() call, in addition to
settings.TEMPLATE_CONTEXT_PROCESSORS.

Cheers

Tom

Kayode Odeyemi

unread,
Aug 11, 2011, 5:27:41 AM8/11/11
to django...@googlegroups.com
I meant a paginated model rendered in a view. Something like:
 
def func(request, **kwargs):
    obj = Model.objects.all()
    SHOW_CONTENT_LIMIT = 2
    paginate_list = Paginator(dataqs, SHOW_CONTENT_LIMIT)
    page_no = int(request.GET.get(u'page', 1))
    contents = paginate_list.page(page_no)
    ...
    ...
    #make a dict of the page number and it's content
    x = {contents.number:contents.object_list}

    #store it in a session
    request.session['contents'] = x
    return render_to_response('template.html', {'contents', contents}, context_instance=RequestContext(request));

def func2(request, **kwargs):
    page = int(request.GET.get('page'))
    # retrieve a slice of the session data by page
    request.session['contents'][page]

    #write to csv
    ...
    
    return HTTPResponse
    

So I'm thinking, wouldn't it be pretty to create a template tag that can make 
the current session object available to the view - a concept similar to JSTL tag.
Is this something template tags can be useful - making standard Python objects 
available to templates right?

Kayode Odeyemi

unread,
Aug 11, 2011, 5:33:29 AM8/11/11
to django...@googlegroups.com
On Thu, Aug 11, 2011 at 9:52 AM, Tom Evans <teva...@googlemail.com> wrote:
On Wed, Aug 10, 2011 at 7:06 PM, bruno desthuilliers
> On 10 août, 16:35, Reinout van Rees <rein...@vanrees.org> wrote:
>>
>> Best solution: calculate that url in your python view code and just pass
>> it along in the context.
>
> Definitly not the best solution if this has to work for more than
> exactly ONE view.
>

So instead of typing this in multiple views:

context['some_var'] = request.GET.get('name')

is somehow more effort than typing this in multiple templates:

{% url foo request.POST|mycustomattrgetter:"name" %}

The template code could be inherited, but then placing the variable in
a context could also be done by a template context processor. Where
you have many views that require the same context variables, this is
easier imo.

Yes I agree. Could you please explain the role of the filter here?

Thanks
 
Reply all
Reply to author
Forward
0 new messages