django template url tag optional parameter - django

Lets say I have these urlpatterns:
url(r'^area/(?P<area>[\w-]+)/?$', views.IndexView.as_view(), name="index"),
url(r'^$', views.IndexView.as_view(), name="index"),
How do I use template tag url to cope with the optional area parameter without if else
I tried the following:
{% url 'index' area=area %}
Problem is:
If area doesn't exist in template context, I get reverse not found.
If I set area to None, then url will become /area/None

Replace your index urls with just one index url.
url(r'^(?:area/(?P<area>[\w-]+))?$', views.IndexView.as_view(), name="index")
I can test that from shell
from django.core.urlresolvers import reverse, resolve
from django.template import Context, Template
Template("url1 is {% url 'index' %}").render(Context())
Template("url2 is {% url 'index' area=1 %}").render(Context())
Template("url3 is {% url 'index' area='ab-12-cd' %}").render(Context())
Output
u'url1 is /'
u'url2 is /area/1'
u'url3 is /area/ab-12-cd'

Related

A issue to use URL template tag in django

I am currently learning Django. When I apply a url template tag, I found that the output of the url tag is not what I expected. I have read the Django Documents, but it does not help.
{{ movie.title }}
from django.urls import path
from . import views
app_name = 'movies'
urlpatterns = [
path('', views.index, name='index'),
path('<int:movie_id>', views.detail, name='detail')
]
The output of the url tag is localhost/movies/%7B%%20url%20'movies:detail'%20movie.id%20%
which is not as I expected: localhost:8000/movies/1
Modify lines as follow:
{{ movie.title }}
...
path('movies/<int:movie_id>/', views.detail, name='detail')

How to convert Template tags from normal django to the one django-hosts use

I have just added django-hosts to setup subdomains for my site which works perfectly. Next step is just to convert all the normal django URL's in my template to the one django-hosts like.
I know how to link pages , but once I need to add variables to my URL's i'm not sure how to construct the code for it.
Normal django URL that works
{% url 'golemstats:nodeinfo' node.Node_id node.Node|slugify %}
How do I convert that to a URL that django-hosts like? I've tried the following:
{% host_url 'nodeinfo' host 'golemstats' 'node.Node_id' 'node.Node|slugify' %}
hosts.py
from django.conf import settings
from django_hosts import patterns, host
host_patterns = patterns('',
host(r'www', settings.ROOT_URLCONF, name='www'),
host(r'golem', 'golemstats.urls', name='golemstats'),
)
golemstats.urls
from django.urls import path
from . import views
app_name = 'golemstats'
urlpatterns = [
path('', views.index, name='index'),
path('node', views.searchNode, name='searchNode'),
path('node/<nodeid>/<node>', views.nodeinfo, name="nodeinfo"),
path('version-notifier', views.notifierIndex, name="notifier"),
path('ports', views.portScanner, name="portscanner"),
path('scoreboard', views.scoreboard, name="scoreboard"),
path('tools', views.tools, name="tools"),
path('troubleshooting', views.troubleshooting, name="troubleshooting"),
path('network', views.networkOverview, name="networkOverview"),
]
Fixed. have to put arguments after host_url
{% host_url 'nodeinfo' node.Node_id node.Node|slugify host 'golemstats' %}

Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name

