[Django] Error 404 wenn DEBUG=False

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Hallo,

tja, wenn man anfängt, sich mit Django auseinanderzusetzen, treten eben so einige Fragen auf (sorry für die vielen Threads von mir :D ).

Ich habe das Problem, dass ich immer einen Error 500 bekomme, wenn ich in der settings.py DEBUG auf False stelle und im Admin-Bereich ein selbst definiertes Model aufrufen möchte.

In der Apache-Log erscheint folgende Meldung:

Code: Alles auswählen

[Wed Mar 25 13:11:35 2009] [info] [client 127.0.0.1] mod_wsgi (pid=18455, process='', application='localhost|'): Loading WSGI script '/home/stephan/Desktop/mysite/apache/mod.wsgi'., referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1] mod_wsgi (pid=18455): Exception occurred processing WSGI script '/home/stephan/Desktop/mysite/apache/mod.wsgi'., referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1] Traceback (most recent call last):, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/core/handlers/wsgi.py", line 241, in __call__, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     response = self.get_response(request), referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/core/handlers/base.py", line 122, in get_response, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     return self.handle_uncaught_exception(request, resolver, sys.exc_info()), referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/core/handlers/base.py", line 166, in handle_uncaught_exception, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     return callback(request, **param_dict), referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/views/defaults.py", line 23, in server_error, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     t = loader.get_template(template_name) # You need to create a 500.html template., referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/template/loader.py", line 81, in get_template, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     source, origin = find_template_source(template_name), referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]   File "/usr/lib64/python2.6/site-packages/django/template/loader.py", line 74, in find_template_source, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1]     raise TemplateDoesNotExist, name, referer: http://localhost/admin/
[Wed Mar 25 13:11:36 2009] [error] [client 127.0.0.1] TemplateDoesNotExist: 500.html, referer: http://localhost/admin/
Stelle ich DEBUG auf True, funktioniert alles wunderbar und ich kann im Admin-Bereich alles nutzen.

Was ich nicht nachvollziehen kann: Warum funktioniert es, wenn ich die DEBUG-Einstellung aktiviere? Welche "Schalter" werden da unter der Haube noch umgelegt?

Mawilo
Zuletzt geändert von Mawilo am Freitag 27. März 2009, 18:27, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Weil im Debug-Modus statt eine 500er Fehlerseite anzuzeigen eine hübsche Traceback-Seite kommt mit einem vollständigen Traceback, lokalen Variablen zum aufklappen etc. Da wird die ``500.html`` gar nicht erst ausgewertet.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Aber wenn ich den Debug-Modus einschalte, bekomme ich keine Fehler und alles funktioniert :?

Edit: Es wird natürlich ein 404er ausgegeben. Der Eintrag in der Apache-Log lag daran, dass ich lokal noch keine 404.html erstellt hatte.

Es wird also vom Server ein 404-Fehler ausgegeben aber in der Apache-Log kein Fehler verzeichnet. Im Debug-Modus ist alles wunderschön (ohne jegliche Fehler).
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Ich bin nicht viel weiter gekommen ...

Um den Fehler besser zu ermitteln, habe ich in der Datei ../django/core/handlers/base.py die Zeilen 117 und 118 nach der else-Anweisung wiederholt. Nun bekomme ich auch bei der Einstellung DEBUG=False bei einem 404-Fehler eine vernünftige Ausgabe.

Da steht jetzt:

Code: Alles auswählen

Using the URLconf defined in myproject.urls, Django tried these URL patterns, in this order:

   1. ^admin/ ^$
   2. ^admin/ ^logout/$
   3. ^admin/ ^password_change/$
   4. ^admin/ ^password_change/done/$
   5. ^admin/ ^jsi18n/$
   6. ^admin/ ^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$
   7. ^admin/ ^(?P<app_label>\w+)/$
   8. ^admin/ ^auth/group/
   9. ^admin/ ^auth/user/
  10. ^admin/ ^sites/site/

The current URL, admin/hauptseite/container/, didn't match any of these.
Wenn ich jetzt den Debugmodus wieder einschalte, wird diese URL auf einmal gefunden und alles wunderschön angezeigt :?

Das ist für mich überhaupt nicht nachvollziehbar.
Hat dazu jemand einen Tip für mich?

Mawilo
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Das Problem hatte ich bei mir auch - mehrmals - und es nach einigen Nachmittagen des Debuggings immer noch nicht umgehen können.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Du musst eine Datei "404.html" in einem deiner template-Ordner anlegen. Diese wird für einen HTTP 404 benötigt. Da du diese Datei nicht hast, ist das ein Server-Fehler, der zu einem HTTP 500 führt und dafür bräuchtest du eine "500.html"-Datei, die du auch nicht hast.

Siehe http://docs.djangoproject.com/en/dev/to ... rror-views

Stefan
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Ich habe mittlerweile eine 500 und eine 404 Datei. Das Problem ist aus meiner Sicht, dass die Url nicht gefunden wird.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ach so.

Ist "hauptseite" der Name einer Anwendung und "container" der Name eines Modells darin, welches du für das Admin-UI registriert hast? Sieht nicht so aus. Deine Liste zeigt nur das auth und das sites-Modul. Hast du das autodiscover in urls.py auch eingeschaltet? Hast du deine Anwendung in settings.py eingetragen?

Stefan
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Da ich in twischen verschiedene Dinge umbenannt habe, hier mal der aktuelle Stand:
Projektname: spindler
Applikationname: mainpage
Models: Beitrag, Container
ModelsAdmin: BeitragAdmin, ContainerAdmin

Beide Models werden registriert:

Code: Alles auswählen

