Django root path not found after adding handler404 - django

I added a handler404 to my project and it immediately broke the root path and the 404 page is shown.
I wonder how I need to change my urls.py to make it work correctly with i18n_patterns. I would appreciate any advice on the issue.
The URLs with the language prefix work fine.
mysite.com 404 why????
mysite.com/en/ OK
mysite.com/fr/ OK
mysite.com/gffg 404
Here's the urls.py of my project.
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path('i18n/', include('django.conf.urls.i18n')),
#apps
path('', include('apps.webapp.urls')),
path('user/', include('apps.userapp.urls')),
path('client-area/', include('apps.accountapp.urls')),
#additional paths
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
name='django.contrib.sitemaps.views.sitemap'),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('rosetta/', include('rosetta.urls')),
) + [
path("robots.txt", TemplateView.as_view(template_name="web/robots.txt", content_type="text/plain"),),
]
handler404 = 'apps.webapp.views.handler404'

i18n_patterns has a keyword argument prefix_default_language whose default is True. According to the documentation it:
Setting prefix_default_language to False removes the prefix
from the default language
(LANGUAGE_CODE).
This can be useful when adding translations to existing site so that
the current URLs won’t change.
You haven't set this to False in your code so you end up not having a pattern that would match mysite.com. Add the keyword argument to the function call so that you don't need the prefix for the default language:
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
...,
prefix_default_language=False,
)

I created custom error view to handle this issue
from django.shortcuts import render, redirect
from django.conf import settings
def handler_error_view(request, *args, **kwargs):
for lang_code, _ in settings.LANGUAGES:
if request.path.startswith('/'+lang_code):
return render(request, 'generals/your_error_template.html')
return redirect('/'+settings.LANGUAGE_CODE+request.path)

Related

Redirect all page not found to home page

I would like to redirect all 404 pages to a home page. I try this but it don't work
app/views.py
from django.http import HttpResponse
from django.shortcuts import render, redirect
def home(request): return HttpResponse('<h1> HOME </h1>')
def redirectPNF(request, exception): return redirect('home')
app/urls.py
from . import views
urlpatterns = [ path('home', views.home, name="home"), ]
app/settings.py
handler404 = 'app.views.redirectPNF'
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
DEBUG = False
Just Add this line in urls.py instead of settings.py
Everything else seems ok.
It is also mentioned in the django documentation that setting handler variables from anywhere else will have no effect. It has to be set from URLconf
The default error views in Django should suffice for most web applications, but can easily be overridden if you need any custom behavior. Specify the handlers as seen below in your URLconf (setting them anywhere else will have no effect).
app/urls.py
from . import views
handler404 = 'app.views.redirectPNF' # Added this line in URLconf instead of settings.py
urlpatterns = [ path('home', views.home, name="home"), ]

Page not found at/admin

