The admin panel
The great thing about Django is that even
with this, our site already has an admin panel, it just doesn’t know about our
new data yet. So we need to tell it. Create a new file calledadmin.pyin the
movies directory, and add the following code to it:
from movies.models import Credit, Movie,
Person, Role
from django.contrib import admin
admin.site.register(Credit)
admin.site.register(Movie)
admin.site.register(Person)
admin.site.register(Role)
Now, run the following command in the
project directory:python manage.py runserver
This will launch the server for our
website, by default at http://127.0.0.1:8000.The real magic right now is at
http://127.0.0.1:8000/admin which hosts the admin panel. Enter the password you
used while running the syncdb command and you will see what we have built.
The
great thing about Django is that even with this, our site already has an admin
panel, it just doesn’t know about our new data yet.
You will see that there is already quite a
functional admin system! You can add movies, people, roles and credits. But,
the way we add credits isn’t very convenient, wouldn’t it be better to
highlight the credits for the movie under it?
The good thing is that the admin panel is
not only automatically generated, but also highly customizable.
Just like we defined a custom data
structure for our app using models, we can define a custom admin panel using
admin models. We want to add credits from within a movie, for this what we need
is an inline model, i.e. a way to input information about one model from within
another model. Here is how that could be coded:
from movies.models import Credit, Movie,
Person, Role
from django.contrib import admin
class CreditInline(admin.TabularInline):
model = Credit
extra = 3
class MovieAdmin(admin.ModelAdmin):
inlines = [CreditInline]
admin.site.register(Movie, MovieAdmin)
admin.site.register(Person)
admin.site.register(Role)
The Credit online class uses the Credit model,
and allows for it to be embedded inline within another admin model. We are sub-classing
from TabularInline, but there is another option, StackedInline which looks a
bit different; try it out. By setting a value for extra we tell the admin panel
to allow people to enter three entries for Credits for a movie by default,
although they are free to add more.
In the previous example we just used the
admin.site.register to register our models with the admin. This uses the
default settings for the admin panel. In this example we are overriding the
settings for the admin panel for movie by making a class for it and customizing
its settings. The only setting we change here is that it should have an inline
model, the CreditInline model.
We
are sub-classing fromTabularInline, but there is another option, StackedInline which
looks a bit different; try it out.
If you run the site now, you will see a
much better interface for adding movie credits. If we want, we can add the same
inline option for people, so each person’s admin page will list the movies that
person has contributed to. For that we just add a Person - Adminmirroring what
we did for Movie Admin, and register it the same we do for Movie. Add:
class PersonAdmin(admin.ModelAdmin):
inlines = [CreditInline]
And modify the line
admin.site.register(Person) to admin.site.register (Person, PersonAdmin).
A little for the front
All we can do right now is add data, but
there is no way to show it to users. Let’s do something about that.
The urls.pyfile comes into play here. When
someone visits a URL on our site, Django checks if the URL matches a pattern in
this file, and calls the corresponding function. The pattern matching is done
using Regex, and the functions are stored in the views.pyfile. Look at the
examples in the urls.pyfile, then let’s add one of our own. Above the admin
code, add this:
url(r’^movie/(?P<movie_id>\d+)/$’,
‘movies.views.movie_detail’),
The first parameter to URL is a regular
expression for matching a URL that has “movie/” followed by a number, which is
captured as movie_id. It will then pass this movie_id to the
movie_detailfunction in the views.py files in the movies app. Open the
views.pyfile and add the following:
from movies.models import Credit, Movie
from django.http import Http Response
def movie_detail(request, movie_id):
the_movie = Movie.objects.get(id=movie_id)
credits =
Credit.objects.filter(movie=the_movie)
html = “<h1>%s</h1>” %
(the_movie.title)
for credit in credits:
html += “%s: %s <br />” %
(credit.role,
credit.person)
return HttpResponse(html)
If you visit the URL http://127.0.0.1:8000/movie/1/the
above function will be called with the value of movie_idset to 1. What you do
in this function is up to you, but it needs to return some-thing for the
browser to show. Here it is an Http Response with some HTML code.
Here
it is an Http Response with some HTML code.
You will see Django ORM (Object-Relation
mapping) API used for the first time here. The first line retrieves the Movie object
for the requested id. We then filter all the Credit objects that match this
Movie. The movie name and credits and then put in some basic HTML code and
returned to the browser. Add a few movies with credits and try this out to see
a very simple HTML page.
Conclusion
And there you have it, a custom CMS with
custom data. It is easy to apply this same method to any kind of data structure
and work with books, libraries and authors, or music, artists, genres, albums
and producers. You define the kind of data you want to work with, and Django
makes you a rich, easy to use admin panel and the rest is up to you.
There is a lot more to Django, the admin
panel can be customized a lot more, there are powerful tools and features for
dealing with the frontend using a simple template language. And there’s a lot
more to Django’s database API which we just glossed over above. If you are
intrigued visit www.djangoproject.comfor a lot more information.