Django - Why url namespaces? - django

I've been learning Django for sometime now. I came across url reverse, understood most of it but couldn't understand namespaces:
1. How is it useful ?
2. How to use it ?
It is poorly documented and I've not found any decent article on it. :(
Also could someone explain how to reverse included urls??

i found a good solution here
Anyone knows good Django URL namespaces tutorial?
Disclaimer : This is written by David Eyk on above mentioned link
Agreed, the docs for this are rather confusing. Here's my reading of it (NB: all code is untested!):
In apps.help.urls:
urlpatterns = patterns(
'',
url(r'^$', 'apps.help.views.index', name='index'),
)
In your main urls.py:
urlpatterns = patterns(
'',
url(r'^help/', include('apps.help.urls', namespace='help', app_name='help')),
url(r'^ineedhelp/', include('apps.help.urls', namespace='otherhelp', app_name='help')),
)
In your template:
{% url help:index %}
should produce the url /help/.
{% url otherhelp:index %}
should produce the url /ineedhelp/.
{% with current_app as 'otherhelp' %}
{% url help:index %}
{% endwith %}
should likewise produce the url /ineedhelp/.
Similarly, reverse('help:index') should produce /help/.
reverse('otherhelp:index') should produce /ineedhelp/.
reverse('help:index', current_app='otherhelp') should likewise produce /ineedhelp/.
Like I said, this is based on my reading of the docs and my existing familiarity with how things tend to work in Django-land. I haven't taken the time to test this.

Related

In Django, how do I get the name of the pattern that was followed for a particular URL within a template?

I have been doing lots of Googling on this topic and have gone through plenty of Django docs, but I can't seem to find a decent answer to what seems like ought to be a very simple question with a simple solution. So hopefully a Django vet out there can help.
Lets say I have the following urlconf:
urlpatterns = patterns('',
....
url(r'^directory/users/$', UserView.as_view(), name='users'),
url(r'^directory/users/(?P<user_id>[0-9]+)/$',UserView.as_view(), name='users'),
....
)
What I want to be able to do is test from within a template which pattern was followed, something like this:
{% if name_of_last_followed_url_pattern == 'users' %}
....
{% endif %}
Now one would think that Django would stash this away somewhere and be able to spit it back out to me. But I cannot find anything that corresponds to "name_of_last_followed_url_pattern" anywhere in the docs or in my searches. Any ideas how I might access this (or if not provided, why not)?
You need the context processors that adds the request to the template django.core.context_processors.request added to the TEMPLATE_CONTEXT_PROCESSORS. Then in the template you can do
{% if request.resolver_match.url_name == 'users' %}
....
{% endif %}
resolver_match has other attributes like namespaces, app_name. You can see here:
https://docs.djangoproject.com/en/1.6/ref/urlresolvers/#django.core.urlresolvers.ResolverMatch

regex in Django urls.py

Help me please to fix urls.py
People suggested this way, but it does't work for me.....
#urls.py
(r'^/user/(?P<username>)/subject/([\w|\W]+)/$', subject),
#template
{% for subject in subjects %}
<li>{{ subject.name }} {{ del_form.delete }}</li>
{% endfor %}
#error
PAGE NOT FOUND
Request URL: http://127.0.0.1:8000/user/root/subject/Math%20140
....
....
^/user/(?P<username>)/subject/([\w|\W]+)/$
You have an error in your regular expression. You should use a regex builder if you are new to this:
http://ryanswanson.com/regexp/ (Perl)
http://www.pyregex.com/ (Python)
I think you want something like this:
^user/(?P<username>.+)/subject/([\w|\W]+)/
But you might want to change the '.+' to something more restrictive:
^user/(?P<username>[^/]+)/subject/([\w|\W]+)/
Note also that you probably don't want that leading slash - due to the way Django feeds the initial URL to the URL dispatcher.

{% url %} gives me NoReverseMatch error while reverse() returns the url just fine. Why?

