Django, özel bir 500/404 hata sayfası oluşturuyor


106

Burada bulunan öğreticiyi tam olarak takip ederek , özel bir 500 veya 404 hata sayfası oluşturamıyorum. Hatalı bir url yazarsam, sayfa bana varsayılan hata sayfasını veriyor. Özel bir sayfanın görünmesini engelleyecek herhangi bir şey var mı?

Dosya dizinleri:

mysite/
    mysite/
        __init__.py
        __init__.pyc
        settings.py
        settings.pyc
        urls.py
        urls.pyc
        wsgi.py
        wsgi.pyc
    polls/
        templates/
            admin/
                base_site.html
            404.html
            500.html
            polls/
                detail.html
                index.html
        __init__.py
        __init__.pyc
        admin.py
        admin.pyc
        models.py
        models.pyc
        tests.py
        urls.py
        urls.pyc
        view.py
        views.pyc
    templates/
    manage.py

mysite / settings.py içinde bunları etkinleştirdim:

DEBUG = False
TEMPLATE_DEBUG = DEBUG

#....

TEMPLATE_DIRS = (
    'C:/Users/Me/Django/mysite/templates', 
)

mysite / anketler / urls.py içinde:

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
    url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)

Gerekli başka bir kodu gönderebilirim, ancak bozuk bir URL kullanırsam özel bir 500 hata sayfası almak için neyi değiştirmeliyim?

Düzenle

ÇÖZÜM: Ek bir

TEMPLATE_DIRS

settings.py içinde ve bu soruna neden oluyordu


1
Kodumda Hata Ayıklama Yanlış olarak ayarlandı
— Zac


1
Bu cevabı sadece özel bir şablon yapmanın yolunu ararken buldum ve bana çok yardımcı olan biraz Django dokümantasyonu paylaşmak istedim; docs.djangoproject.com/en/1.7/ref/views/…
— Blackeagle52

Benimki template_dirs ayarı olmadan çalıştı.
— Programmingjoe

1
İlk satırdaki bağlantı Django'nun 404 sayfasına götürdüğünde ironi için puan. Sanırım var olmayan bir Django sürümü için bir eğitim sayfasına yönlendiriyor. İşte Django 2.0 eğitim sayfasına bağlantı: docs.djangoproject.com/en/2.0/intro/tutorial03
— andrewec

Yanıtlar:


121

Ana Altında views.pyeklenti kendi özel aşağıdaki iki görüş uygulanması ve sadece kurmak şablonları 404.html ve 500.html ekranda etmek istediğimiz şeyi.

Bu çözümle, özel kodun eklenmesi gerekmez. urls.py

İşte kod:

from django.shortcuts import render_to_response
from django.template import RequestContext


def handler404(request, *args, **argv):
    response = render_to_response('404.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render_to_response('500.html', {},
                                  context_instance=RequestContext(request))
    response.status_code = 500
    return response

Güncelleme

handler404ve içinde handler500bulunan Django dize yapılandırma değişkenleri dışa aktarılır django/conf/urls/__init__.py. Yukarıdaki yapılandırmanın işe yaramasının nedeni budur.

Yukarıdaki yapılandırmanın çalışmasını sağlamak için, urls.pydosyanızda aşağıdaki değişkenleri tanımlamalı ve dışa aktarılan Django değişkenlerini aşağıdaki gibi bu Django işlevsel görünümlerinin tanımlandığı Python yoluna yönlendirmelisiniz:

# project/urls.py

handler404 = 'my_app.views.handler404'
handler500 = 'my_app.views.handler500'

Django 2.0 güncellemesi

İşleyici görünümleri için imzalar Django 2.0'da değiştirildi: https://docs.djangoproject.com/en/2.0/ref/views/#error-views

Yukarıdaki gibi görünümleri kullanırsanız, handler404 şu mesajla başarısız olur:

"handler404 () beklenmedik bir anahtar kelime bağımsız değişkeni 'istisna' aldı"

Böyle bir durumda görünümlerinizi şu şekilde değiştirin:

def handler404(request, exception, template_name="404.html"):
    response = render_to_response(template_name)
    response.status_code = 404
    return response

