I am using Django (version 2.1.3) in one of my project and currently struggle with a weird bug. I use the build in internationalization module and included a language toggler in my main menu which is loaded on every page
{% get_current_language as LANGUAGE_CODE %}
<form id="form" action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ request.get_full_path|strip_lang }}" />
<input id="form_lang" name="language" type="hidden" value="{{ LANGUAGE_CODE }}"/>
</form>
<ul role="menu" class="dropdown-menu"id="lang-dropdown">
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<li>
<a href="#" onClick='(function(){
document.getElementById("form_lang").value = "{{ language.code }}";
document.getElementById("form").submit(); return false;})();return false;'>
{{ language.name_local }} ({{ language.code }})</a>
</li>
{% endfor %}
</ul>
I created a special tag "strip_lang" to strip the language identifier from the current URL.
#register.filter
#stringfilter
def strip_lang(value):
"""Removes all values of arg from the given string"""
lang = getattr(settings, "LANGUAGES", None)
url = value.split('/')
if url[1] in [l[0] for l in lang]:
return urllib.parse.unquote('/' + '/'.join(value.split('/')[2:]))
else:
return urllib.parse.unquote(value)
This all works well. However, for one of my apps, I always get rerouted to a different app.
ie if I am at path
/en/app1/mypage1
and toggle the language i suddenly end up at
/fr/app2/mypage1
*****EDIT*****
Referals for app2 work correctly. When entering a URL manually for app1 the pages load correctly.
My url.py in the main project looks like this
urlpatterns = [
path('admin/', admin.site.urls),
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
path('app1/', include('app1.urls')),
path('app2/', include('app2.urls')),
path('app3/', include('app3.urls')),
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
url(r'^login/$', auth_views.LoginView.as_view(), {'template_name': 'login.html'}, name='login'),
url(r'^logout/$', auth_views.LogoutView.as_view(), {'template_name': 'logged_out.html'}, name='logout'),
url(r'^oauth/', include('social_django.urls', namespace='social')),
prefix_default_language=False)
ans urls.py of my apps look like this
urlpatterns = [
path('', views.index, name='index'),
path('surveys/', views.nrgt_surveys, name='nrgt_surveys'),
path('surveys/<str:survey_name>/', views.survey, name='survey'),
path('surveys/<str:survey_name>/<query_name>', views.survey_query, name='survey_query'),
path('landscapes/', views.landscapes, name='landscapes'),
path('landscapes/<str:landscape_name>/', views.landscape, name='landscape'),
path('landscapes/<str:landscape_name>/<query_name>', views.landscape_query, name='landscape_query'),
]
I do not specify the app name anywhere in my code. When I track my network requests I can also see that the correct URL is submitted in the POST request. Why does my url get modified?
Related
this was actually working fine i don't know what changed or happened.
suddenly {{ redirect_to }} as shown here from django documentation
<input name="next" type="hidden" value="{{ redirect_to }}">
doesn't have a value when i view it from developer tools
this my template code
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
<li class="mx-0 mx-lg-1">
<form action="{% url 'set_language' %}" method="post" id="lang_form" style="display: flex; margin-top: 1rem;">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<select id="language_selection" onchange="ChangeLanguage(this);" class="form-control bg-primary text-white" name="language">
{% for language in languages %}
<option class="text-white" value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }}
</option>
{% endfor %}
</select>
</form>
</li>
the form is submitted using this java script code
function ChangeLanguage(element){
const lang_form = document.getElementById('lang_form');
console.log(lang_form);
lang_form.submit();
}
and this is my main urls.py
rom django.contrib import admin
from django.urls import path, include
from django.conf import settings #add this
from django.conf.urls.static import static #add this
from django.contrib.auth import views as auth_views
from django.conf.urls.i18n import i18n_patterns
from django.views.i18n import JavaScriptCatalog
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('lazord.urls', namespace='lazord')),
path('authentication/', include('authentication.urls', namespace='authentication')),
path('booking/', include('booking.urls', namespace='booking')),
path('doctors/', include('doctors.urls', namespace='doctors')),
path('notifications/', include('notifications.urls', namespace='notifications')),
path('reception/', include('reception.urls', namespace='reception')),
path('instagram_api/', include('instagram_api.urls', namespace='instagram_api')),
path('i18n/', include('django.conf.urls.i18n')),
path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),
# reset password views
path('reset_password/', auth_views.PasswordResetView.as_view(
template_name='authentication/password_reset.html',
), name='reset_password'),
path('password_reset_done', auth_views.PasswordResetDoneView.as_view(
template_name='authentication/password_reset_sent.html'
), name='password_reset_done'),
path('password_reset_confirm/<uidb64>/<token>', auth_views.PasswordResetConfirmView.as_view(
template_name = 'authentication/password_reset_form.html'
), name='password_reset_confirm'),
path('password_reset_complete', auth_views.PasswordResetCompleteView.as_view(
template_name='authentication/password_reset_done.html'
), name='password_reset_complete'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path('', include('lazord.urls', namespace='lazord')),
path('authentication/', include('authentication.urls', namespace='authentication')),
path('booking/', include('booking.urls', namespace='booking')),
path('doctors/', include('doctors.urls', namespace='doctors')),
path('notifications/', include('notifications.urls', namespace='notifications')),
path('reception/', include('reception.urls', namespace='reception')),
path('instagram_api/', include('instagram_api.urls', namespace='instagram_api')),
path('i18n/', include('django.conf.urls.i18n')),
path('jsi18n/', JavaScriptCatalog.as_view(), name='javascript-catalog'),
# reset password views
path('reset_password/', auth_views.PasswordResetView.as_view(
template_name='authentication/password_reset.html',
), name='reset_password'),
path('password_reset_done', auth_views.PasswordResetDoneView.as_view(
template_name='authentication/password_reset_sent.html'
), name='password_reset_done'),
path('password_reset_confirm/<uidb64>/<token>', auth_views.PasswordResetConfirmView.as_view(
template_name = 'authentication/password_reset_form.html'
), name='password_reset_confirm'),
path('password_reset_complete', auth_views.PasswordResetCompleteView.as_view(
template_name='authentication/password_reset_done.html'
), name='password_reset_complete'),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
i am currently changing the language by changing the language code in the link using js ( i don't know if this is right or not) i dont know what is messing or if changed something without me noticing thanks in advance for any help.
I'm trying to pass an object's id through the url, but its not able to find the page even after it tries the path when it goes through its patterns
Error:
Using the URLconf defined in GroomingService.urls, Django tried these URL patterns, in this order:
admin/
[name='Home']
appointment-Maker/
account/
admin-home
view_appointment/<id>/
login/ [name='Login Page']
registration/ [name='Registration Page']
logout [name='Logout Page']
The current path, adminview_appointment/21/, didn’t match any of these.
GroomingService.urls
#urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', Home_view, name="Home"),
path('appointment-Maker/', include('appointmentApp.urls')),
path('account/', include('accountApp.urls')),
path('admin-home', include('adminApp.urls')),
path('view_appointment/<id>/', viewAppointment_view), #this is the page it is not finding
path('login/', Login_view, name='Login Page'),
path('registration/', Registration_view, name='Registration Page'),
path('logout', Logout_view, name='Logout Page')
]
adminApp/views.py viewAppointment_view
def viewAppointment_view(request, id):
appointments = Appointment.objects.get(id = id)
context = {
'appointments' : appointments
}
return render(request, "admin_templates/viewappointment.html", context)
templates/admin_templates viewappointment.html
{% extends 'base.html' %}
{% block content %}
<a>appointment view</a>
{% endblock %}
templates/admin_templates adminhome.html (the link is clicked through this page)
{% extends 'base.html' %}
{% block content %}
<a>this is the admin page</a>
<br>
{% for a in appointments %}
Client name:{{a.client_dog_name}}<br> {% comment %} this is the link that is clicked {% endcomment %}
{% endfor %}
<br>
<a>find month</a>
<form method="POST">
{% csrf_token %}
{{ monthyear }}
<button class="btn btn-primary" type="submit">click</buttom>
</form>
{% endblock %}
If I'm missing anything please let me know, I had the path at the adminApp/urls.py earlier
urlpatterns = [
path('', views.adminhome_view, name="Admin Home"),
]
but moved it to where it was trying to find the urls. I have no idea why this might not be working.
It should be view_appointment/{{a.id}}, not adminview_appointment/{{a.id}}, but it is better to make use of the {% url … %} template tag [Django-doc]. You can give the view a name:
path('view_appointment/<int:id>/', viewAppointment_view, name='view_appointment'),
and then refer to it in the template:
Client name:{{a.client_dog_name}}<br>
My form with language selection buttons and an update button. Customer update form is implemented through django forms and views however language selections are directly implemented in html file using below code:
{% load i18n %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
1:image of webpage rendered form
Whenever I select any language same page with default english is rendered again.
I have placed the relevant context processors and locale middleware where it should be in settings file.
My root urlConf is given below:
urlpatterns = [
url(r'^', include('custupdate.urls')),
url(r'^i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
url(r'^', include('custupdate.urls')),
My application url conf is given:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^personBasic', views.person_detail, name='person_detail'),
url(r'^licenseeBasic', views.licensee_detail, name='licensee_detail'),
url(r'^address', views.address, name='address'),
url(r'^contact', views.contact, name='contact'),
url(r'^email', views.email, name='email'),
]
My each url e.g personBasic is hooked to its relevant view and view is hooked with relevant form.
Now when I enter following url in address bar and hit enter
http://mycompany.com/custupdate
Because of above url configurations it goes to index view which redirects to following url
http://mycompany.com/custupdate/personBasic
and image 1 is shown in browser.
So selecting any language renders the same page again without change of language.
When I do inspect element in the browser for any language button when its pressed I get following url requested
http://mycompany.com/custupdate/i18n/setlang/
instead of
http://mycompany.com/custupdate/personBasic/i18n/setlang/
Question is when the language buttons are pressed shouldn't the whole url in address bar be rendered as translated version. Whatever is after custupdate is skipped somehow and i18n/setlang is appended after custupdate where i'm expecting it to be like this
/custupdate/personBasic/i18n/setlang/
or
/custupdate/contact/i18n/setlang/
or
/custupdate/email/i18n/setlang/
Change your root URLconf to this:
urlpatterns = [
url(r'^i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(
url(r'^', include('custupdate.urls')),
)
Also, inside your form, remove the hidden input named next, completely. You have not defined a redirect_to variable.
Also, make sure that you have set middlewares in the correct order.
I don't know how to put this question as a title. But my question is I have 2 templates for each view in my django project templates folder. One template for english language and another for spanish language. My templates structure is
Project
|
app
|
templates
|
app
|
home_en.html
home_es.html
about_en.html
about_es.html
I need to render the templates according to the user choice of language. I have the project now fully in english running. As a start I only have the templates converted to spanish and ready to render. I am sorry this is a vague question but some directions to this problem would help.
My main urls are
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^en/', include('app.urls')),
url(r'^es/', include('app.urls')),
]
my app urlpatterns are
urlpatterns = [
url(r'^about$', views.about, name='about'),
url(r'.*', views.home, name='home'), ]
I also tried checking the request url with /en/ or /es/ and then render according to it in each views like below.
def home(request):
if request.path == '/en/':
return render(request, 'app/home_en.html', {'title':'HOME'})
else:
return render(request, 'app/home_es.html', {'title':'HOME'})
def about(request):
if request.path == '/en/about':
return render(request, 'app/about_en.html', {'title':'ABOUT'})
else:
return render(request, 'app/about_es.html', {'title':'ABOUT'})
This works fine when I explicitly give url request as /en/ or /es/. How could i set it on the url based on the users selection of language ?
If I explicitly make request to http://127.0.0.1/es/about, my about page is shown in spanish but when I switch to home from there, it goes back to English home page. I want the url to stay as /es/ as the start even if I change the url. Now it changes to english since it is upper level in pattern
A very simple solution is to use a single pattern with a named group:
url(r'^(?P<language>en|es)/', include('app.urls'))
Your views must then accept the language parameter:
def home(request, language):
# language is either "es" or "en".
return render(request, 'app/home_{}.html'.format(language), {'title': 'HOME'})
You may also consider Django's localization and avoid duplicating the views.
Please read Django translation docs. here: https://docs.djangoproject.com/en/1.10/topics/i18n/translation/#module-django.conf.urls.i18n
See the part: Language prefix in URL patterns
in your urls.py:
from django.conf.urls.i18n import i18n_patterns
urlpatterns += i18n_patterns (
url(r'^about$', views.about, name='about'),
url(r'.*', views.home, name='home'),
)
This will automatically prefix you urls with language codes.
in the views.py you can get language code fomr request.LANGUAGE_CODE like this: from request.LANGUAGE_CODE == 'en'
To choose language put in your html templates:
{% load i18n %}
<form action="{% url 'set_language' %}" method="POST">{% csrf_token %}
<select name="language" id="language">
<option value="en">en</option>
<option value="ru">ru</option>
<option value="az">az</option>
</select>
<button type="submit">send</button>
</form>
or
{% load i18n %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}" />
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go" />
</form>
I am a newbie at Django.
Got Django 1.4.2 working with Python 2.7
on Windows 7.
I am following a tutorial and I need to get a form template appear
with radio buttons. Selecting a button sends data and the page should
ask you if you want to 'vote again?'. Also, if you do not select a button
and submit the form it should show a message asking you to make a choice.
So far,
here's the HTML form:
<h1>{{ poll.question }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>
Now when I type http://localhost:8000/polls/1/ I should get the form, but instead I get the following error message:
NoReverseMatch at /polls/1/
u"'polls" is not a registered namespace
I registered polls as a namespace, see below in the project urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
)
To answer cathy's kind request, here's the vote url:
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
.. and below I include the project folder's urls if this could help:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
)
And I just noticed the following error message shown on the browser (because Debug = True):
Error during template rendering
In template C:\Python27\Scripts\mysite\mytemplates\polls\index.html, error at line 4
u"'polls" is not a registered namespace
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Any help to make that form run properly will be appreciated!
urlpatterns = patterns('polls.views',
url(r'^$', 'index', name='index'),
url(r'^(?P<poll_id>\d+)/$', 'detail', name='detail'),
url(r'^(?P<poll_id>\d+)/results/$', 'results', name='results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'vote', name='vote'),
)
{% url polls:detail poll.id %}
Go to your settings.py file and check out your template loaders. You may need to switch their order.
The correct order should be:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
Hope this helps.
Try to put {% load url from future %} on the top of your html file. It should fix your problem.