Step Eight: Configuring the admin and uploading to S3

by Andy Boyle.

We set up our uWSGI and nginx conf files and our server is now running. Now we will set up the admin to add content — one of the totally sweet parts of Django — and then show you how to get your admin files onto Amazon S3.

What sets Django apart from many other out-of-the-box frameworks is that it has a pretty bitchin’ admin built into it. You don’t have to use it, of course. You could just do everything from your terminal, and add information in through the shell. But Django was designed by developers who worked for a newsroom. Thus bits of it had to be understood by regular newsroom folk — editors, reporters, photographers, etc. People who weren’t super web-savvy should be able to use it through some sort of web interface.

Hence setting up the admin. When you’re done, it’ll look like this:

Neat, right? This looks like something your average person who’s ever added a photo on Facebook should be able to work, right? Right.

So, first you need to add a file in your project directory (/opt/django-projects/fires/). Name it admin.py. You can do this by either creating a file on your computer and then uploading it, or if you’re using something like Coda, just right click on the in the area listing files and click New File.

Copy and paste this code inside. I’ll explain afterword how it works:


from django.contrib import admin
from firetracker.fires.models import State, City, Address, Department, Station, Title, Person, StoryLink, Injury, Victim, Fire, Cause

class StateAdmin(admin.ModelAdmin):
    prepopulated_fields = {'name_slug': ('name', ) }
    search_fields = ['name']

class CityAdmin(admin.ModelAdmin):
    prepopulated_fields = {'name_slug': ('name', ) }
    search_fields = ['name']

class AddressAdmin(admin.ModelAdmin):
    prepopulated_fields = {'street_slug': ('street', ) }
    search_fields = ['street']

class DepartmentAdmin(admin.ModelAdmin):
    prepopulated_fields = {'name_slug': ('name', ) }
    search_fields = ['name']

class StationAdmin(admin.ModelAdmin):
    prepopulated_fields = {'name_slug': ('name', ) }
    search_fields = ['name']

class TitleAdmin(admin.ModelAdmin):
    prepopulated_fields = {'title_slug': ('title', ) }
    search_fields = ['title']

class PersonAdmin(admin.ModelAdmin):
    prepopulated_fields = {'name_slug': ('first_name', 'last_name' ) }
    search_fields = ['name']

class InjuryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'injury_slug': ('injury', ) }
    search_fields = ['injury']

class CauseAdmin(admin.ModelAdmin):
    prepopulated_fields = {'type_slug': ('type', ) }
    search_fields = ['type']

admin.site.register(State, StateAdmin)
admin.site.register(City, CityAdmin)
admin.site.register(Address, AddressAdmin)
admin.site.register(Department, DepartmentAdmin)
admin.site.register(Station, StationAdmin)
admin.site.register(Title, TitleAdmin)
admin.site.register(Person, PersonAdmin)
admin.site.register(Injury, InjuryAdmin)
admin.site.register(Cause, CauseAdmin)


So, if you look at this and compare it with your models.py file, you’ll see a lot of things overlapping. First, you need to pull in everything from your models.py file. This line tells Django to import its admin bits:

from django.contrib import admin

The next line pulls in the various classes from your models.py file. This allows you to later use them in this admin.py file.

Line 4-6 is the basic way we’re setting up everything in the admin. So you need to make a class for the State class. Thus StateAdmin. Line 5 is telling you to pre-populate the name_slug field (which you have in your models.py file, remember?) with whatever is typed in the name slug. You’ll see this in action once everything is live. Then search_fields allows you to include a field to search by in the admin.

Line 40 is where you basically sync stuff up. You’re sort of saying “Hey, State and StateAdmin, make friends!” So you need one of these for each of the previous admin classes you created above.


Now we need to upload some files to S3. Why, do you ask? Because the admin uses some CSS, Javascript and styling deals. Well, why don’t we just put that on the instance we created and are hosting the Django stuff on? Because that would require us to also set up a server to run media files. That would mean more hits to your server, more traffic, more load, etc. And as media files in general — photos, audio, video, etc. — can be large, that means it would also push up your Amazon bill, as they charge for traffic leaving an instance after 1 gigabyte.

Also, I don’t know how to set up a media server that isn’t for PHP. SO THERE.

First, we are going to download a copy of Django onto our harddrive and then pull out the media bits. Go here to download a copy. Make sure it’s your current version — if you have Django 1.2.3 running, get that. If it’s 1.3, download that version. After it’s downloaded, unzip it and look inside. Go to the unzipped file, then this path /django/contrib/admin/media/

Inside of this are all the files you’re going to want to upload to your S3 account. This is sort of an annoying process, and I’m sure there’s a quicker way, but I’m kind of dumb so I end up doing things the longer way. (AKA hey anyone out there reading this, if you have a better way to do this, leave a comment or let me know, and I’ll include it in here and give you props).

So in the end, you’ll want to have uploaded to S3 a css, img and js folder, with all the files in each individual folder, and then each individual folder will have its subsequent subfolders and files. Like I said, this will be annoying and tedious.

To get this set up, login with the account you created earlier to AWS. Click on S3 once you’re logged in. You will now create a bucket. I suggest you either name it after your organization — dailynewstribuneglobecompany — or something. Or name it after your project. Whatever. Once you do that, you need to create a folder named “admin.” Inside of that, add three more folders named css, img and js. And from there, you will upload each individual file, create new subfolders, etc., so it matches the file on your computer. Do that shit like I said you should do up there.

Once that’s done, go back to the main bucket directory. Right click on the admin folder, and then click Make Public. This will make it so people can look at your files without the various AWS credentials.

Now, to test that that worked, go to the equivalent URL that looks like this, only instead of dailynewstribuneglobecompany it’s whatever you threw up there: https://s3.amazonaws.com/dailynewstribuneglobecompany/admin/img/admin/arrow-down.gif

You should be able to see a little arrow appear in the screen of your top left browser. If you can see that, voila, your admin shit was uploaded.

Once that’s done, you will need to edit your settings.py file, like we did in Step Five.

Change line 51 that to:

ADMIN_MEDIA_PREFIX = 'http://s3.amazonaws.com/dailynewstribuneglobecompany/admin/'

This tells Django to look for the admin stylesheets here. Now that your project is live at, go there and then add /admin/ to the end of the URL. You can now add in the username and password you entered when you originally syncdb’d back in Step Five.

Once you’re logged in, you should see the basic admin screen that we showed earlier. In my next post, I’ll discuss adding content.