Admin URLs not working correctly

2,108 views
Skip to first unread message

Michael Williamson

unread,
Sep 27, 2009, 4:41:43 PM9/27/09
to Django users
Admin URLs do not seem to behaving themselves for me. My urls.py looks
like this:

from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
(r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
(r'^blog/', include('mikesite.blog.urls')),
(r'^admin/', include(admin.site.urls)),
)

When DEBUG=True, the admin interface works fine. When DEBUG=False, I
get 404 errors when I attempt to access some URLs, such as /admin/blog/
comment/add/, yet others, such as /admin/blog/ or /admin/auth/user/
add/ work just fine.

After some digging around, I found that setting DEBUG=True fixes the
problem since this enables validation in django.contrib.admin.sites
(lines 69 to 72). When DEBUG is True,
django.contrib.admin.validation.validate is called, which in turn
calls django.db.models.get_apps().

Putting django.db.models.get_apps() at the top of urls.py fixes the
problem e.g.

from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

from django.db import models
models.get_apps()

urlpatterns = patterns('',
(r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
(r'^blog/', include('mikesite.blog.urls')),
(r'^admin/', include(admin.site.urls)),
)

I can also fix the problem by slightly changing the admin regex like
so:

from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
(r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
(r'^blog/', include('mikesite.blog.urls')),
(r'^admin/.*', include(admin.site.urls)),
)

I'm using Django 1.1.

If anybody could shed some light on this, it would be greatly
appreciated.

Mike

Karen Tracey

unread,
Sep 27, 2009, 5:23:28 PM9/27/09
to django...@googlegroups.com
On Sun, Sep 27, 2009 at 4:41 PM, Michael Williamson <mikerwi...@yahoo.co.uk> wrote:

Admin URLs do not seem to behaving themselves for me. My urls.py looks
like this:

   from django.conf.urls.defaults import *

   from django.contrib import admin
   admin.autodiscover()

   urlpatterns = patterns('',
       (r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
       (r'^blog/', include('mikesite.blog.urls')),
       (r'^admin/', include(admin.site.urls)),
   )

When DEBUG=True, the admin interface works fine. When DEBUG=False, I
get 404 errors when I attempt to access some URLs, such as /admin/blog/
comment/add/, yet others, such as /admin/blog/ or /admin/auth/user/
add/ work just fine.

You've listed one that doesn't work -- /admin/blog/comment/add.  Is comment listed as a model at all under /admin/blog when things break?  Does /admin/blog/comment/ work to show a change list of comment models?  Can you bring up a detail page on an existing one?  Successfully change it?  I'm trying to figure out if something has happened to cause the comment model to disappear entirely from admin or if it's still partly there but broken.  If only partially broken, what parts, exactly, are broken?
 

After some digging around, I found that setting DEBUG=True fixes the
problem since this enables validation in django.contrib.admin.sites
(lines 69 to 72). When DEBUG is True,
django.contrib.admin.validation.validate is called, which in turn
calls django.db.models.get_apps().

Putting django.db.models.get_apps() at the top of urls.py fixes the
problem e.g.

   from django.conf.urls.defaults import *

   from django.contrib import admin
   admin.autodiscover()

   from django.db import models
   models.get_apps()


It surprises me that putting something after the call to autodiscover() could fix the problem.  It sounds like the call to autodiscover() is running into trouble and not ending up registering all your models (causing 404 errors on some attempts to access them).  I don't see how putting something after the call to autodiscover() would fix that. 

This type of workaround sounds vaguely like some posted for this ticket: http://code.djangoproject.com/ticket/10405.  You might read through that and see if your models share characteristics with those in use by people who have posted there.  If so, the root problem may be similar. 

 
   urlpatterns = patterns('',
       (r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
       (r'^blog/', include('mikesite.blog.urls')),
       (r'^admin/', include(admin.site.urls)),
   )

I can also fix the problem by slightly changing the admin regex like
so:

   from django.conf.urls.defaults import *

   from django.contrib import admin
   admin.autodiscover()

   urlpatterns = patterns('',
       (r'^$', 'django.views.generic.simple.redirect_to', {'url': '/
blog/'}),
       (r'^blog/', include('mikesite.blog.urls')),
       (r'^admin/.*', include(admin.site.urls)),
   )


Again, I don't understand how that would help.  Someone did recently open a ticket (http://code.djangoproject.com/ticket/11918) saying that switching to the older url pattern for admin worked with DEBUG=False where the current one did not, but you haven't actually switched all the way back to the old pattern here.  Plenty of people are using the 1.1 pattern without trouble, so there's something in the configs where problems arise that is different.  We've not gotten enough specifics on the failing configs for me to have any idea what it might be.  A small, recreatable example would help.
 
Karen

Michael Williamson

unread,
Sep 27, 2009, 5:33:41 PM9/27/09
to Django users
> You've listed one that doesn't work -- /admin/blog/comment/add. Is comment
> listed as a model at all under /admin/blog when things break? Does
> /admin/blog/comment/ work to show a change list of comment models? Can you
> bring up a detail page on an existing one? Successfully change it? I'm
> trying to figure out if something has happened to cause the comment model to
> disappear entirely from admin or if it's still partly there but broken. If
> only partially broken, what parts, exactly, are broken?

Here's the error when DEBUG=True, and I've commented out the bit of
code that fixes the problem when DEBUG=True:

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

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

So, I can't add one, view a list of existing ones, or change an
existing one. All I seem to be able to do with the blog app is visit /
admin/blog/.

> Again, I don't understand how that would help. Someone did recently open a
> ticket (http://code.djangoproject.com/ticket/11918) saying that switching to
> the older url pattern for admin worked with DEBUG=False where the current
> one did not, but you haven't actually switched all the way back to the old
> pattern here.

Turns out I'm a fool. Changing the regex didn't really help -- it
stopped 404s coming up, but it also started showing the wrong pages,
so disregard this as a fix.

> Plenty of people are using the 1.1 pattern without trouble,
> so there's something in the configs where problems arise that is different.
> We've not gotten enough specifics on the failing configs for me to have any
> idea what it might be. A small, recreatable example would help.

I'll try coming up with the smallest failing example tomorrow.

Thanks for the reply

Mike

Michael Williamson

unread,
Sep 27, 2009, 6:55:26 PM9/27/09
to Django users
> A small, recreatable example would help.

I've just recreated by doing the following, all with Django 1.1:

1. Run django-admin startproject bug
2. Set DATABASE_ENGINE to sqlite3 and DATABASE_NAME to /tmp/bug-
database
3. Add 'django.contrib.admin' to INSTALLED_APPS
4. Edit urls.py so that it looks like this:

from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
)

5. Run manage.py startapp blog
6. Edit models.py so it looks like this:

from django.db import models
from django.contrib import admin

class Tag(models.Model):
name = models.CharField(max_length=50)

admin.site.register(Tag)

7. Add 'bug.blog' to INSTALLED_APPS
8. Run manage.py syncdb
9. Add a VirtualHost to apache2:

<VirtualHost *:8426>
DocumentRoot /var/www/django-admin-bug/public
<Directory "/var/www/django-admin-bug/public">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

10. Put the following .htaccess in /var/www/django-admin-bug/public:

SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE bug.settings
PythonOption django.root
PythonDebug On
PythonPath "['/var/www/django-admin-bug'] + sys.path"

11. Set DEBUG=False
12. Try to add a tag, and get a 404.

When running the application using manage.py runserver, the bug
disappears, so it seems mod_python is doing something differently.

Karen Tracey

unread,
Sep 27, 2009, 8:16:02 PM9/27/09
to django...@googlegroups.com
On Sun, Sep 27, 2009 at 6:55 PM, Michael Williamson <mikerwi...@yahoo.co.uk> wrote:

> A small, recreatable example would help.

I've just recreated by doing the following, all with Django 1.1:

 1. Run django-admin startproject bug
 2. Set DATABASE_ENGINE to sqlite3 and DATABASE_NAME to /tmp/bug-
database
 3. Add 'django.contrib.admin' to INSTALLED_APPS
 4. Edit urls.py so that it looks like this:

from django.conf.urls.defaults import *

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
   (r'^admin/', include(admin.site.urls)),
)

 5. Run manage.py startapp blog
 6. Edit models.py so it looks like this:

from django.db import models
from django.contrib import admin

class Tag(models.Model):
   name = models.CharField(max_length=50)

admin.site.register(Tag)


Ah.  You've put your admin.site.register call in models.py.  This should go in an admin.py file, not models.py.  Whether your model is registered with admin is being determined by the accident of whether your models.py file has happened to be loaded at the time you attempt to access it in admin.  Your models.py file will have been loaded when running under the development server, since it does explicit model validation during startup.  Similarly the admin validation done when DEBUG=True will have ensured that your models.py file is loaded when you first attempt to access admin. 

When running under Apache with DEBUG=False, however, there has not necessarily been any need to load your models.py by the time you attempt to access admin. That's why you are getting 404 errors...that call to admin.site.register has not yet been made.

admin.autodiscover() and placing admin registrations in admin.py files (what are loaded by admin.autodiscover()) ensures that model registrations happen once and only once, at a predictable time, regardless of deployment scenario and debug setting.  If you move your admin registrations to an admin.py file I believe your problem will go away.

Karen

Vic Fryzel

unread,
Sep 27, 2009, 9:50:24 PM9/27/09
to Django users
I'm also able to reproduce this. Trying to figure out the issue.

On Sep 27, 6:55 pm, Michael Williamson <mikerwilliam...@yahoo.co.uk>
wrote:

Michael Williamson

unread,
Sep 28, 2009, 4:11:17 AM9/28/09
to Django users
> If you move your admin registrations to an admin.py file
> I believe your problem will go away.

Right you are! Well, that was somewhat foolish of me.

Thanks for your patience.

Mike
Reply all
Reply to author
Forward
0 new messages