admin.site.register(Beitrag, BeitragAdmin)
admin.site.register(Container, ContainerAdmin)
Ich habe in der Datei ../django/contrib/admin/sites.py
nach Zeile 87 folgende aAusgabe eingefügt:

Code: Alles auswählen

f = open('/tmp/error.tmp', 'w+')
f.write(str(admin_class))
f.write(str(model))
f.close()
Die Ausgabe in der Datei ist:

Code: Alles auswählen

<class 'spindler.mainpage.models.ContainerAdmin'><class 
'spindler.mainpage.models.Container'>
Also werden die Models auch registriert (ich habe nur eins im Admin-Bereich angeklickt, daher steht nur das eine Model in der Datei)
Meine urls.py:

Code: Alles auswählen

# -*- coding: utf-8 -*-
from django.conf.urls.defaults import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
)
Meine settings.py (Auszug):

Code: Alles auswählen

DEBUG = False
MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.utils.debug.UserBasedExceptionMiddleware',
)
ROOT_URLCONF = 'spindler.urls'
TEMPLATE_DIRS = (
    '/home/stephan/Desktop/Projekte/Webseiten/spindler/mainpage',
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'spindler.mainpage',
    'django.contrib.admin',
)
Im Admin-Bereich sind die zwei Models auch zu sehen
Bild
Wenn ich jetzt auf ein Model klicke oder auf Hinzufügen/Ändern, erhalte ich diese Meldung (ich habe die Datei ../django/core/handlers/base.py manipuliert, damit ich auch im ausgeschaltenen Debug-Modus die Fehlermeldungen sehe):

Code: Alles auswählen

Using the URLconf defined in spindler.urls, Django tried these URL patterns, in this order:
   1. ^admin/ ^$
   2. ^admin/ ^logout/$
   3. ^admin/ ^password_change/$
   4. ^admin/ ^password_change/done/$
   5. ^admin/ ^jsi18n/$
   6. ^admin/ ^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$
   7. ^admin/ ^(?P<app_label>\w+)/$
   8. ^admin/ ^auth/group/
   9. ^admin/ ^auth/user/
  10. ^admin/ ^sites/site/
The current URL, admin/mainpage/beitrag/add/, didn't match any of these.
Wie schon gesagt - Wenn ich den Debugmodus zuschalte, ist alles in bester Ordnung

Ich hoffe, jemand hat noch einen Tip für mich
Mawilo
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

In der Liste der URL-Pattern in der Fehlermeldung fehlt offensichtlich "^mainpage/beitrag/". Irgendwie scheint deine Registrierung nicht zu funktionieren. Allerdings wird die Seite im Admin-UI angezeigt.

Was ist denn das für eine "UserBasedExceptionMiddleware"? Könnte die stören? Du sagst, du hast die Zeilen 117 und 118 nach der else-Anweisung wiederholt. Bei mir sind dies aber Zeile 114 und 115:

Code: Alles auswählen

from django.views import debug
return debug.technical_404_response(request, e)
und das "else" steht in Zeile 116. Ich habe hier r10176.

Wenn ich mir get_urls() aus contrib/admin/sites.py anschaue, sehe ich in Zeile 191, wie die Modelle zum URL-Pattern hinzugefügt werden. Passiert dies bei dir auch? Vielleicht baust du da mal ein print ein und prüfst die Werte. Was steht in "self._registry"? Was in "urlpatterns" (Zeile 197)? Bei mir sehe ich da eine längere Liste, die so endet:

Code: Alles auswählen

<RegexURLResolver [<RegexURLPattern admin_a_b_changelist ^$>,
<RegexURLPattern admin_a_b_add ^add/$>, 
<RegexURLPattern admin_a_b_history ^(.+)/history/$>,
<RegexURLPattern admin_a_b_delete ^(.+)/delete/$>,
<RegexURLPattern admin_a_b_change ^(.+)/$>] ^a/b/>
Warum da aber etwas im DEBUG-Modus funktionieren soll und ohne nicht, kann ich nicht nachvollziehen.

Stefan
Benutzeravatar
Mawilo
User
Beiträge: 452
Registriert: Sonntag 22. Februar 2004, 10:58
Wohnort: Sachsen
Kontaktdaten:

Ich habe jetzt die Lösung für mein Problem :D

Die Registrierung darf nicht in der Datei model.py , sondern muss in der Datei admin.py erfolgen.
http://docs.djangoproject.com/en/dev/ref/contrib/admin/

Meine admin.py sieht so aus (ich verwende den tiny-mce-editor in der Admin-Oberfläche):

Code: Alles auswählen

# -*- coding: utf-8 -*-
from django.contrib import admin
from spindler.mainpage.models import Beitrag, Container

class BeitragAdmin(admin.ModelAdmin):
    class Media:
        js = ('js/tiny_mce/tiny_mce.js','js/tiny_mce/textareas.js',)

class ContainerAdmin(admin.ModelAdmin):
    class Media:
        js = ('js/tiny_mce/tiny_mce.js', 'js/tiny_mce/textareas.js',)

admin.site.register(Beitrag, BeitragAdmin)
admin.site.register(Container, ContainerAdmin)
Die Lösung hat mir Karen Tracey in der Django-Mailingliste genannt.
If you put the calls in models.py first it is intdeterminate when that file will be loaded, so unpredictable when the registrations will happen. I'd guess when you run with DEBUG set to True your models.py hapens to be loaded early on, but not when you run with DEBUG=False. Another problem with register calls in models.py is that if/when models.py file is imported multiple times, you will get AlreadyRegistered exceptions on the register calls, since the models were registered the first time models.py was loaded.

Placing the registrations in admin.py and calling admin.autodiscover() from urls.py ensures that the admin registrations happen only once, at a predictable time.
Grüße
Mawilo
Antworten