Bu benim için oldukça iyi çalışıyor gibi görünüyordu, ancak bazı nedenlerden dolayı request.user 404 şablonunda iyi görünüyor, ancak 500 şablonunda hiç de değil (ve neredeyse aynılar) - burada soru yayınladı: stackoverflow.com/ sorular / 26043211 /…
— Gravity Grave

1
Merak ettiğim başka bir şey - ya yönetici arka ucunu kullanırsanız ve bunlar için ayrı şablonlar kullanmak isterseniz? Bildiğim kadarıyla, yöneticinin bu kod parçasını geçersiz kılıp yerleştirebileceği bir views.py yok.
— Gravity Grave

11
@GravityGrave, 500 sunucu hatası bildirdiği için 500 templateolmayacak request.user, bu nedenle sunucu hiçbir şey sunamayacak .
— Aaron Lelevier

5
Django 1.9 ile benim için işe yaramadı; (Belki yanlış bir şey yapıyorum. Handler404 django özel ad mı? Django tam olarak bu görünümü çağırması gerektiğini nasıl bilebilir?
— deathangel908

1
Cevabı yorumunuza göre güncelledim. Maalesef güncelleme çok geç. Umarım bu yardımcı olur.
— Aaron Lelevier

71

Resmi cevap:

Özel hata görünümlerinin nasıl ayarlanacağına ilişkin resmi belgelerin bağlantısı aşağıda verilmiştir:

https://docs.djangoproject.com/en/stable/topics/http/views/#customizing-error-views

URLconf'unuza buna benzer satırlar eklemenizi söylüyor (bunları başka bir yere ayarlamanın hiçbir etkisi olmayacak):

handler404 = 'mysite.views.my_custom_page_not_found_view'
handler500 = 'mysite.views.my_custom_error_view'
handler403 = 'mysite.views.my_custom_permission_denied_view'
handler400 = 'mysite.views.my_custom_bad_request_view'

Ayarı değiştirerek CSRF hata görünümünü de özelleştirebilirsiniz CSRF_FAILURE_VIEW.

Varsayılan hata işleyicileri:

Varsayılan hata işleyicileri belgeleri okuyarak It değerinde, page_not_found, server_error, permission_deniedve bad_request. Onlar sırasıyla bunları bulabilirsiniz Varsayılan olarak, onlar bu şablonları kullanın: 404.html, 500.html, 403.html, ve 400.html.

Dolayısıyla, tek yapmak istediğiniz güzel hata sayfaları TEMPLATE_DIRSyapmaksa, bu dosyaları bir dizinde oluşturun, URLConf'u hiç düzenlemenize gerek yoktur. Hangi bağlam değişkenlerinin mevcut olduğunu görmek için belgeleri okuyun.

Django 1.10 ve sonraki sürümlerde, varsayılan CSRF hata görünümü şablonu kullanır 403_csrf.html.

Anladım:

DEBUGBunların çalışması için False olarak ayarlanması gerektiğini unutmayın , aksi takdirde normal hata ayıklama işleyicileri kullanılacaktır.


1
Ekledim ama işe yaramıyor. İşleyici404 eklendi ve diğerleri görünümlerimde doğru yerleri işaret ediyor, ancak yine de çalışmıyor, varsayılan
— 404'ü

Django 1.9'u kullanmak ve sadece 500.html vb. Şablonlar eklemek standart sayfalar yerine bunları gösterir. Güzel kolay düzeltme.
— Curtis

2
Gotcha bana yardım etti. Bu değişiklikleri, herhangi bir istemciden gelen http talebini kabul etmek için settings.py, DEBUG = False ve ALLOWED_HOSTS = ['0.0.0.0'] olarak ayarlayın.
— shaffooo

1
Başka birinin dünyanın neresinde URLconf olduğunu merak etmesi ihtimaline karşı, işte burada
— Arthur Tarasov

@ArthurTarasov Evet, urls.py dosyasını onunla birlikte referans olarak kullanmak daha iyi olurdu haha.
— Zack Plauché

40

Bu satırları urls.py'ye ekleyin

urls.py

from django.conf.urls import (
handler400, handler403, handler404, handler500
)

handler400 = 'my_app.views.bad_request'
handler403 = 'my_app.views.permission_denied'
handler404 = 'my_app.views.page_not_found'
handler500 = 'my_app.views.server_error'

# ...

ve özel görünümlerimizi views.py'de uygulayın.

views.py

from django.shortcuts import (
render_to_response
)
from django.template import RequestContext

# HTTP Error 400
def bad_request(request):
    response = render_to_response(
        '400.html',
        context_instance=RequestContext(request)
        )

        response.status_code = 400

        return response

# ...

5
Neden handler400sadece üzerine yazmak için içe aktarıyorsunuz handler400 = 'myapp.views.bad_request'?
— Flimm


5
İşleyicileri geçersiz kılmak için buraya aktarmanıza gerek yoktur.
— funkotron

1
Kullanmamalısın render_to_response. Dokümanlardan: "Önerilmiyor ve büyük olasılıkla gelecekte kullanımdan kaldırılacak."
— Timmy O'Mahony

Django 1.10 için, render_to_responsekullanımdan kaldırılacağı gibi, aşağıdakilere bakın ( renderbunun yerine kullanın): stackoverflow.com/questions/44228397/…
— mrdaliri

21

Referans verdiğiniz sayfadan:

Http404'ü bir görünüm içinden yükselttiğinizde, Django 404 hatalarını işlemeye ayrılmış özel bir görünüm yükleyecektir. Bunu, Python noktalı sözdiziminde bir dize olan kök URLconf'unuzda (ve yalnızca kök URLconf'unuzda; işleyici404'ü başka herhangi bir yerde ayarlamanın hiçbir etkisi olmayacak) değişken işleyici404'ü arayarak bulur - normal URLconf geri aramalarının kullandığı formatla aynı. Bir 404 görünümünün özel bir yanı yoktur: Bu sadece normal bir görünümdür.

Bu yüzden urls.py dosyanıza buna benzer bir şey eklemeniz gerektiğine inanıyorum:

handler404 = 'views.my_404_view'

ve handler500 için benzer.


Mike nasıl görünüyor? Bugün Django'yu kullandığım ilk günüm ve hala iplere takılıyorum
— Zac

2
@JimRilye Görünümlerinize uygun bir 500 işlevi eklemeniz ve ardından bu değişkenle ona başvurmanız gerekir. Bu nedenle, urlpatterns = ...çizginizin üstüne, yazan bir satır ekleyin handler500 = 'views.handle500've ardından def handle500(request):views.py dosyanıza 500.html dosyanızı gösteren bir satır ekleyin .
— Mike Pelley

18

İhtiyacınız olan tek şey, siteniz için bazı süslü hata mesajları içeren özel sayfalar göstermekse DEBUG = False, şablon dizininize 404.html ve 500.html adlı iki şablon ekleyin ve bir 404 veya 500 olduğunda bu özel sayfaları otomatik olarak alacaktır. yükseltilir.


1
Bu, şunun gibi bir şeye sahip olduğunuzdan emin olun: 'DIRS': [os.path.join(BASE_DIR, '<project_name>/templates')]içindeki ŞABLONLAR listenizde settings.py.
— eric

12

In Django 2. * Eğer bu inşaat kullanabilirsiniz views.py

def handler404(request, exception):
    return render(request, 'errors/404.html', locals())

In settings.py

DEBUG = False

if DEBUG is False:
    ALLOWED_HOSTS = [
        '127.0.0.1:8000',
        '*',
    ]

if DEBUG is True:
    ALLOWED_HOSTS = []

In urls.py

# https://docs.djangoproject.com/en/2.0/topics/http/views/#customizing-error-views
handler404 = 'YOUR_APP_NAME.views.handler404'

Genellikle default_app oluşturuyorum ve site genelindeki hataları, içindeki bağlam işlemcilerini ele alıyorum .


Benim için çalış. Ama nedir exception?
— zeleven

Dokümantasyon bağlantısına göre: docs.djangoproject.com/en/2.1/ref/urls/… .
— Yazılıdır

1
Benim için Django 3.0'da çalıştı . Ama nedir locals()? Dosya yalnızca gösterir pass.
— ENCHANCE

9

settings.py:

DEBUG = False
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = ['localhost']  #provide your host name

ve sadece eklemek 404.htmlve 500.htmlşablonlar klasöründeki sayfaları. kaldırmak 404.htmlve 500.htmlanketler uygulamasında şablonlardan.


Şu mesajın kullanımı raise Http404('msg'): stackoverflow.com/a/37109914/895245 {{ request_path }} de mevcuttur.
— Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功


7

Bir hatayı olun Django yol stack.In bazı kastetmek templates.I yükleniyor yerden hatası sayfasında öğrenmek template_dir bu html sayfaları eklemek 500.html , 404.html . Bu hatalar meydana geldiğinde ilgili şablon dosyaları otomatik olarak yüklenecektir.

400 ve 403 gibi diğer hata kodları için de sayfalar ekleyebilirsiniz .

Umarım bu yardım !!!


6

Django'da 3.x, kabul edilen cevap işe yaramayacaktır çünkü render_to_responsetamamen kaldırılmıştır ve kabul edilen cevabın çalıştığı versiyondan bu yana bazı değişiklikler yapılmıştır.

Bazı başka cevaplar da var ama ben biraz daha net bir cevap sunuyorum:

Ana urls.pydosyanızda:

handler404 = 'yourapp.views.handler404'
handler500 = 'yourapp.views.handler500'

In yourapp/views.pydosyası:

def handler404(request, exception):
    context = {}
    response = render(request, "pages/errors/404.html", context=context)
    response.status_code = 404
    return response


def handler500(request):
    context = {}
    response = render(request, "pages/errors/500.html", context=context)
    response.status_code = 500
    return response

Alınan emin olun render()içinde yourapp/views.pydosyanın:

from django.shortcuts import render

Yan Not: render_to_response()Django olarak kullanımdan kaldırıldı 2.xve tamamen verision kaldırılmıştır 3.x.


5

Tek satır olarak (404 genel sayfa için):

from django.shortcuts import render_to_response
from django.template import RequestContext

return render_to_response('error/404.html', {'exception': ex},
                                      context_instance=RequestContext(request), status=404)

1
Ve nerede kullanılır?
— Sami


4
# views.py
def handler404(request, exception):
    context = RequestContext(request)
    err_code = 404
    response = render_to_response('404.html', {"code":err_code}, context)
    response.status_code = 404
    return response

# <project_folder>.urls.py
handler404 = 'todo.views.handler404' 

Bu, django 2.0'da çalışır

Özelinizi 404.htmluygulama şablonları klasörüne eklediğinizden emin olun .


4

Django 3.0

İşte hata görünümlerinin nasıl özelleştirileceği bağlantısı

İşte bir görünümün nasıl işleneceği bağlantısı

içinde urls.py(proje klasöründe ana one), koyun:

handler404 = 'my_app_name.views.custom_page_not_found_view'
handler500 = 'my_app_name.views.custom_error_view'
handler403 = 'my_app_name.views.custom_permission_denied_view'
handler400 = 'my_app_name.views.custom_bad_request_view'

ve bu uygulamada ( my_app_name) şunu girin views.py:

def custom_page_not_found_view(request, exception):
    return render(request, "errors/404.html", {})

def custom_error_view(request, exception=None):
    return render(request, "errors/500.html", {})

def custom_permission_denied_view(request, exception=None):
    return render(request, "errors/403.html", {})

def custom_bad_request_view(request, exception=None):
    return render(request, "errors/400.html", {})

NOT: error/404.htmldosyalarınızı projeler (uygulamalara değil) şablon klasörüne templates/errors/404.htmlyerleştirirseniz yoldur, bu nedenle lütfen dosyaları istediğiniz yere yerleştirin ve doğru yolu yazın.

NOT 2: Sayfayı yeniden yükledikten sonra, hala eski şablonu görüyorsanız, değiştirin settings.py DEBUG=True, kaydedin ve ardından tekrar False(sunucuyu yeniden başlatmak ve yeni dosyaları toplamak için).


Ek not: DEUB=FalseStatik dosyalarınızda çalışıyorsanız , özel hata şablonu değişikliklerinizin önizlemesini yapamayacağınız şekilde bunu yapmak sunulmayabilir. ./manage.py runserver --insecureDjango'yu onlara hizmet etmeye zorlamak için kullanın .
— Rob

3

İçin hata şablonları taşımayı deneyin .../Django/mysite/templates/?

Bundan emin değilim, ancak bunların web sitesi için "küresel" olması gerektiğini düşünüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.