Entering blog content via the command-line is certainlypossible but not very user-friendly. As Raymond Hettinger would prod you to shout, "There must be a better way."

And, there is a better way. It's called the Django admin .
Django is able to automatically generate an admin interface based on the metadata it collects from your models.
I'll show you how to use the admin to manage your blog content.
N.B. The admin is best used only as an internal management tool. If you need an interface that's less model-centric and more process-centric then you should consider writing your own views. Buddy Lindsey from GoDjango gives a good list of 5 reasons not to use the Django admin .
Let's get started.
Accessing the adminThe admin is already enabled since we started with the default project template used by startproject .
N.B. If you're curious about the admin's requirements then you can check here .
To login to the admin you need to create a user. Use the createsuperuser command to do it.
(venv) $ python manage.py createsuperuser Username (leave blank to use 'dwayne'): Email address: dwayne@simplydjango.com Password: Password (again): Superuser created successfully.Then, you can start up the server and navigate to http://127.0.0.1:8000/admin to login and view the admin site.

Take some time to explore the admin site before continuing. I can wait.
Manage posts via the adminYou'd notice that our posts app is nowhere to be found. Let's fix this by telling the admin about our Post model.
Edit posts/admin.py to contain the following:
from django.contrib import admin from .models import Post admin.site.register(Post)Refresh http://127.0.0.1:8000/admin to see the posts app.

That's it. We can now manage our posts via the admin.
Let me show you.
Click on the Add link next to Posts to view the add page for posts.

Enter some information into the required fields and click the Save button to persist your changes to the database and get redirected to the change list page.

Finally, click on the post to be taken to its change page. Notice that it's similar to the add page. Make any edits you need and save it when you're done.
I'll now show you how easy it is to customize the pages you just saw.
Customize the change list pageUpdate posts/admin.py to contain the following:
from django.contrib import admin from .models import Post @admin.register(Post) class PostAdmin(admin.ModelAdmin): date_hierarchy = 'published_at' list_display = ( 'title', 'is_published', 'published_at', 'created_at', 'updated_at', ) list_filter = ('is_published',) ordering = ( '-published_at', '-created_at', ) search_fields = ( 'title', 'excerpt', )Firstly, we create a new class, PostAdmin , that subclasses admin.ModelAdmin . It gives us a place to put our custom values.
Notice that I used the register decorator this time around to register the Post model with PostAdmin . However, doing it the previous way is perfectly fine as well. After the class definition you'd just put admin.site.register(Post, PostAdmin) .
N.B. You can't use the register decorator if you have to reference your model admin class in its __init__() method, e.g. super(PersonAdmin, self).__init__(*args, **kwargs) .
Here's what each class attribute does:
date_hierarchy : It makes the change list page use the published_at field of the Post model to display a date-based drilldown navigation.
list_display : It controls which fields are displayed as columns in the table shown on the change list page.
list_filter : It activates search filters in the right side bar of the change list page based on the elements of the tuple. In our case it will allow us to easily filter between draft and published posts.
ordering : It determines how the posts are ordered. First in descending order of published_at and then in descending order of created_at . This keeps draft posts at the top so they're right there in front of us when we go to the page to continue working on them. Then comes the most recent published posts. Finally, if two posts are published on the same day then the most recently created one appears first in the table.
search_fields : It enables a search box. I've set it to search the title and excerpt fields of the Post model whenever a search query is submitted.
Here's the final result of this customization:

Customize the add/change pages
We're going to make the following changes:
Re-label the is_published field to Is published? .
Auto-populate the slug field when entering the title of the post.
Exclude the published_at field from the form.
Lastly, set the published_at field to an appropriate value when the is_published field is toggled. In particular, when is_published is true then published_at should contain the current date and time when the change is saved. And, when is_published is false then published_at should be set to None .
Here are the edits to posts/admin.py that will make all that possible:
from django import forms from django.contrib import admin from django.utils.timezone import now from .models import Post class PostAdminForm(forms.ModelForm): class Meta: model = Post fields = ['is_published', 'title', 'slug', 'excerpt', 'body'] labels = { 'is_published': 'Is published?', } @admin.register(Post) class PostAdmin(admin.ModelAdmin): # ... form = PostAdminForm prepopulated_fields = { 'slug': ('title',) } def save_model(self, request, obj, form, change): if form.has_changed() and 'is_published' in form.changed_data: if obj.is_published: obj.published_at = now() else: obj.published_at = None super().save_model(request, obj, form, change)I create a custom model form called PostAdminForm and then tell PostAdmin to use that form instead of the default it generates by setting the form class attribute.
The prepopulated_fields class attribute allows me to auto-populate the slug field when entering the post's title.
Finally, notice how I override the ModelAdmin 's save_model method to perform a custom pre-save operation.
Here are the visible changes:

Wrap up
That completes the customizations we'll be doing to the admin for now. I hope you're still tracking your changes with Git. If so, then now is the time to make your commits. Here are links to the ones I made:
Change list page customizations Add/change page customizationsFinally, check off the second task on your Trello card and bask in the joy of being 50% complete with the feature.
P.S. Let me know in the comments if you get into any problems. I'd be happy to help.
P.S.S. Subscribe to my newsletter if you're interested in getting exclusive Django content.