View referenced by two urls and url tag - django

I am using url tag in my template for a view, that is used by two different urls. I am getting the wrong url in one place. Is there any way to force django to retrieve different url? Why it doesn't notify my, that such conflict occured and it doesn't know what to do (since python zen says, that is should refuse temptation to guess).
Code in template:
{% url djangoldap.views.FilterEntriesResponse Entry=entry.path as filter_url %}
Code in urls:
(r'^filter_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'filter_entries.html',
'results_template': 'filter_results.html'}),
(r'^choose_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'search_entries.html',
'results_template': 'search_results.html'}),
As you can see, those two urls use the same view, but with different templates. How I can force django to retrieve former url, rather than latter?

Name your URLs by adding another item to the tuple:
(r'^choose_entries/(?P<Entry>.*)/$',
'djangoldap.views.FilterEntriesResponse',
{'filter_template': 'search_entries.html',
'results_template': 'search_results.html'},
'sensibleprefix-choose_entries') # <-- this is the name
Then you can use the name in the URL tag.

Related

django url concatenation. I don't want to concatenate

when I do something in 'profile' page,
the url is concatenated to the next of 'profile'.
but I want to link to just 'signout'. not 'profile/signout'
this is my urls.py.
when ever I do something in 'profile'page,
the href link is concatenated to 'profile'url.
this is href source.
since this href source is header.html,
this page is included another pages.
and in the other pages, it works well.
only in profile page, the href url is concatenated to 'profile/1' url.
how can I fix it?
Yes, a URL not starting with a slash or a scheme is a relative URL. href="foo" is equivalent to href="./foo", i.e. it refers to the path foo relative to the current path. If you want the top-level path, you want href="/foo".
In Django you're supposed to use the {% url %} template tag to generate URLs, you don't hardcode them. Django will take care to generate the correct URL; especially if you move the app around to other environments, the URL may require a prefix or such, so you should never hardcode the URL.

Is there a way to apply a filter to a URL generated with the URL tag in Django?

For part of my user interface I need a URLencoded URL.
This code doesn't work, but it's intended to give an impression of what I'd like to do:
{% url 'team_event_calendar' id=team.id | urlencode %}
Basically, get a particular URL - in this case "team_event_calendar" for a particular team, and then URLencode it.
I suppose I could make a new version of the URL tag which URLencodes everything, but is there a way to do it with just Django's built-in tags?

Add url parameters to a url in django view

I have a django view that lists several urls on external sites.
When I render them I would like to add a few url parameters to each.
These urls are to an external system and thus not listed in my urls.py. Furthermore, some of the links have a hash '#' so it is not as easy as appending a few parameters to the end of the string.
Based on these requirements it seems the url template tag will not be a good fit. I was wondering if there is a custom filter out that to do this.
You don't need Django's url tag here. The url tag is to resolve to URLs that belong to your application.
However, there is the nice django-spurl library. It allows you to handle query parameters via template tags.
An example from the documentation to add query parameters:
{% spurl base="http://example.com/?foo=bar" add_query="bar=baz" %}
<!--
will result in: http://example.com?foo=bar&bar=baz
-->

Is it possible to give external URLs names in django

I have just started naming my URL patterns in Django, so that if I want to change the URL pattern, I just have to change it in one place. e.g:
url(r'^$', HomeListView.as_view(), name='home'),
And referencing it in my templates like this:
{% url home %}
Is this possible with external links in case they change or I change the a Facebook page link for example. How would this look?
Thanks
One way to do this could be to write an external_url template tag, and have an ExternalURL model that stores them.
This would give you the advantage of being able to have the urls editable without redeploying changed code.
The disadvantage is that there will be database lookups to see those urls. Also, you would need to {% load external_urls %} in templates you want to use it in.
# models.py pseudo-code
class ExternalURL(models.Model):
name = models.CharField(unique=True)
url = models.URLField()
Your template tag might look something like:
# app/templatetags/external_url.py
#library.register()
def external_url(name):
try:
return ExternalURL.objects.get(name=name).url
except ExternalURL.DoesNotExist:
return ''
Another alternative could be to have a Context Processor that stores them all in the context, allowing you to not have to pass them explicitly into views: would be useful if you had several external urls that were used in many places within your system.
def external_urls(request):
return {
'google': 'http://www.google.com/',
# more here
}
The advantages of this is no database lookup, no requirement to load the template tag, but you will need to add it to your settings.CONTEXT_PROCESSORS. Also, you could inspect request to see if the current user may see all the urls.
If its external links, and possibility of the change then you should define it in settings or separate static url file and pass those variable with request context.
urls.py should be recommended to use only for your app specific urls.
In this SO thread you can see how to approach defining constant

New url syntax from django 1.3/dev onwards

Why did the django core developers allow the url templatetag to point directly to a django view function? (reference - https://docs.djangoproject.com/en/dev/ref/templates/builtins/#url)
{% load url from future %}
{# 1st method: pointing to a view function #}
{% url 'app_views.client' %}
{# 2nd method: pointing to a named url #}
{% url 'myapp:view-name' %}
One can already name the url in urls.py and hence use the 2nd method to point to a specific url. It doesn't feel right to allow developers to actually reference a view function directly from the template.
Does anyone know why this decision was made?
Passing a dotted view function name to the {% url %} template tag is simply the form the template tag took in the earlier days of Django, before you could name URLs. It's still supported, though as you point out, you probably wouldn't use it in a modern application.
URLs in Django are just mappings to views. Therefore, in the template, using a named URL is just indirectly referencing the view anyway.
The exception is where a single view is mapped to by multiple URLs.
Also note that they are planning to change the syntax of the url tag in 1.5. It will take a context variable as the parameter, rather than a string. It will still take views or named URLs though.