How to include in django template a reverse url in translation - python

I have the following block of code, And I want to include a url to the login page, after the user logs out, in a translatable text.
Unfortunately, translation blocks cannot include tags, and I get the following error:
SyntaxError: Translation blocks must not include other block tags: url "account:login"
{% blocktrans %}
You have been successfully logged out.
You can log-in again.
{% endblocktrans %}
urls.py:
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = 'account'
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
What would be the right way to achieve something like this?
Edit: I figured there are workarounds, such as translating blocks of text separately, or using javascript to append the "href" element after the page loads. But I wonder if there is a more efficient, Django way.

As documented
Reverse URL lookups cannot be carried out within the blocktrans and
should be retrieved (and stored) beforehand:
{% url 'path.to.view' arg arg2 as the_url %}
{% blocktrans %}
This is a URL: {{ the_url }}
{% endblocktrans %}

Related

How can I redirect to a page depend on different user group correctly by django?

I am creating a feature to let the banned user (user without any group) go to a specific page banned_alert when they click the "post", because they are not allowed to do so. But then when I test this feature, the Chrome shows This page isn’t working | the IP redirected you too many times. Can somebody tell me how to do it correctly? Did I miss any configuration? Below is my code snippets. Thank you for your time!
base.html: (has_group function already works correctly somewhere else)
{% load get_group %}
{% if request.user|has_group:"mod" or request.user|has_group:"default" or user.is_staff %}
<a class="nav-link" href="/create-post">Post</a>
{% else %}
<a class="nav-link" href="/banned_alert">Post</a>
{% endif %}
banned_alert.html:
{% extends 'main/base.html' %}
{% block title %}Your account has been banned by Admin{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<h2>Please contact the Admin!</h2>
{% endblock %}
view.py
def banned_alert(request):
return redirect('/banned_alert')
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('home', views.home, name='home'),
path('sign-up', views.sign_up, name='sign_up'),
path('create-post', views.create_post, name='create_post'),
path('banned_alert', views.banned_alert, name='banned_alert'),
]
You have a recursion:
this is your path
path('banned_alert', views.banned_alert, name='banned_alert'),
User visit this banned_alert path,
it redirects user to view banned_alert
Which redirects user back to url banned_alert
and it redirects back to view banned_alert
reapeat N times (it has no ending)
best way to ban user is to create a flag in his model:
models.py
class User(AbstractUser):
is_banned = models.BooleanField(default=False)
if you want to ban user, change user's field is_banned to true, and then in your template or view, check if user is banned or not, and do your logic according to it
By the way, in your ulrs.py you need to close paths with backslash like this path('home/', views.home, name='home'),

Not able to navigate between two templates in a Django application

