Difference between admin.site.root and admin.site.urls - django

In the The Django Book in chapter 6 about the Admin Site, they tell me to add the follwing URLpattern to urls.py:
urlpatterns = patterns('',
# ...
(r'^admin/', include(admin.site.urls)),
# ...
)
But to make it work on my system, I had to uncomment the following line:
(r'^admin/(.*)', admin.site.root),
Can somebody enlighten me on what the differences are?

Both Gabriel and Antti have it the wrong way round, unfortunately.
admin.site.root is the version 1.0 behaviour. If you have downloaded 1.0 or 1.0.2, that's what you should use.
However, there were some changes to the URL handling for Django's admin very recently, which are part of the yet-to-be-released 1.1. These are primarily to make it possible to use the reverse() function to look up admin URLs. So if you have a recent checkout of the code, you'll need to use admin.site.urls.
Your link is to the second edition of the Django Book, which is being updated for version 1.1 - and the docs which Gabriel refers to are also for the current checkout, which has the new version.
(Just for completeness, I'd note that versions of Django before newforms-admin was merged, prior to 1.0, used admin.urls, not admin.site.urls or admin.site.root.)

Please notice the following; I struggled because of (.*) being in the second entry below.
Works, but is deprecated:
urlpatterns = patterns('',
(r'^admin/(.*)', admin.site.root)),
)
Incorrect, and partially works:
urlpatterns = patterns('',
(r'^admin/(.*)', include(admin.site.urls)),
)
Correct, and works well:
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
)

The Django Book speaks of version 0.9.6. Since then the admin has been rewritten. In Django 1.0 the whole admin is served by a single view (admin.site.root) which parses the rest of the URL internally.
Compare the admin directory of 0.96.3 with the corresponding directory from 1.0.2. There is no urls.py in the latter.

from the source code for the admin.site.root function:
root(self, request, url): Handles main URL routing for the admin app.
[...] method can be used as a
Django view function that presents a
full admin interface for the
collection of registered models.

Related

Where does the smartselect URLS belong?

I'm trying to set op SmartSelect in my django project so I can chain dropdown menu's.
I do not understand how/where the urls belongs for the installation?
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^chaining/', include('smart_selects.urls')),
)
This is what their official installation guide says. Though this is either and old version of Django or i'm doing something wrong as I have not seen any URLS file written this way before and VScode does not recognize it.
What am I doing wrong?
As of django-3.1, url(…) [Django-doc] is
deprecated in favor of re_path(…) [Django-doc] and has been removed in django-4.0.
Furthermore a new syntax for paths has been introduced with path converters: you
use path(…) [Django-doc] for that.
So you can implement this as:
from django.urls import include, path
urlpatterns = [
path('admin/', include(admin.site.urls)),
path('chaining/', include('smart_selects.urls')),
]
That being said, if the documentation is that old, the project might no longer be "alive".

Why do my files not match a Django 1.8 installation even though Bash confirms I have one installed?

I set up the virtual environment variable for Django 1.8 as per the instructions in the Django tutorial (1.8) and the (almost) matching 1.7 tutorial on PythonAnywhere. When I go into Bash and follow the instructions to check the Django version it confirms that I have version 1.8. installed.
I am up to part 3 in the Django tutorial at this URL:
https://docs.djangoproject.com/en/1.8/intro/tutorial03/
In mysite/urls.py the tutorial tells me to write this:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
]
However, when I actually opened the file I was presented with this:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
The tutorial then has this to say:
Doesn’t match what you see? If you’re seeing admin.autodiscover()
before the definition of urlpatterns, you’re probably using a version
of Django that doesn’t match this tutorial version. You’ll want to
either switch to the older tutorial or the newer Django version.
As I said though, Bash confirms that I Do have Django 1.8 installed. What am I missing here? Why do I not have the correct files for Django 1.8 even though that's what I supposedly installed?
I tried to make the files match the tutorial files, but it only resulted in an error appearing on my public site.
The most likely cause is that you didn't activate the virtualenv when you ran startproject, so you got the default Django from PythonAnywhere instead of the one that you installed.

Zinnia Blog Entry showing up 404 Page Not Found

