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.