I have a ran into a difficulty when navigating between different templates in a Django (v3.2) application. The app is called 'manage_remittance'.
The default landing page (which uses template manage_remittance/templates/manage_remittance/view_remittance.html) for the app should show a list of items (list is not relevant at the moment), and at the top of that list there should be a link, leading to another page in the same app, which would allow to add new items to the list.
The form that is invoked first is here:
manage_remittance/templates/manage_remittance/view_remittance.html
{% extends "root.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% url 'manage_remittance:remittance_add' as remittance_add %}
{% block title %}
VIEW REMITTANCES PAGE
{% endblock title %}
{% block content %}
<div class="list-group col-6">
Click here to add remittance data
</div>
I want to be able to get to another template (manage_remittance/templates/manage_remittance/remittance_add.html), but the {{ remittance_add }} has no value.
In addition, when I specify exact name of the html file (remittance_add.html) in the a href (see above), and click on it, I get a following error:
Using the URLconf defined in sanctions_project.urls, Django tried these URL patterns, in this order:
admin/
[name='login']
login/ [name='login']
logout/ [name='logout']
manage_remittance/ [name='view_remittance']
manage_remittance/ remittance_add/ [name='create_remittance']
^static/(?P<path>.*)$
^media/(?P<path>.*)$
The current path, manage_remittance/remittance_add.html, didn’t match any of these.
What am I doing wrong here?
fragment of urls.py for the project:
urlpatterns = [
path('admin/', admin.site.urls),
path('', login_view, name='login'),
path('login/', login_view, name='login'),
path('logout/', logout_view, name='logout'),
path('manage_remittance/', include('manage_remittance.urls')), # namespace='manage_remittance'
]
urls.py at manage_remittance app:
from .views import (
CreateRemittanceInfo,
RemittanceListView
)
app_name = 'manage_remittance'
urlpatterns = [
path('', RemittanceListView.as_view(), name='view_remittance'),
path('remittance_add/', CreateRemittanceInfo.as_view(), name='create_remittance'),
]
views.py at manage_remittance app:
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views.generic import ListView
from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Remittance
class CreateRemittanceInfo(LoginRequiredMixin, CreateView):
model = Remittance
fields = ['remittance_text']
template_name_suffix = '_add'
class RemittanceListView(ListView):
model = Remittance
template_name = 'manage_remittance/view_remittance.html'
It seems that you have an issue in your urls:
manage_remittance/ remittance_add/ [name='create_remittance']
the name does not match with
manage_remittance:remittance_add
It seems quite simple: in your template, you should display a list, which is not the case. Have a look at Django User Guide: https://docs.djangoproject.com/fr/3.2/ref/class-based-views/generic-display/
It should look like
{% for object in object_list %}
<p>{{object.remittance_text}}</p>
{% endfor %}

django can't show a template - how to fix

I just made the app users to validate user that is already registered in database. Included url inside project directory(urls.py), executed the login page in urls.py from app directory, made the template and a link refer in base.html. It all works, however when click Login link return this error:
TemplateDoesNotExist at users/login/
I tried to rename the path according tree navigation but always return this same error. Any idea what is happening?
Sorry my english
tree navigation in my project like this:
my_project
urls.py(project):
from django.contrib import admin
from django.urls import include, path
app_name = ['app_web_gym', 'users']
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', include('users.urls', namespace='users')),
path('', include('app_web_gym.urls', namespace='app_web_gym')),
]
urls.py(app)
from django.urls import path
from django.contrib.auth import views as auth_views
from . import views
app_name = 'users'
urlpatterns= [
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
]
base.html:
<p>
Web Gym-
Clientes-
Treinos-
Instrutores-
{% if user.is_authenticated %}
<p>Hello, {{user.username}}.<p/>
{% else %}
Login
{% endif %}
</p>
{% block content %} {% endblock content %}
login.html:
{% extends 'app_web_gym/base.html' %}
{% block content %}
{% if form.errors %}
<p>Wrong username/password. Try again.</p>
{% endif %}
<form method='POST' action="{% url 'users:login' %}">
{% csrf_token %}
{{form.as_p}}
<button name='submit'>Log in</button>
<input type='hidden' name='next' value="{% url 'app_web_gym:index' %}" />
</form>
{% endblock content %}
I printed the full error:
TemplateDoesNotExist
I noticed that says Django tried loading these templates, in this order, in last line ->
/home/at_admin/prj01/app_web_gym/templates/users/login.html (Source does not exist)
thats the wrong path to login.html the correct is
/home/at_admin/prj01/users/templates/users/login.html as shown in tree navigation.
I don't know why is this happening and don't know how to fix it.
have you registered your app in main settings.py? It occurs sometimes when you forget to register your app
In main settings.py file:
at the end of, add one more line
INSTALLED_APPS = ['appname'] (replace appname with the name of your app having login page)
Hey people i just deleted all the app users and recreated it with the same coding that i previously copied. It worked this time though still don't know what happened.
Thanks all
First you should've checked if the app was installed in your settings. And as it looks in the error the files were being looked at the wrong place(app_web_gym/users/login.html) instead of (users/login.html). So I suppose you made a mistake in installing your app in settings.py.

Django: html without CSS and the right text

First of all, this website that I'm trying to build is my first, so take it easy. Thanks. Anyway, I have my home page, home.html, that extends from base.html, and joke.html, that also extends base.html. The home page works just fine, but not the joke page. Here are some parts of my files, for you to understand how I want my system to work:
views.py
def joke_page(request, joke_id):
joke = Joke.objects.get(id=int(joke_id))
return render(request, 'joke.html', {'joke': joke})
urls.py
urlpatterns = [
url(r'^$', views.home_page, name='home_page'),
url(r'^(?P<joke_id>[0-9]+)/$', views.joke_page, name='joke_page'),
]
joke.html
{% extends 'base.html' %}
{% block header_text %}{{ joke.title }}{% endblock %}
{% block text %}{{ joke.text }}{% endblock %}
What I want is that URLs that end like jokes/1/ to render a page with the right html using joke.html. Instead, it renders a page without CSS or with joke.title and joke.text Also, I noticed that jokes/1/ doesn't find anything:
DoesNotExist at /jokes/1/
Joke matching query does not exist..
I had 20 jokes in the database and I can find jokes/2/ through jokes/21/, which means their ids have shifted? :P
Can someone experienced with Django point out my(many, without a doubt) mistakes? Thank you!
Edit: second urls.py
urlpatterns = [
url(r'^$', jokes_views.home_page, name='home'),
url(r'^jokes/', include(jokes_urls)),
url(r'^admin/', include(admin.site.urls)),
]
Are you using the {% load staticfiles %} in your templates?

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

