Simple Blog Using Django 1.9 — Finalizing Simple Blog
This article is continuation from this article https://medium.com/@gerrysabar/simple-blog-using-django-1-9-make-the-blog-looks-nicer-2f57ea83e3aa, makesure you have read this article before proceed to this article and you also have completed or clone the code from previous series.
We’re in he last article for creating a simple blog using Django 1.9. In this article we’ll cover small adjustment at admin page, uploading image for article, pagination for listing article, implementing slug and last a basic authentication in Django 1.9 framework. If you take a look at admin page, after you insert article you’ll see like this
It makes us difficult to edit certain article as each article is labeled as Article Object instead. Therefore let’s replace this label into article’s title to make it meaningful. At articles/models.py add this line inside class Article
def __unicode__(self):
return self.title
def __unicode__ is a special method that will return string representation of object Article (this is the reason why we got “Article Object” list in admin page. Then we replace it with column title from our database. That’s why we got article title now instead of “Article Object” at admin page.
Alright, so far our article only able to put text, what if we want to add image as well? Let’s implement it now. Go to articles/models.py and we create a method named upload_location as follow:
def upload_location(article, filename):
return “%s%s” %(article.id, filename)
The idea is to avoid file with the same filename is overwritten. For example I upload a file named 1.jpg for the first article then next I upload another file with the same name 1.jpg but different image to the second article, then 1.jpg for the first article will be overwritten by 1.jpg for the second article. To avoid this we rename uploaded file with article id then followed by the article name. Next inside class Article we add one field to handle image as follow
image = models.ImageField(upload_to=upload_location, null=True, blank=True)
So our code in articles/models.py will be like this
From terminal create migration as usual since we adjust the database
$ python manage.py makemigrations
Then execute the migration
$ python manage.py migrate
To upload image the HTML form should support multipart/form-data. At templates/form.html we need to replace this tag
<form method=”POST” action=””>
into
<form method=”POST” action=”” enctype=”multipart/form-data”>
Add image field inside articles/forms.py to support adding image inside form
After you add this and go to localhost:8000/articles/create you’ll see one additional input file to upload image. Create method at articles/views.py need to support receiving file by modifying this line:
form = ArticleForm(request.POST) # form will hold input forms those are defined in articles/forms.py
Inside create method into
form = ArticleForm(request.POST, request.FILES) # form will hold input forms those are defined in articles/forms.py
The same goes for update method. Our final code for articles/views.py will look like this
We have adjusting the workflow in to handle data but we haven’t adjusting Django settings to handle image file. Go to myblog/settings.py then add these two lines of code at the bottom of the file
MEDIA_URL = “/media/”
MEDIA_ROOT = os.path.join(BASE_DIR, ‘static/media’)
At the bottom or myblog/urls.py add these lines
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
From admin page now you can try to add or edit articles including upload image. Last, wee need to display image in index.html and detail.html file, first at index.html let’s modify the code to check if there’s any image we’ll display it in bootstrap style, for template/index.html adjust the code as follow:
Great, we have accomplished image uploader for our simple blog project. Let’s tackle for pagination now. First of all, let’s create more articles from admin page if your articles are less than in 10 articles in admin page to help us working with pagination. We’ll working with articles/views.py now and below this line
from .forms import ArticleForm # importing form to be rendered at template
Add code below:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Then modify index method become like this
If you access localhost:8000/articles you’ll get the first 3 articles. If you try to access localhost:8000/articles/?page=2 you’ll get articles from 4th to 6th. Last we need to add html pagination button in index.html. Modify the html code at <div class=”clearfix”> as follow
Now at your index page you can go to page 2 and more if you have more than 3 articles in your database. Cool, we have implemented pagination in our simple blog project.
Last part of this article we’ll try to implement a very basic authentication. When we want to create or update any article, we want to make sure that only login admin is able to do that in our blog page. Make sure you logout from admin page first for now. At articles/views.py let’s import http library as follow
from django.http import Http404
Then add this two lines of code right below code def create(request)
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
The code snippet above is used to detect that only user with type staff or superuser who can access this page. If you go to admin page and create user you can see there’s option to add the user as staff or superuser or both. Please also implement this snippet for update method as well. Now if you’re logout from admin page and try to access localhost:8000/articles/create you’ll get 404 error. The same applies when you try to edit any article but if you login to admin page, now you can access create or update article page. You can get the complete code for this article here