I have got installed Django 1.9.2 and want to use a custom view to handle error 404. I am trying to do this:
# myapp/urls.py
from django.conf.urls import url, handler404
from django.views.generic.base import RedirectView
from django.core.urlresolvers import reverse_lazy
import views
urlpatterns = [
url(r'^not-found/$', views.NotFoundView.as_view(), name='not_found'),
]
#handler404 = RedirectView.as_view(url=reverse_lazy('not_found'))
handler404 = 'myapp.views.NotFoundView.not_found_handler'
# myapp/views/NotFoundView.py
from django.http import HttpResponse
class NotFoundView(object):
#classmethod
def as_view(cls):
return cls.handler
#classmethod
def handler(cls, request):
return HttpResponse(u"My error 404", status=404)
def not_found_handler(request, exception, template_name='404.html'):
return HttpResponse(u"New handler 404", status=404)
In other words, I overrode handler404 with RedirectView initialized by the URL to my custom view called NotFoundView. But unfortunately it didn't work, I got the standard Django's error 404 instead of my custom one. What am I doing wrong?
Related
When I am trying to send data to my localhost using the ajax call in popup.js, I am getting an error :
Not Found: /sentiment/
"GET /sentiment/?number=219 HTTP/1.1" 404 1714
Even though I checked the url and it is correct and exists.
This is the snippet of my ajax call:
$.ajax({
url:"http://127.0.0.1:8000/sentiment/",
dataType:"json",
data:{
number:newTotal
},
crossDomain:true,
success:function(json)
{
$('#total').text(json.number)
}
})
and this is my urls.py file in django app :
from django.contrib import admin
from django.urls import path,include
from DetectHate import views
from django.urls import path,re_path
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^sentiment/$', views.sentiment,name="sentiment"),
]
and this is my views.py file -
import json
from django.http import Http404,HttpResponse
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def sentiment(request):
if request.is_ajax():
var=request.POST.get('number')+5
data={}
data['number']=var+5
return HttpResponse(json.dumps(data),content_type='application/json')
else:
raise Http404
When I load an inexistent url the page 404 does not show instead the page 500 is shown. Below my setups. Could you please guide me to turn Django on to show 404 page? Thanks
Ubuntu Server 16.04 ; Python 3.5.2 ; Django 2.0
cat contatoproj/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from django.conf.urls import include
from django.conf.urls import handler404, handler500
from contatoapp import views
from contatoapp import views as myapp_views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.index, name='index'),
url(r'^contato', views.contato, name='contato'),
]
handler404 = myapp_views.error_404
handler500 = myapp_views.error_500
cat contatoapp/views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext
from django.contrib import messages
from django.core.mail import send_mail, BadHeaderError
from django.http import HttpResponse, HttpResponseRedirect
from django.conf import settings
from contatoapp.forms import ContatoForm
def error_404(request):
data = {}
return render(request, 'ops404.html', data)
def error_500(request):
data = {}
return render(request, 'ops500.html', data)
$ ls -la templates/ops*
-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:31 templates/ops404.html
-rwxr-xr-x 1 admweb admweb 614 Dec 13 15:29 templates/ops500.html
cat contatoproj/settings.py
DEBUG = False
ALLOWED_HOSTS = ['*']
If you're getting a 500 error for missing pages then it's because there is an error happening when Django tries to handle that response.
From looking at your code, this is probably because your 404 error handler is wrongly defined - it needs to accept a second exception argument which is missing. Change it to:
def error_404(request, exception):
data = {}
return render(request, 'ops404.html', data)
Also note that you should be returning a HttpResponseNotFound, otherwise the client will not receive a HTTP 404 response.
You're getting an error in the process of handling the 404. This means you're getting a 500 instead.
As you're not doing anything special in your 500 or 404 views, you don't need to explicitly define the handler views for them using handler404/500.
Instead, you should define 404.html and 500.html in your templates directory. Django will use these instead of the default templates, and you don't need to re-implement the 404 and 500 views correctly.
I have dir template with all templates, and I have dir errors, with all templates with errors 404.html.
I found the following old solution:
In urls.py my app I wrote
from django.conf.urls import (handler400, handler403, handler404, handler500)
handler404 = 'my_app.views.page_not_found'
And in view my app
from django.shortcuts import (render_to_response)
from django.template import RequestContext
def page_not_found(request):
response = render_to_response(
'errors/404.html',
context_instance=RequestContext(request))
response.status_code = 404
return response
But I use Django 1.11 and this doesn't work.
If you follow the docs
You should return HttpResponseNotFound which is the same as HttpResonse except for status code. It worked for me.
def bad_request(request):
response = render_to_response(
'errors/404.html'
)
return HttpResponseNotFound(response.content)
In my urls.py I have set handler404 to CustomErrorView. CustomErrorView is a generic view which generates a template for an error based on the error message and error code that it receives.
Since the handler404 is only raised in the case of a 404 error, how can I send the errorcode = 404 kwarg to CustomErrorView whenever it is raised?
Already tried-
handler404 = CustomErrorView(errorcode = 404)
This causes an "Expected one positional argument, none given error."
handler404 = CustomErrorView(request, errorcode = 404)
This causes a NameError (Name 'request' is not defined)
My urls.py:
from django.conf.urls import url, include
from django.contrib import admin
from blog_user.views import home, create_error_view
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', home),
url(r'^', include('user_manager.urls')),
]
handler404 = create_error_view(error = 404)
handler500 = create_error_view(error = 500)
My views.py (after using the modifications recommended by #knbk) :
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseNotFound
def create_error_view(error = 404, mybad = False):
def custom_error_view(request, error, mybad):
''' Returns a generic error page. Not completed yet. error code and messages are supposed to be modular so that it can be used anywhere for any error in the page.'''
content = "Incorrect url"
context= {
'error': error,
'content':content,
'mybad':mybad
}
response = render(request, 'error.html', context=context, status=error)
return HttpResponse(response)
return custom_error_view
You can use a function closure to create the view function:
def create_error_view(error_code):
def custom_error_view(request, *args, **kwargs):
# You can access error_code here
return custom_error_view
Then just call create_error_view to set the handler:
handler404 = create_error_view(error_code=404)
Or you can use functools.partial(), which basically does the same:
from functools import partial
handler404 = partial(custom_error_view, error_code=404)
views.py
from django import HttpResponse
def hello(request):
return HttpResponse("Hello world ! ")
Request Method: GET
Request URL: http://127.0.0.1:8000/hello/
Django Version: 1.3.1
Exception Type: ImportError
Exception Value:
cannot import name HttpResponse
You can try this: from django.http import HttpResponse
You are importing from wrong location
django.http this is right location from django.http import HttpResponse
Changing from django to django.http in the views.py file works in most cases, if it doesn't check the urls.py file in the project dir and make sure that :
the path() to your view is imported correctly
that it is above the path('admin/', admin.site.urls) in the urlpatterns list