I'm a very beginner.
When I tried to go visit this (http://127.0.0.1:8000/admin), I couldn't. Here have shown page not found. What can be the solution?
Problem that I faced:
Page not found (404)
“D:\1_WebDevelopment\Business_Website\admin” does not exist
Request Method: GET
Request URL: http://127.0.0.1:8000/admin
Raised by: django.views.static.serve
Using the URLconf defined in business_website.urls, Django tried these URL patterns, in this order:
admin/
admin/
[name='index']
singup [name='handle_singUp']
login [name='handle_login']
logout [name='handle_logout']
contact [name='handle_contact']
frontend_orders [name='frontend_orders']
hire_me [name='hire_me']
^(?P<path>.*)$
The current path, admin, matched the last one.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Problem : open the picture
business_website urls.py:
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('business_app.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
business_website url.py : open the picture
business_app urls.py:
from os import name
from django.contrib import admin
from django.urls import path
from .import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name="index"),
path('singup', views.handle_singUp, name= "handle_singUp"),
path('login', views.handle_login, name="handle_login"),
path('logout', views.handle_logout, name="handle_logout"),
path('contact', views.handle_contact, name="handle_contact"),
path('frontend_orders', views.frontend_orders, name="frontend_orders"),
path('hire_me', views.hire_me, name="hire_me")
]
business_app url.py : open the picture
Delete from business_app urls.py this row:
path('admin/', admin.site.urls),
You should not call it twice.
You should set MEDIA_URL in settings to something. Like:
MEDIA_URL = '/media/'
Django urls need to have a trailing slash and the url you tried to access does not have it, check in your settings.py file if APPEND_SLASH is set to false
Among Django's many built-in features is APPEND_SLASH, which by default is set to True and automatically appends a slash / to URLs that would otherwise 404.
You can turn off this option by just setting APPEND_SLASH = False
You can read more here about why django uses trailing slashes
You have the same admin path defined in your root urls.py and in your app. It should probably be in just the root. Remove it from:
from os import name
from django.contrib import admin
from django.urls import path
from .import views
urlpatterns = [
# path('admin/', admin.site.urls), ##### REMOVE
path('', views.index, name="index"),
path('singup', views.handle_singUp, name= "handle_singUp"),
path('login', views.handle_login, name="handle_login"),
path('logout', views.handle_logout, name="handle_logout"),
path('contact', views.handle_contact, name="handle_contact"),
path('frontend_orders', views.frontend_orders, name="frontend_orders"),
path('hire_me', views.hire_me, name="hire_me")
]
Edit
After trying, and failing to reproduce the OP's error on my machine using all the answers given as of this writing, it turned out my original answer was not correct (not incorrect, but also not the solution), in fact the original answer given by Jaime Ortiz, was most likely the correct one.
But why was it so hard to come to this realization? Within the link he provided was this, which is why, when I initially tried his solution it did not work. Below is from the answer provided by
All Іѕ Vаиітy in that link. Note that within the [] is my insertion.
Since django observes both the urls [the one with the trailing slash
and the one without] as different, if you are caching your app, Django
will keep two copies for same page at ...
So either use admin/ instead of admin, or apply APPEND_SLASH = False to your settings.py, clear your browser cache and then you can use either, Django will append the slash automatically.

Add internationalization to Django URL with prefix of the language coming after the added prefix

I know how to add a general prefix to all urls thanks to this answer https://stackoverflow.com/a/54364454/2219080. But I want to have urls where we have the added prefix always coming before the language prefix (added by i18n_patterns ).
from django.urls import include, path, re_path
from django.views.generic import TemplateView
from django.conf.urls.i18n import i18n_patterns
urlpatterns = [
path("grappelli/", include("grappelli.urls")), # grappelli URLS
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls),
path("pages/", include("django.contrib.flatpages.urls")),
re_path(r"^api-auth/", include("rest_framework.urls")),
re_path(r"^accounts/", include("allauth.urls")),
re_path(r"^indicators/", include("indicators.urls", namespace="indicators")),
path("", TemplateView.as_view(template_name="landing.html"), name="landing"),
]
if settings.URL_PREFIX:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
E.g: Having this code above, I would like to have an url https://example.com/mycuteprefix/en/indicators/ instead of the usual https://example.com/en/mycuteprefix/indicators/.
Whenever I apply internationalization to the first urlpatterns I get an error. For example if I try this one bellow:
urlpatterns = [
path("grappelli/", include("grappelli.urls")), # grappelli URLS
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls),
path("pages/", include("django.contrib.flatpages.urls")),
re_path(r"^api-auth/", include("rest_framework.urls")),
re_path(r"^accounts/", include("allauth.urls")),
re_path(r"^indicators/", include("indicators.urls", namespace="indicators")),
]
urlpatterns += i18n_patterns(
path("", TemplateView.as_view(template_name="landing.html"), name="landing"),
)
if settings.URL_PREFIX:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
I have this error:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
File "/home/username/.virtualenvs/roject/lib/python3.5/site-packages/django/urls/conf.py", line 52, in include
'Using i18n_patterns in an included URLconf is not allowed.'
django.core.exceptions.ImproperlyConfigured: Using i18n_patterns in an included URLconf is not allowed.
How to achieve that ?

