Consider that I include namespaced reusable application:
urlpatterns = patterns('',
# ella urls
url('^ella/', include('ella.core.urls', namespace="ella")),
)
Now, the Ella applications has urls like that:
urlpatterns = patterns( '',
url( r'^(?P<category>[a-z0-9-/]+)/$', category_detail, name="category_detail" ),
# object detail
url( r'^(?P<category>[a-z0-9-/]+)/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<content_type>[a-z0-9-]+)/(?P<slug>[a-z0-9-]+)/$',
object_detail, name="object_detail" )
)
Now, calling {% url ella:category_detail category="cat" %} works fine. However, when object tries to generate link to it's details, it calls
from django.core.urlresolvers import reverse
url = reverse('object_detail', kwargs={'required' : 'params'})
This is not working, unless rewritten as
from django.core.urlresolvers import reverse
url = reverse('ella:object_detail', kwargs={'required' : 'params'})
So, if I understand it correctly, including reusable application into namespace breaks all inner reverse()s inside given application.
Is it true? What have I missed? Is there any way around?
Since you have name-spaced url configuration, you need to mention namespace:view-name pattern in order to reverse it properly (especially from view).
But, if you want to avoid this, you may also pass namespace/appname as current_app parameter.
There are multiple ways to specify current_app when you are in template. But if you are in view, you need to hard-code as you did, or pass to current_app parameter
url = reverse('object_detail',
kwargs={'foo':'bar'},
current_app=app_name_or_name_space)
refer: http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
URL Namespaces can be specified in two ways.
Firstly, you can provide the application and instance namespace as arguments to include() when you construct your URL patterns. For example,:
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
This is right from http://docs.djangoproject.com/en/dev/topics/http/urls/#defining-url-namespaces.
Try changing include('ella.core.urls', namespace="ella") to include('ella.core.urls', namespace="ella", app_name="ella"). I'm not 100% this will work, but its worth a shot.
At least in Django 1.8 you can write something like this:
url = reverse('%s:object_detail' % request.resolver_match.namespace, kwargs={'required' : 'params'})
request.resolver_match.namespace is a string containing the namespace of the currently running view.
Related
Suppose I have this:
from django.core.urlresolvers import reverse
url = reverse('account-list')
Assume this leads to the URL: `/account/list/'
How do I add on to the URL? I want to make that URL this: /account/list/1 (adding a pk value to the end of it). I know over here: Including a querystring in a django.core.urlresolvers reverse() call it explains how to add GET parameters (e.g. ?pk=1 but I want to know if there is a proper way for me to add on to the URL (not using GET parameters)).
I'm using DRF routers: router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) and the user-detail view takes a pk value. So I want to do url = reverse('user-list') with /1 appended to the end of it.
If you are interested specifically in the detail view then you shouldn't use account-list. Assuming you have a separate account-detail view (Django Rest Framework will create these for you as well when you are using default ModelViewSets, just the same as it did with account-list):
from django.core.urlresolvers import reverse
u = reverse('account-detail', args=[1])
would be the proper way to go about this if I understand your question correctly.
You can also handle named URL parameters. For the following URL rule with a slug parameter:
url(r'/accounts/(?<slug>[a-fA-F0-9]+)/', name='account-detail', ...)
here's how you'd reverse the detail view for the account with a slug equal to something:
from django.core.urlresolvers import reverse
u = reverse('account-detail', kwargs={'slug': 'something'})
Django newbie here, need help on basic middleware to redirect to another view if a certain model field is empty.
I am creating a terms of agreement page that users must get redirected to right after they signup to the platform if their filed_terms field on their Profile model is empty.
I am using middleware for this. However I am unable to get this to work. This is my middleware class:
class TermsMiddleware(object):
def process_request(self, request):
if request.user.profile.filled_terms is None:
return redirect(reverse(terms))
This gives me the following error:
global name 'terms' is not defined
I also have the url matcher that works perfectly when I navigate to it manually:
url(r'^terms/', 'my_app.views.terms')
I have a terms.html template and a terms view in my views.py file that is working perfectly in all other respects. I have also added it to the settings middleware requirements to make sure it loads.
Do I have to import something from views or url dispatcher into my middleware file? If so what would that be? I have been at this for a while an cannot find anything helpful.
reverse function takes url name instead on the regex. So you need to add name on your url configuration. Here is the example.
url(r'^terms/', 'my_app.views.terms', name='terms')
Add this in your views.py
from django.core.urlresolvers import reverse
And you need to fix your reverse function into.
return redirect(reverse('terms'))
Python interpret your terms as a variable and you have no variable named terms while you need to put string on reverse.
I am using allauth and after registration the user receives an email asking them to click a link to verify their email address. I would like to change the value of this link.
I would like to change it from
http://localhost:8001/account/confirm-email/hy72ozw8b1cexuw2dsx4wwrmgzbmnyxx4clswh67tcvgyovg/
to
http://localhost:8001/index.html#/verifyEmail/hy72ozw8b1cexuw2dsx4wwrmgzbmnyxx4clswh67tcvgyovg/
How can I do this? I see that activate_url value is being used in email_confirmation_text.txt
You don't really have to override allauth's urls.py in order to achieve this, all you need to do is specify your version of url after including allauth's urls:
from django.conf.urls import patterns, include, url
from allauth.account.views import confirm_email
urlpatterns = patterns('',
...
url(r'^accounts/', include('allauth.account.urls')),
url(r'^index.html#/verifyEmail/(?P<key>\w+)/$', confirm_email,
name="account_confirm_email"),
# but I would recommend changing that url:
url(r'^verify-email/(?P<key>\w+)/$', confirm_email,
name="account_confirm_email"),
...
)
Here is a nice article about URLS: Cool URIs don't change
I have not used django-allauth or incorporated it into one of my projects, but just poking around in their source code tells me the following:
The send method just does a basic urlresolvers.reverse call, which means it's constructing the URL from account/urls.py as defined here.
As such, you have three options:
Overwrite their urls.py which you will have to repeat each time you update the package (yuck).
Raise an issue on their GitHub and see if they will add this as a configuration option rather than "hard-coding" it which they have done.
Try to subclass their EmailConfirmation model, overriding their send method with something more appropriate for your project, and see if you can get it to use yours instead of theirs (no idea if this is workable or not).
I am trying to dynamically generate links in my template of the form ..../hub/username/ but am always getting back only ..../hub for some reason. I have read through the docs several times and it seems very clear what to do, but I am just making some mistake somewhere I suppose!
Please Help!
I have in my urls:
urlpatterns = patterns(
'',
url(r'^hub/(.+)/$', 'hub.views.hub_view', name="hub"),
...
...
)
I have in my template:
<li><a id="todoMenuButton" href="{% url 'hub' user.username %}">ToDo</a></li>
template context preprocessors is enabled in my settings:
TEMPLATE_CONTEXT_PROESSORS = (
'django.core.context_processors.request',
)
Thanks!
Instead of adding the request context processor to the default set, you've overwritten the defaults with that single one. That means there is no user variable defined in the context. You could use request.user instead, but it would be better to fix your seeing as there are other useful processors you are missing out on (eg debug).
It was a simple mistake, I was using the todo button instead of the hub button :/
Sorry!
Thanks!
My url is :
1. http://localhost:8000/docs/[slug]
2. http://localhost:8000/docs/[slug]/login
1. url calls before number 2. url I want to send
the slug value to the function mapped by the url 2. In template
what should i wrote for form action event.
I agree, this is nearly incomprehensible, but I'm going to give it a go in terms of an answer.
In terms of calling sequence, there is none. A user might first visit url 2 or url 1. You have no way of guaranteeing which they will try to access first because they might directly input the url into their browser. The only thing you can do is set a variable in request.session's dict and test for it with your login url.
In terms of passing slug to another url, if you're having a url with this in it:
urls = ('',
url(r'docs/(?P<slug>\w+)', 'app.views.slug', name='slug-view'),
url(r'docs/(?P<slug>\w+)/login', 'app.views.slug_login', name='slug-login'),
#..
)
Then in your template you can do this:
<form action="{% url slug-login slugname %}" method="POST">
Your views.py would look something like this.
def slug(request, slug):
#
#
return render_to_response('templatename.html', {'slugname':slug}, context_instance=RequestContext(request))
def slug_login(request, slug):
# do something with slug.
This way, when you access the slug view, you pass into the template a variable called slugname, which the template uses with django's url library to resolve a specifically named url in urls.py with one named parameter, slug, which it will assign the value of slugname.
I suggest you try it.
I might also reccoment you read up on the django url dispatcher. Your use of regex without named parameters is acceptable but really not best practice. I'd also suggest django shortcuts (render_to_response) as a quick way to pass variables into templates and the django template language itself.