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.

Madhav Mishra
Jan 14 · 6 min read
Image for post
Image for post
How to Make a Blogging Site Using Django (Python Library)

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

  1. Create a Folder (Name = django_project)
  2. Open created folder. Run cmd, set a path
  3. 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
Image for post
Image for post
Windows 7 Screenshot - 1
Image for post
Image for post
Windows 7 Screenshot — 2

Round 1 — Completed!

Image for post
Image for post
Congratulations! from Django

CODING TIME!

Image for post
Image for post

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
Image for post
Image for post
Create a superuser

What I set —

  • username = user
  • password = 1234

Go to: http://127.0.0.1:8000/admin, and login

Image for post
Image for post
Image for post
Image for post

Round 2— Completed!

Image for post
Image for post

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

  1. 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 &copy; 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!

Image for post
Image for post
home
Image for post
Image for post
post-detail

Github Code

URL: madhav727/django-blog-tutorial

Analytics Vidhya

Analytics Vidhya is a community of Analytics and Data…

Sign up for Analytics Vidhya News Bytes

By Analytics Vidhya

Latest news from Analytics Vidhya on our Hackathons and some of our best articles! Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Madhav Mishra

Written by

AI Enthusiast

Analytics Vidhya

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Madhav Mishra

Written by

AI Enthusiast

Analytics Vidhya

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface.

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox.

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic.

Get the Medium app