I want to use the default django.contrib.auth.views for resetting passwords with email confirmation. All this code is on urls.py :
from django.conf.urls import url
from . import views
from django.contrib.auth import views as auth_views
app_name = 'houses'
urlpatterns = [
# Root and details page
url(r'^$', views.index, name='index'),
url(r'^(?P<house_id>[0-9]+)/$', views.view_house, name='index'),
# Register / login / logout
url(r'^register/$', views.UserFormView.as_view(), name='register'),
url(r'^login/$', views.login_user, name='login_user'),
url(r'^logout/$', views.logout_user, name='logout_user'),
# User profiles and edit profiles
url(r'^profile/$', views.view_profile, name='view_profile'),
url(r'^profile/edit/$', views.edit_profile, name='edit_profile'),
# ---- ERRORS ARE HERE ---- change / reset passwords
url(r'^change_password/$', views.change_password, name='change_password'),
url(r'^password_reset/$', auth_views.password_reset,
{'post_reset_redirect': 'houses:password_reset_done',}, name='password_reset'),
url(r'^password_reset/done/$', auth_views.password_reset_done, name='password_reset_done'),
url(r'^reset-password/confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
auth_views.password_reset_confirm, name='password_reset_confirm'),
]
No matter what I try i keep getting:
Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.
Is it because my app name is houses? I've been trying things for hours with no luck.
This error is because Django expects to find the url password_reset_complete in the project urls and not in the app urls, so for you to keep that url in the app you need to rewrite the template password_template_email.html and passes it in the url password_reset pass the param email_template_name:
path('reset_password/',
auth_views.PasswordResetView.as_view(
template_name="users/registration/password_reset.html",
email_template_name = 'users/registration/password_reset_email.html',
success_url=reverse_lazy('users:password_reset_done')),
name="reset_password"),
and in the template password_reset_email, pass
{% autoescape off %}
To initiate the password reset process for your Account {{ user.email }},
click the link below:
{{ protocol }}://{{ domain }}{% url 'youapp:password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
{% endautoescape %}
I hope I helped!
If you are using reverse url in template
{% url 'houses:password_reset_confirm' uidb64=<uidb64> token=<token> %}
and if you using reverse url in python code then use
reverse('houses:password_reset_confirm', args=(<uidb64>,<token>,))
Here, <uidb64> means uidb64 value
<token> means token value
I had the same error before, to fix this I just wrote the URLs of the reset password option in the main URLs file (project_name/urls.py) and I've add in the templates folder a folder named "registration" that has inside a file named password_reset_email.html ( it contains the email that will be sent to the user, something like:
{% autoescape off %}
To initiate the password reset process for your Account {{ user.email }},
click the link below:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
{% endautoescape %}
). you can check my code on github if you want to see it clearly https://github.com/Ninou01/customer-relationship-management-system/blob/master/crm1/urls.py

How can I get {% url logout %} to work in my Django template?

My Django app's site-wide urls.py file looks like this:
urlpatterns = patterns('',
url(r'^$', include('myApp.urls')),
url(r'^admin/', include(admin.site.urls)),
url (
r'^accounts/register/$',
RegistrationView.as_view(form_class=extendedRegistrationForm),
),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^', include('myApp.urls')),
)
I also have a urls.py specific to myApp but I have not shown that here because I don't think it's relevant.
In my template file, I have this:
{% url logout %}
It gives me this error:
'url' requires a non-empty first argument. The syntax changed in Django 1.5, see the docs.
When I change the template to:
{% url 'logout' %}
It gives me the following error:
Reverse for 'logout' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
How do I put a link to logout in my view?
Add a logout url like this:
url(r"^logout/$", "django.contrib.auth.views.logout_then_login",
name="logout"),
The correct template syntax is:
{% url 'logout' %}
You didn't include django.contrib.auth's URLs in your urls.py, so there is no logout URL.
Try adding something like
url(r'^auth/', include('django.contrib.auth.urls')),
In django 3.0 {% url 'admin:logout' %} works perfect.

Django NoReverseMatch

I have the following setup:
/landing_pages
views.py
urls.py
In urls.py I have the following which works when I try to access /competition:
from django.conf.urls.defaults import *
from django.conf import settings
from django.views.generic.simple import direct_to_template
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^competition$', 'landing_pages.views.page', {'page_name': 'competition'}, name="competition_landing"),
)
My views.py has something like this:
def page(request, page_name):
return HttpResponse('ok')
Then in a template I'm trying to do this:
{% load url from future %}
<a href="{% url 'landing_pages.views.page' page_name='competition'%}">
Competition
</a>
Which I apparently can't do:
Caught NoReverseMatch while rendering: Reverse for 'landing_pages.views.page' with arguments '()' and keyword arguments '{'page_name': u'competition'}' not found.
What am I doing wrong?
You ask in your comment to DrTyrsa why you can't use args or kwargs. Just think about it for a moment. The {% url %} tag outputs - as the name implies - an actual URL which the user can click on. But you've provided no space in the URL pattern for the arguments. Where would they go? What would the URL look like? How would it work?
If you want to allow the user to specify arguments to your view, you have to provide a URL pattern with a space for those arguments to go.
{% url [project_name].landing_pages.views.page page_name='competition' %}
Or better
{% url competition_landing 'competition' %}