Make arbitrary url as homepage

I have such a urls.py configuration in project repository "forum"
# Project url
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r"^$", views.index, name="index"),
url(r'^article/', include('article.urls',namespace='article')),
]
and with article/urls.py as
#Article app's url config
urlpatterns = [
# show the article list
url(r"^list/(?P<block_id>\d+)$", views.article_list, name="article_list"),
I attempt to take "^article/list/1$" as home page instead of "views.index".
How to make it redirect to "^article/list/1$" when I issue request "127.0.0.1:8000"?
You can redirect from your views.index. In your views.py
from django.shortcuts import redirect
def index(request):
return redirect('article:article_list')
which should take you to article/list. You can include that block_id parameter in the redirect function.
try this
redirect(reverse('article:article_list', kwargs={'block_id':2}))
and make sure to add kwargs in function like this
article_list(request,**kwargs):
I assume you want to this to debug your article page.
You have two ways of doing this.
Either redirect your index view to article view
views.py
from django.shortcuts import redirect
def index(request):
#We force a redirect to article_list view, and we pass arguments.
#Notice it has to come first.
redirect ("article_list", article_list_argument_view=1)
#it will redirect to localhost:8000/article/list/1
'''
Your Home page code.
'''
Put the url directly before the include
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r"^$", views.index, name="index"),
#The order is important.
url(r'^article/list/1$', "article_list", {'article_list_argument_view':1})
url(r'^article/', include('article.urls',namespace='article')),
]

In Django, How do you write the url pattern for '/' and other root-based urls

I'm new to django, and one of the things that I'm still learning is url_patterns. I set up a pages app to handle the root path (http://www.mysite.com) as well as some static pages such as the about page. I figured out how to set up the url pattern for the root path, but I can't get the site to direct the path '/about' to the pages "about" view.
Here is my main urls.py
from django.conf.urls import patterns, include, url
from django.conf import settings
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls')),
url(r'^$', 'pages.views.root'),
url(r'^/', include('pages.urls')),
)
here is my pages urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('pages.views',
url(r'^about', 'about'),
)
Here is my pages views.py
# Create your views here.
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
def root(request):
return render_to_response('pages/root.html',context_instance=RequestContext(request))
def about(request):
return render_to_response('pages/about.html',context_instance=RequestContext(request))
If I change the main urls.py file to have r'^a/', include('pages.urls') then the path '/a/about' directs to the about action.. so I think it has to be an issue in the way i'm writing the url pattern in this file. But, I can't figure out how to change it. Can anyone help?
Figured out what the issue is. The proper url_pattern on the project level is:
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls')),
url(r'^$', 'pages.views.root'),
url(r'', include('pages.urls')),
)
When this is in place, '/about' and other simple paths direct properly.
Thanks everyone!
Try this, for url.py on the project level:
urlpatterns = patterns('',
# Examples:
url(r'^$', 'apps_name.views.home', name='home'),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
(r'^about/', include('about.urls')),
)
and then the url.py for the app about
urlpatterns = patterns('',
url(r'^$', direct_to_template, {"template": "about/about.html"}, name="about"),
)
Take into account that regular expression are evaluated from top to bottom, then if the path fits the regexp it will enter. To learn more about regexp google it or try the great book from Zed Shaw about regexps
Note that from Django version 2.0 the URL pattern has changed to use django.urls.path() Check Example here: link
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
About the url method:
url(r'^$', 'pages.views.root')
url is deprecated in Django 3.1, it's good to use re_path instead.
https://docs.djangoproject.com/en/3.1/ref/urls/#s-url
https://docs.djangoproject.com/en/3.1/ref/urls/#re-path
Note: The r'^$'pattern WON'T work with path function, and will give you a misleading error that the route could not be found.
You have to use re_path(r'^$', [etc]) every time you use a regular expression instead of a simple string in pattern.