I don't know if this SO question is of the same problem that I am about to describe, but it does share the same symptoms. Unfortunately, it still remains unresolved as I am writing.
So here is my problem. I am trying to add James Bennett's django-registration app to my django project. I have pretty much finished configuring it to my needs - custom templates and urls. Just when I thought everything was good to go. I got NoReverseMatch error from using {% url 'testing' item_id=123 %} (I also tried using the view name, myapp.views.test, instead but no luck) in one of the custom templates required by django-registration. Interestingly, I tried reverse('testing', kwargs={'item_id':123}) in the shell and the url was returned just fine. I thought {% url %} uses reverse() in the back-end but why did I get different outcomes?
urls.py: (the URLconf of my site)
urlpatterns = patterns('myapp.views',
url(r'^test/(?P<item_id>\d+)/$', 'test', name='testing'),
)
activation_email.txt: (the said template. Note it's intentionally in .txt extension as required by django-registration and that shouldn't be the cause of the problem.)
{% comment %}Used to generate the body of the activation email.{% endcomment %}
Welcome to {{ site }}! Please activate your account by clicking on the following link:
{% url 'testing' item_id=123 %}
Note the activation link/code will be expired in {{ expiration_days }} days.
I don't know if it matters but just thought I should mention activation_email.txt is stored in the templates directory of myapp though it is used by django-registration.
Also, I am using django 1.4
I have a feeling that the problem has something to do with the url namespaces, a topic that I have never understood, but it's just a naive guess. (IMO, the django documentation is great in explaining everything about django, except when it comes to url namespaces)
I'm no expert here, but in a Django project I'm working on at the moment I use the name of the url without quotes. I just added quotes around a similar line in one of my templates and it produced the same error as your error.
Try:
{% url testing item_id=123 %}

How to use namespace urls with django in a reusuable app

I have a django app, a forum app, that has templates with it. In those templates, there are urls that point to parts of the app. For instance the thread_list template has links to each thread like so:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
The thing is, I don't really like calling my urls "forum_thread". I prefer just "thread" and using the namespace feature of django. "forum_thread" may be used somewhere else in the project (namespace collision).So it will look like this:
{% for thread in threads %}
{{thread.title}}
{% endfor %}
but this doesn't feel like the correct way to do this. The docs are kind of unclear here.
I want this app to be reusable and easy to configure. But I also want to use the best standards. I don't want to have the to make the user specify their own namespace name, and then have them edit every single url in each template.
How should I do urls in this app?
From what I can gather you should be able use {% url forum:thread thread %} as you've described. Namespaces always seem to be defined with two variables, namespace and app_name.
If you then do the following in urls.py:
url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')),
url(r'^/foo/', include('forum.urls', namespace='foo', app_name='forum')),
url(r'^/bar/', include('forum.urls', namespace='bar', app_name='forum')),
In my understanding, this defines 3 instances of the app 'forum', 'foo', 'bar', and the default (which has namespace==app_name).
When you reverse forum:thread, it uses the current context to determine which one to use- if you are in namespace 'foo' it will use that, otherwise it will fall back on the default.
If anyone is able to clarify how Django decides what the 'current' namespace/app is that would be very helpful. I currently categorise it as 'black magic'.
Some clarification on the actual difference between namespace and app_name would also be helpful- it's possible that I have this totally reversed. The current docs are highly ambiguous.
Note: I have this working for initial requests, but I'm currently unable to make this work for AJAX requests- those always use the default instance for some reason.
This might be a simple syntax error. I was following the Django Tutorial, and I changed mysite/urls.py improperly. The original syntax:
url(r'^polls/', include('polls.urls')),
The desired change:
url(r'^polls/', include('polls.urls', namespace="polls")),
What I did:
url(r'^polls/', include('polls.urls'), namespace="polls"),
Correcting the syntax resolved the issue.
based on my understanding of this question:
in Django 2.1.7
You can app name in app's urls.py file
# app's urls.py
from django.urls import path
from . import views
app_name = 'forum'
urlpatterns = [
path('thread/', views.mark_done, name='thread')
]
in main urls.py
# urls.py
....
urlpatterns = [
path('forum/', include('forum.urls')),
]
then you can employ {% url 'forum:thread' %} in your template
If you wanna use it in a for loop
I think we should
create a view return all threads as context
then add a path to that view
...
path('thread/<int:pk>', views.mark_done, name='thread')
the url in template will like:
{% for thread in threads %}
{{thread.title}}
{% endfor %}

Django url template tage and variable values with dot (.)

why doesn't {% url myVar %} where myVar = 'jack.johnson' doesn't work ?
The view is fine, the urls.py is:
url(r'^(?P[A-Za-z0-9-._]+)/$', overview, name='user_profile'),
Because the URL name is 'user_profile', not 'jack.johnson'.
Confirm that you're using at least Django 1.0 (named url patterns didn't exist before then), re-read the Django doc on Naming URL Patterns, then try
{% url user_profile myVar %}
guys, sorry. I found my mistake and the example I gave was misleading.
Thanks for the quick response.