How to Make a Blogging Site Using Django (Python Library) — Django Tutorial
Want to make a blogging site for your blogs? Start building your customizable blogging sites using Django.

Note: In this tutorial, I am using a free bootstrap template from startbootstrap. You can find the code of this tutorial in Github. Below I am giving the URL.
Setup Project
- Create a Folder (Name = django_project)
- Open created folder. Run cmd, set a path
- Create a Virtual Environment and activate it.
# create
$ python -m venv myvenv#activate
$ myvenv\Scripts\activate
4. Install Django
$ pip install django==3.1.5
5. Start a project
$ django-admin startproject django_blog
6. Change Directory
$ cd django_blog
7. Start a app
$ django-admin startapp blog
8. Create 3 necessary folders —
- templates (for html’s)
- static_in_env (for css, js, etc.)
- media_root (for storing files while uploading)
8. Finally, run server. Go to http://127.0.0.1:8000/
$ manage.py runserver


Round 1 — Completed!

CODING TIME!

Settings
path = django_blog/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog' # new
]TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],# new
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]# new
# Static files (CSS, JavaScript, Images)
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_in_env')]
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_root')
Models
A model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table.
The basics:
- Each model is a Python class that subclasses
django.db.models.Model
. - Each attribute of the model represents a database field.
Source: Django Documentation
path = blog/models.py
from django.db import models
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=150)
slug = models.SlugField()
image = models.ImageField()
content = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.title
Make migrations and migrate
$ python manage.py makemigrations
$ python manage.py migrate
Admin
path = blog/admin.py
from django.contrib import admin
from .models import Post# Register your models here.
class PostAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug':('title',)}
admin.site.register(Post, PostAdmin)
Create a superuser
$ python manage.py createsuperuser

What I set —
- username = user
- password = 1234
Go to: http://127.0.0.1:8000/admin, and login


Round 2— Completed!

Views
A view function, or view for short, is a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, or a redirect, or a 404 error, or an XML document, or an image . . . or anything, really. The view itself contains whatever arbitrary logic is necessary to return that response. This code can live anywhere you want, as long as it’s on your Python path. There’s no other requirement–no “magic,” so to speak. For the sake of putting the code somewhere, the convention is to put views in a file called
views.py
, placed in your project or application directory.Source: https://docs.djangoproject.com/en/3.1/topics/http/views/
Go to templates folder and create —
- home.html
- post-detail.html
Then open views.py
path = blog/views.py
from django.shortcuts import render
from .models import Post
from django.views.generic import DetailView, View
# Create your views here.
class HomeView(View):
def get(self, *args, **kwargs):
posts = Post.objects.all()
context = {
'posts': posts,
}
return render(self.request, "home.html", context)
class PostDetailView(DetailView):
model = Post
template_name = 'post-detail.html'
Urls
- path = blog/urls.py
from django.urls import path
from .views import HomeView, PostDetailView
urlpatterns = [
path('', HomeView.as_view(), name='home'),
path('<slug:slug>', PostDetailView.as_view(), name='post-detail')
]
2. path = django_blog/urls.py
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')) #including blogs urls
]#new
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Templates
First, download all css, js files from here, and save in static_in_env folder.
- Create a new base.html file. Enter following code.
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block head_title %}{% endblock %}</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<!-- Custom fonts for this template -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<!-- Custom styles for this template -->
<link href="{% static 'css/clean-blog.min.css' %}" rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
<div class="container">
<a class="navbar-brand" href="\">Django Blog</a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i class="fas fa-bars"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="\">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="about.html">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="post.html">Sample Post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="contact.html">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
{% block content %}
{% endblock content %}
<hr>
<!-- Footer -->
<footer>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<ul class="list-inline text-center">
<li class="list-inline-item">
<a href="#">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-twitter fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li class="list-inline-item">
<a href="#">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-facebook-f fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li class="list-inline-item">
<a href="#">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-github fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
</ul>
<p class="copyright text-muted">Copyright © Your Website 2020</p>
</div>
</div>
</div>
</footer>
<!-- Bootstrap core JavaScript -->
<!-- <script src="vendor/jquery/jquery.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
<!-- Custom scripts for this template -->
<script src="{% static 'js/clean-blog.min.js' %}"></script>
</body>
</html>
home.html
{% extends 'base.html' %}
{% load static %}
{% block head_title %}Django Blog{% endblock %}
{% block content %}
<!-- Page Header -->
<header class="masthead" style="background-image: url({% static 'img/studyofdista.jpg' %})">
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="site-heading">
<h1>Django Blog</h1>
<span class="subheading">A Blog Theme by Start Bootstrap</span>
</div>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-preview">
{% for post in posts %}
<a href="/{{post.slug}}">
<h2 class="post-title">
{{post.title}}
</h2>
</a>
<p class="post-meta">Posted by
<a href="#">Django Blog</a>
on {{post.created_date}}</p>
</div>
<hr>
{% endfor %}
<!-- Pager -->
</div>
</div>
</div>
{% endblock content %}
post-detail.html
{% extends 'base.html' %}
{% load static %}
{% block head_title %}{{object.title}}{% endblock %}
{% block content %}
<!-- Page Header -->
<header class="masthead" style="background-image: url('{{object.image.url}}')">
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<div class="post-heading">
<h1>{{object.title}}</h1>
<span class="meta">Posted by
<a href="#">Django Blog</a>
on {{object.created_date}}</span>
</div>
</div>
</div>
</div>
</header>
<article>
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-10 mx-auto">
<p>{{object.content|linebreaks}}</p>
</div>
</div>
</div>
</article>
{% endblock content %}
Final Round — Completed!