I have Django 1.5.1 installed and django-cms 2.4.2
However I have not integrated zinnia blog and django-cms just yet.
I was able to create a blog entry but when going to the blog entry
8000/en/weblog/2013/10/13/test-entry/
I receive a 404 Page not Found
any thoughts?
Possible cause: order of urlpatterns inclusions in urls.py. Django-Cms design lack.
Fix: put cms.urls after zinnia.urls:
# patterns or i18n_patterns here.
urlpatterns = i18n_patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^blog/', include('zinnia.urls')),
url(r'^comments/', include('django.contrib.comments.urls')),
url(r'^', include('cms.urls')),
)
Explanation:
If you include cms urls before zinnia urls, django-cms "slug" pattern matches a wide range of URLs including Zinnia blog entry URL:
<RegexURLPattern pages-details-by-slug ^(?P<slug>[0-9A-Za-z-_.//]+)/$>
As an example, it will match: "blog/2014/01/20/test-article-about-something/"
After it matched as django-cms:pages-details-by-slug, the whole URI is stored in the "slug" variable and is provided as an argument (in "kwargs") to cms.views.detail view function. And this view will call:
cms.utils.page_resolver import get_page_from_request(request, use_path=slug)
and cms will not find (and will raise "Resolver404" exception) any suitable page to render because this URI belongs to Zinnia blog.
End of story.
Resources:
"details" view can be found here: cms.views
django url resolving logic is here: django.core.urlresolvers mainly in two "resolve" methods. (lines: 315 *recursive, 209 *non-recursive)

Page not found at /archive/

EDIT: Figured it out, please see bottom.
I'm writing a simple blog app in Django and deploying it locally using this guide. I've completed the guide and everything was nominal so I decided to extend the functionality to view an archive of blog posts. This is how the index functions at the moment, but I wanted to move it to /archive/. I went to the tutorial again to get refresh my memory and it said I had to do three things:
Write the root URLconf in urls.py
Write the view function in views.py
Write the templates for the views
I edited the URLconf to look like this:
urlpatterns = patterns('',
#other patterns
url(r'^archive/', 'RehabLog.views.archive'),
)
I edited my views.py to add this function:
def archive(request):
posts = Post.objects.filter(published=True)
return render(request, 'RehabLog/archive.html', {'posts':posts})
I've saved it all and restarted foreman. When I load the page I get a 404 error which tells me No Post matches the given query. What am I missing out on?
Answer
I remembered reading the the order of your URLConfs was very important.
Previously I had:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'RehabLog.views.index'),
url(r'^(?P<slug>[\w\-]+)/$', 'RehabLog.views.post'),
url(r'^archive/', 'RehabLog.views.archive'),
)
Whereas now I have:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^archive/', 'RehabLog.views.archive'),
url(r'^$', 'RehabLog.views.index'),
url(r'^(?P<slug>[\w\-]+)/$', 'RehabLog.views.post'),
)
Which now works. Could anyone explain why?
/archive/ URL was first-matched by url(r'^(?P<slug>[\w\-]+)/$', 'RehabLog.views.post') so your actual rule url(r'^archive/', 'RehabLog.views.archive') was never reached. When you changed the order the first rule matched was the right one.

Django basic url slugifying issues

I want to slugify my urls in my Django application. I have read many documents but I am still not sure how to do it better. I have two questions:
How to call the same view for two different urls?
I would like to call home view for both www.mysite.com and www.mysite.com/index.html
(r'^$', 'myapp.main.views.home')
(r'([-\w]+)$', 'myapp.main.views.home')
The code above sounds good but of course it raises an error as home view expects 1 parameter but 2 is given. How can I resolve this?
I have so many apps and they all have their own urls.py file. I was handle them as including their urls file to the root urls.py as
(r'^warehouse/', include('myapp.warehouse.urls')),
In that way, urls seems like www.mysite.com/warehouse/blabla/
However, I want to slugify them as www.mysite.com/warehouse_blabla.html
Slugifying is not hard but how can I resolve such url and redirect it to the blabla view in warehouse app?
Thanks
Regarding the first problem, you would be better off using a redirect for the index.html URL (better for SEO etc.)
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
url(r'^$', 'myapp.main.views.home')
url(r'^index.html$', redirect_to, {'url': '/'}),
)
Regarding the second issue, your urls.py file is just a set of regular expressions, so you have control over the URL scheme you want to use:
urlpatterns = patterns('',
url(r'^warehouse_(?P<slug>[_w]+).html$', 'warehouse.views.warehouse_detail'),
)
That said, I think you would be better sticking to the usual convention of slashes