Django: Named Url's/ Same regex, different Names - python

I have a urls.py file which contains multiple urls with same named paramaters and regex but different names. When I call a view function from the template using {% url 'name' param %} it calls the function which comes first in the urls.py file in disregard to the name. Here is the content of urls.py:
urlpatterns = patterns('accountsearch.views',
url(r'^$', 'account_search', name='account_search'),
url(r'(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$','reset_password',name='reset_password'),
url(r'(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$','reset_securityquestions',name='reset_securityquestions'),
I am trying to call reset_securityquestions from the template using:
"{% url 'reset_securityquestions' account.uuid user.uuid %}">
but it calls reset_password instead.
If I change the order of urls in urls.py to this:
urlpatterns = patterns('accountsearch.views',
url(r'^$', 'account_search', name='account_search'),
url(r'(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$', 'reset_securityquestions',
name='reset_securityquestions'),
url(r'(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$', 'reset_password', name='reset_password'),
and call reset_password using:
{% url 'reset_password' account.uuid user.uuid %}
it calls the reset_security_questions function. Where am I going wrong?

Django always take firsts matching url pattern , so rewrite the urls as :
urlpatterns = patterns('accountsearch.views',
url(r'^$', 'account_search', name='account_search'),
url(r'^reset-password/(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$','reset_password',name='reset_password'),
url(r'^security-question/(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$','reset_securityquestions',name='reset_securityquestions'),

I don't understand how you are expecting Django to know which URL to use if they both have exactly the same url pattern. When the request comes in, all Django has to go on is the URL itself, and it will always try and match those in order. With your switched patterns, you'll find that the reset_password view now doesn't work.
You need to give Django some way of distinguishing between them. Usually some literal text, either as a prefix or a suffix, would be used, for example:
r'reset/(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$'
r'security/(?P<account_uuid>[a-zA-Z0-9\-]+)/(?P<user_uuid>[a-zA-Z0-9\-]+)/$'

Related

TypeError at / 'str' object is not a mapping in django template

I am trying to set up links inside a tags, and when I do this procedure as seen in the code, it gives me the error:
TypeError at / 'str' object is not a mapping
It use to work fine but then decided not to
template code:
<a class="item" href="{% url 'home' %}">
urls code:
urlpatterns = [
path('admin/', include('admin_llda.urls') ),
path('about/', views.about, name = 'about'),
path('dashboard/',views.dashboard, name = 'dashboard'),
path('',views.homepage, name = 'home')
]
Check that you have properly named the name kwarg in your urls file.
It's a keyword argument, not an argument. So you should type the keyword and the value.
For example your current urlpatterns list in one of your installed apps urls.py file looks like this:
urlpatterns = [
path('', views.index, 'index'),
path('like/', views.like, 'like')
]
You should check if you have missed the name kwarg. The above code should be changed to:
urlpatterns = [
path('', views.index, name='index'),
path('like/', views.like, name='like')
]
If you want to find it faster, you can comment each app's url inclusion, in the your_project/urls.py file. When the error is gone, it means that you should check the commented app urls.py file.
Check if you have the name argument in all of your urls.py files, for each Django app you have installed.
If you have specified a name argument for any url in the path function, it should be declared like path('', views.a, name='view.a'), not like path('', views.a, 'view.a').
Notice the absence of the name argument in the latter code.
If you miss the name argument, you will get the 'TypeError at / 'str' object is not a mapping' error.
Please, check for errors in admin_llda.urls.
You might have missed adding name='' in one of the path() calls.
E.g.:
You might have written
path('',views.some_method, 'somename')
instead of path
path('',views.some_method, name= 'somename')
I just had the same issue and I found the solution! Check your urls.py and whether you failed to name any url appropriately- not necessarily
Try adding namespace to your url
e.g add the following to your 'my_app/urls.py'
app_name='my_app'
then your template should look something like: <a class="item" href="{% url 'my_app:home' %}">
finally be sure to register your app in the 'my_project/settings.py'
https://docs.djangoproject.com/en/3.0/topics/http/urls/#naming-url-patterns
I had the same issue , check the name argument in the path('',,name=" ")

Django: reverse() and get_absolute_url() returns different output for same object?

When used with flatpages reverse() and get_abolute_url() returns different outputs:
>>> about = FlatPage.objects.get(id=2)
>>>
>>> about
<FlatPage: /about-us/ -- About us page>
>>>
>>> about.url
>>> '/about-us/'
>>>
>>> about.get_absolute_url()
'/about-us/'
>>>
>>>
>>> reverse('django.contrib.flatpages.views.flatpage', args=[about.url])
'/%2Fabout-us/' ## from where %2F comes from ?
>>>
Here is the sitewide urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from django.contrib .flatpages import urls as flatpage_urls
# from . import blog
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include(flatpage_urls)),
]
Although, I am able to access to about page at http://127.0.0.1:8000/about-us/. From where does %2F come from ?
I was expecting both method should return same output. What's going on here ?
Update:
Here is flatpages/urls.py
from django.conf.urls import url
from django.contrib.flatpages import views
urlpatterns = [
url(r'^(?P<url>.*)$', views.flatpage, name='django.contrib.flatpages.views.flatpage'),
]
Update 2:
Updated urls.py to:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
# url(r'', include(flatpage_urls)),
]
urlpatterns += [
url(r'^(?P<url>.*/)$', views.flatpage),
]
It looks to me like you are trying to insert a URL inside another URL, which just seems weird.
From your code:
reverse('django.contrib.flatpages.views.flatpage', args=[about.url])
You have also clarified about.url contains /about-us/. This string will get quoted and inserted in the URL:
http://hostname.example/<here>/
Or:
http://hostname.example/%2Fabout-us%2F/
I don't understand why you are not seeing the last %2F however.
django.contrib.flatpages is apparently incompatibile with reverse() with args or kwargs. The intended use is with its custom tag:
{% load flatpages %}
{% get_flatpages as flatpages %}
<ul>
{% for page in flatpages %}
<li>{{ page.title }}</li>
{% endfor %}
</ul>
Source Flatpages > Getting a list of FlatPage objects in your templates
Why the %2f
FlatPage.get_absolute_url() merely returns whatever is in the self.url field, which in your example is a string enclosed by slashes, i.e. '/about-us/'.
def get_absolute_url(self):
# Handle script prefix manually because we bypass reverse()
return iri_to_uri(get_script_prefix().rstrip('/') + self.url)
On the other hand, reverse() calls _reverse_with_prefix(), which prefixes a slash / to the URL, resulting in //about-us/. Then, it falsely determines the double-slash to mean an attempted schema rewrite, and so it replaces the second slash with the URL ASCII code %2f to neutralize it.
Unfortunately, the form validator for FlatPage.url requires that offending leading /:
def clean_url(self):
url = self.cleaned_data['url']
if not url.startswith('/'):
raise forms.ValidationError(
ugettext("URL is missing a leading slash."),
...
You can sort of work around it by using a prefix without a slash, like:
url(r'^pages', include(django.contrib.flatpages.urls))
but this would also match pagesabout-us/. If you remove the prefix altogether like with r'^', _reverse_with_prefix() will prefix a / in an attempt to avoid relative linking.
You can hard-code the URLs like the 3rd example from https://docs.djangoproject.com/en/1.11/ref/contrib/flatpages/#using-the-urlconf, but this defeats the purpose of managing URLs in the flatpages table.
from django.contrib.flatpages import views
urlpatterns += [
url(r'^about-us/$', views.flatpage, {'url': '/about-us/'}, name='about'),
url(r'^license/$', views.flatpage, {'url': '/license/'}, name='license'),
]

Django Haystack Reverse URL Failing

I am currently trying to configure the most barebones possible setup for Django Haystack. In my HTML, I have a form that resolves a url using a named url pattern. Here is the HTML code.
<form id="search-ticket-form" class="navbar-form navbar-left dropdown" method="get"
action="{% url "search_ticket" %}" role="search">
Django returns an error every time saying "Reverse for 'search_ticket' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []"
Here is the configuration in my urls.py:
urlpatterns = patterns('',
url(r'^$', contact.views.home, name='homepage'),
#url(r'^blog/', include('zinnia.urls', namespace='zinnia')),
url(r'^profile/', include('user_profile.urls')),
url(r'^registration/', include('registration.urls')),
url(r'^comments/', include('django_comments.urls')),
url(r'^contact/', include('contact.urls')),
url(r'^tickets/', include('tickets.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^search/', include('haystack.urls')),
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Here is the configuration in my tickets/urls.py:
urlpatterns = patterns('',
url(r'submit_ticket/$', submit_ticket, name='submit_ticket'),
url(r'search_ticket/$', include('haystack.urls'), name='search_ticket')
)
The setup certainly looks fine. When I substitute include('haystack.urls') for a function based view named 'abc', the url resolves just fine. This makes me think that something is wrong with my Django Haystack setup, but the error certainly is misleading. Here is what my single Haystack view looks like:
class TicketIndex(indexes.BasicSearchIndex, indexes.Indexable):
def get_model(self):
return Ticket
I modeled this setup after the barebones example in Haystack's github repo (https://github.com/toastdriven/django-haystack/blob/master/example_project/bare_bones_app/search_indexes.py).
Any thoughts on what is going on here?
Can you actually name an included URL tree? It usually includes multiple URL patterns. Looking at haystack.urls you may want to try {% url "haystack_search"%}.

Django named routes like Laravel

I'm starting to learn about Django Framework. I have this urls in my urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
# Examples:
url(r'^hello/$','article.views.hello'),
)
My questions are: Can I give this routes a name, like i would in Laravel? How can i reference those named routes from template?
Thanks!
Yes, you can:
url(r'^hello/$','article.views.hello', name="hello"),
You would reference it in a template as:
{% url 'hello' %}
For more information, including how to give arguments to a named URL, see here.

Reverse for ''*'' with arguments '()' and keyword arguments '{}' not found

I am trying to use the {% url %} tag to send my user to a new template, called payment.html. I am receiving the error above. Here's what I have:
In some Javascript in my template:
{% url 'payment' %}
In my urls:
urlpatterns = patterns('',
(r'media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^pc-admin/', include(pcAdminSite.urls)),
(r'^$', index),
(r'^signup/', signup),
(r'^info_submit/', info_submit),
(r'^payment/', payment, name="payment"),
In my views:
def payment(request):
return render_to_response('payment.html', {})
Based on similar posts, I've made sure that only 1 URL points to my payment view and have used named URLs. Can anyone help with what I might be doing wrong? Thanks.
There shouldn't be any '' surrounding the view name in the url tag - check the documentation out.
(Unless you're using the Django's 1.5 future {% url %} tag.)
this error also occurs this way :
My account
the message will be this one
Reverse for ''profiles_profile_detail'' with arguments '(u'mynick',)' and keyword arguments '{}' not found.
once the two '' dropped like explain erlier everything works fine ;)

Categories