Creating My Own Blogging Engine Part 3

In part 2 we setup the model and added a post using the basic admin forms. So let's start by adding some pizzazz to the admin forms.

Admin

Before customizing the admin, I want to have a Featured Image for the blog posts, and after some research, the django-filebrowser seems the way to go. To install,

pip install django-filebrowser

Installing django-filebrowser will also automatically install Grappelli. Let's add the new apps to the settings file and see how it works:

INSTALLED_APPS = [ 
    'grappelli', 
    'filebrowser', 
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles',    
    'blog', 
]

Running the server and opening the admin gives us an error.

python manage.py runserver

No problem. We just need to load some dependencies.

pip install Image

Now the dependent package Image is loaded, time to check the admin again.

Nice! The Grappelli plugin is running. Continuing the quick start guide for Grappelli, we need to add some url's to the project urls.py file,

from filebrowser.sites import site

urlpatterns = [
   url(r'^admin/filebrowser/', include(site.urls)),
   url(r'^grappelli/', include('grappelli.urls')),
   url(r'^admin/', include(admin.site.urls)),
]

Chances are you will get a error that include is not defined. If so, add,

from django.conf.urls import include

to the top of the urls.py file. There are quite a few settings to customize with Grappelli. The docmentation is worth a read. First thing to do though is add a setting for a custom dashboard. Follow the dashboard setup. In settings add app and setting:

'grappelli.dashboard',
# Grappelli dashboard
GRAPPELLI_INDEX_DASHBOARD = 'TenYearPlan.dashboard.CustomIndexDashboard'

Run the new customdashboard command to generate a dashboard.py file:

python manage.py customdashboard

Move the generated dashboard.py file to the tenyearplan folder, and restart the server.

Cool! Looking good.

To browse using filebrowser, it looks for an uploads directory. If not already setup in settings, follow the django tutorial and setup static and media paths. Add an uploads folder in the media folder.

One of my favorite features of filebrowser, is files dumped in the uploads folder are automatically added. Very handy!

Now that filebrowser is setup, we'll update the blog model to include a featured image by adding the following to blog/models.py,

from filebrowser.fields import FileBrowseField

class Post(models.Model):
    ...
    featured_image = FileBrowseField("Image", 
            max_length=200, 
            extensions=[".jpg",".jpeg",".png",".tif",".tiff"], 
            blank=True, null=True)

Once added, make a new migration file, and run migrate:

(tenyearplan) ➜  tenyearplan python manage.py makemigrations
Migrations for 'blog':
  blog/migrations/0002_post_featured_image.py:
    - Add field featured_image to post
(tenyearplan) ➜  tenyearplan python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying blog.0002_post_featured_image... OK
(tenyearplan) ➜  tenyearplan 

Now when adding or editing a post, there's a featured_image field with a link that opens the filebrowser.

Ok, let's open up the blog/admin.py file and add some useful features.

class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
    list_display = ('title', 'slug', 
            'status', 'category', 'pub_date',
            )
    list_filter = ['pub_date']
    search_fields = ['title']

Nice. This simple adjustment gives us more sort columns, a search field, and the option to filter by pub_date.

That's enough for now. In the next post, we'll look at Bootstrap and start creating our first template.

Enjoy!