Background
I am trying to customize the authentication views in a Django project, but I can't seem to get the customized password_change view to run. I use Django 1.8.2 and Python 2.7.
The urls.py of my module userauth looks like the following:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('django.contrib.auth.views',
url(r'^login/$', 'login', {'template_name': 'userauth/login.html'},
name='userauth_login'),
url(r'^logout/$', 'logout', {'next_page': '/'},
name='userauth_logout'),
url(r'^password-change/$', 'password_change',
{'template_name': 'userauth/password_change_form.html'},
name='userauth_password_change'),
url(r'^password-change-done/$', 'password_change_done',
{'template_name': 'userauth/password_change_done.html'},
name='userauth_password_change_done'),
)
this is referenced in the main urls.py as this:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^account/', include('userauth.urls')),
]
The template of my userauth/password_change_form.html
{% extends "base.html" %}
{% block title %}{{ block.super }} - Change Password{% endblock %}
{% block toggle_login %}{% endblock %}
{% block content %}
<form action="{% url 'userauth_password_change' %}" method="post" accept-charset="utf-8">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Change password"/>
</form>
{% endblock %}
And the template for userauth/password_change_done.html
{% extends "base.html" %}
{% block title %}{{ block.super }} - Password change successful{% endblock %}
{% block content %}
<p>Your password has been changed successfully.</p>
Back to your Account
{% endblock %}
The Problem
When I open the 'password_change_done' page (at /account/password-change-done), then everything is fine.
But at 'password-change' (/accunt/password-change) I am getting this error:
NoReverseMatch at /account/password-change/
Reverse for 'password_change_done' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
What I tried
I have no idea, why this should be happening.
I tried removing the single quotes from url 'userauth_password_change'
I made sure the password-change-donepage exists in urls.py and is available
I read the solutions at Reverse for '*' with arguments '()' and keyword arguments '{}' not found, Django: Reverse for 'detail' with arguments '('',)' and keyword arguments '{}' not found, Django change_password NoReverseMatch at /accounts/password/change/ (and a few more, I tried all the solutions there, but I can't find a problem in my own code)
Any help is appreciated. Thank you!
Ok, so the suggested solution for me didn't work here. I'm using Django 1.8.8 in an application with a specific app label, so I need to specify a url in a template like this e.g. app_label:url_name. This meant the reverse for password_change_done would never work since it's app_label:password_change_done.
But thankfully there's a solution: 'post_change_redirect'. Hence I specified password_change like this:
url(r'^password_change$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change.html', 'post_change_redirect': 'app_label:password_change_done'}, name='password_change'),
I'm sure others could use this to overcome the problem above and still keep their own custom url name.
In some section you call the url named "password_change_done"
the correct name is: "userauth_password_change_done"
The solution was, that the in the urls.py the name of the password_change_done link must be 'password_change_done':
url(r'^password-change-done/$', 'password_change_done',
{'template_name': 'userauth/password_change_done.html'},
name='password_change_done'),
I had a look into django.contrib.auth.views.password_change (which was creating the problem) and realized, that the the url 'password_change_done' is hardcoded there in Django 1.8.2.
You need delete single quotes around the view name
{% url password_change_done %}
instead of
{% url 'password_change_done' %}
I meet the same kind of problem. The reason is the "password_change_done" is hard code in the auth.views, so I extense the class base on the auth.views.PasswordChangeView。
the auth.views.PasswordChangeView:
class PasswordChangeView(PasswordContextMixin, FormView):
......
success_url = reverse_lazy('password_change_done')
the MyPasswordChangeView:
class MyPasswordChangeView(PasswordChangeView):
success_url = reverse_lazy('app_label:password_change_done')
just overide the success_url.
and use MyPasswordChangeView in the urlpattern. Now, everything is ok.
in case if you are using
app_name
and trying to overwrite default template for update/change password you have to tell that Django:
from django.urls import path, reverse_lazy
from django.contrib.auth import views as auth_view
from . import views
app_name = 'account'
urlpatterns = [
path('login/', auth_view.LoginView.as_view(), name='login'),
path('logout/', auth_view.LogoutView.as_view(), name='logout'),
path('password_change/',
auth_view.PasswordChangeView.as_view(
template_name='registration/password_change_form.html',
success_url=reverse_lazy('account:password_change_done')), name='password_change'),
path('password_change/done/',
auth_view.PasswordChangeDoneView.as_view(
template_name='registration/password_change_done.html'), name='password_change_done'),
]

Categories

Resources