Building A Blog Application With Django

In this tutorial, we’ll build a Blog application with Django that allows users to create, edit, and delete posts. The homepage will list all blog posts, and there will be a dedicated detail page for each individual post. Django is capable of making more advanced stuff but making a blog is an excellent first step to get a good grasp over the framework. The purpose of this chapter is to get a general idea about the working of Django.

Here is a sneak peek of what we are going to make.

Building a blog with django 2.1

Before kicking off, I hope you already have a brief idea about the framework we are going to use for this project if not then read the following article: Django – Web Framework For Perfectionists.

Pre-Requirements

Django is an open-source web framework, written in Python, that follows the model-view-template architectural pattern. So Python is needed to be installed in your machine. Unfortunately, there was a significant update to Python several years ago that created a big split between Python versions namely Python 2 the legacy version and Python 3 the version in active development.

Since Python 3 is the current version in active development and addressed as the future of Python, Django rolled out a significant update, and now all the releases after Django 2.0 are only compatible with Python 3.x. Therefore this tutorial is strictly for Python 3.x. Make sure you have Python 3 installed on your machine if not follow the below guides.

Windows Users

Mac And Unix Users

Creating And Activating A Virtual Environment

While building python projects, it’s a good practice to work in virtual environments to keep your project, and it’s dependency isolated on your machine. There is an entire article on the importance of virtual environments Check it out here: How To A Create Virtual Environment for Python

Windows Users

cd Desktop
virtualenv django
cd django
Scripts\activate.bat

Mac and Unix Users

mkdir django
cd django
python3 -m venv django
source django/bin/activate

Now you should see (django) prefixed in your terminal, which indicates that the virtual environment is successfully activated, if not then go through the guide again.

Installing Django In The Virtual Environment

If you have already installed Django, you can skip this section and jump straight to the Setting up the project section. To Install Django on your virtual environment run the below command

pip install Django

This will install the latest version of Django in our virtual environment. To know more about Django installation read: How To Install Django

Note – You must install a version of Django greater than 2.0

Setting Up The Project

In your workspace create a directory called mysite and navigate into it.

cd Desktop
mkdir mysite
cd mysite

Now run the following command in your shell to create a Django project.

django-admin startproject mysite

This will generate a project structure with several directories and python scripts.

├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py

To know more about the function of the files read: Starting A Django Project

Next, we need the create a Django application called blog. A Django application exists to perform a particular task. You need to create specific applications that are responsible for providing your site desired functionalities.

Navigate into the outer directory where manage.py script exists and run the below command.

cd mysite
python manage.py startapp blog

These will create an app named blog in our project.

├── db.sqlite3
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── manage.py
└── blog
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

Now we need to inform Django that a new application has been created, open your settings.py file and scroll to the installed apps section, which should have some already installed apps.

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

Now add the newly created app blog at the bottom and save it.

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

Next, make migrations.

python manage.py migrate

This will apply all the unapplied migrations on the SQLite database which comes along with the Django installation.

Let’s test our configurations by running the  Django’s built-in development server.

python manage.py runserver

Open your browser and go to this address http://127.0.0.1:8000/ if everything went well you should see this page.

Starting A Django Project
Database Models

Now we will define the data models for our blog. A model is a Python class that subclasses django.db.models.Model, in which each attribute represents a database field. Using this subclass functionality, we automatically have access to everything within django.db.models.Models and can add additional fields and methods as desired. We will have a Post model in our database to store posts.

from django.db import models
from django.contrib.auth.models import User


STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

At the top, we’re importing the class models and then creating a subclass of models.Model Like any typical blog, each blog post will have a title, slug, author name, and the timestamp or date when the article was published or last updated.

Notice how we declared a tuple for STATUS of a post to keep draft and published posts separated when we render them out with templates.

The Meta class inside the model contains metadata. We tell Django to sort results in the created_on field in descending order by default when we query the database. We specify descending order using the negative prefix. By doing so, posts published recently will appear first.

The __str__() method is the default human-readable representation of the object. Django will use it in many places, such as the administration site.

Now that our new database model is created we need to create a new migration record for it and migrate the change into our database.

(django) $ python manage.py makemigrations 
(django) $ python manage.py migrate

Now we are done with the database.

Creating An Administration Site

We will create an admin panel to create and manage Posts. Fortunately, Django comes with an inbuilt admin interface for such tasks.

In order to use the Django admin first, we need to create a superuser by running the following command in the prompt.

python manage.py createsuperuser

You will be prompted to enter email, password, and username. Note that for security concerns Password won’t be visible.

Username (leave blank to use 'user'): admin
Email address: [email protected]
Password:
Password (again):

Enter any details you can always change them later. After that rerun the development server and go to the address http://127.0.0.1:8000/admin/

python manage.py runserver

You should see a login page, enter the details you provided for the superuser.

Django Admin login

After you log in you should see a basic admin panel with Groups and Users models which come from Django authentication framework located in django.contrib.auth.

Building a Blog application with Django
Still, we can’t create posts from the panel we need to add the Post model to our admin.

Adding Models To The Administration Site

Open the blog/admin.py file and register the Post model there as follows.

from django.contrib import admin
from .models import Post 

admin.site.register(Post)

Save the file and refresh the page you should see the Posts model there.

Building Blog application with django admin
Now let’s create our first blog post click on the Add icon beside Post which will take you to another page where you can create a post. Fill the respective forms and create your first ever post.

Writing blog Post with Django
Once you are done with the Post save it now, you will be redirected to the post list page with a success message at the top.

Building a Blog Application With Django

Though it does the work, we can customize the way data is displayed in the administration panel according to our convenience. Open the admin.py file again and replace it with the code below.

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
  
admin.site.register(Post, PostAdmin)

This will make our admin dashboard more efficient. Now if you visit the post list, you will see more details about the Post.

Creating a Blog Application With Django

Note that I have added a few posts for testing.

The list_display attribute does what its name suggests display the properties mentioned in the tuple in the post list for each post.

If you notice at the right, there is a filter which is filtering the post depending on their Status this is done by the list_filter method.

And now we have a search bar at the top of the list, which will search the database from the search_fields attributes. The last attribute prepopulated_fields populates the slug, now if you create a post the slug will automatically be filled based upon your title.

Now that our database model is complete we need to create the necessary views, URLs, and templates so we can display the information on our web application.

Building Views

A Django view is just a Python function that receives a web request and returns a web response. We’re going to use class-based views then map URLs for each view and create an HTML templated for the data returned from the views.

Open the blog/views.py file and start coding.

from django.views import generic
from .models import Post

class PostList(generic.ListView):
    queryset = Post.objects.filter(status=1).order_by('-created_on')
    template_name = 'index.html'

class PostDetail(generic.DetailView):
    model = Post
    template_name = 'post_detail.html'

The built-in ListViews which is a subclass of generic class-based-views render a list with the objects of the specified model we just need to mention the template, similarly DetailView provides a detailed view for a given object of the model at the provided template.

Note that for PostList view we have applied a filter so that only the post with status published be shown at the front end of our blog. Also in the same query, we have arranged all the posts by their creation date. The ( – ) sign before the created_on signifies the latest post would be at the top and so on.

Adding URL patterns for Views

We need to map the URL for the views we made above. When a user makes a request for a page on your web app, the Django controller takes over to look for the corresponding view via the urls.py file, and then return the HTML response or a 404 not found error, if not found.

Create an urls.py file in your blog application directory and add the following code.

from . import views
from django.urls import path

urlpatterns = [
    path('', views.PostList.as_view(), name='home'),
    path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]

We mapped general URL patterns for our views using the path function. The first pattern takes an empty string denoted by ' ' and returns the result generated from the PostList view which is essentially a list of posts for our homepage and at last we have an optional parameter name which is basically a name for the view which will later be used in the templates.

Names are an optional parameter, but it is a good practice to give unique and rememberable names to views which makes our work easy while designing templates and it helps keep things organized as your number of URLs grows.

Next, we have the generalized expression for the PostDetail views which resolve the slug (a string consisting of ASCII letters or numbers) Django uses angle brackets < > to capture the values from the URL and return the equivalent post detail page.

Now we need to include these blog URLs to the actual project for doing so open the mysite/urls.py file.

from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
]

Now first import the include function and then add the path to the new urls.py file in the URL patterns list.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
]

Now all the request will directly be handled by the blog app.

Creating Templates For The Views

We are done with the Models and Views now we need to make templates to render the result to our users. To use Django templates we need to configure the template setting first.

Create directory templates in the base directory. Now open the project’s settings.py file and just below BASE_DIR add the route to the template directory as follows.

TEMPLATES_DIRS = os.path.join(BASE_DIR,'templates')

Now In settings.py scroll to the,TEMPLATES which should look like this.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
            ],
        },
    },
]

Now add the newly created TEMPLATE_DIRS  in the DIRS.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        #  Add  'TEMPLATE_DIRS' here
        'DIRS': [TEMPLATE_DIRS],
        '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',
            ],
        },
    },
]

Now save and close the file we are done with the configurations.

Django makes it possible to separate python and HTML, the python goes in views and HTML goes in templates. Django has a powerful template language that allows you to specify how data is displayed. It is based on template tags, template variables, and template filters.

I’ll start off with a base.html file and a index.html file that inherits from it. Then later when we add templates for homepage and post detail pages, they too can inherit from base.html.

Let’s start with the base.html file which will have common elements for the blog at any page like the navbar and footer. Also, we are using Bootstrap for the UI and Roboto font.

<!DOCTYPE html>
<html>

    <head>
        <title>Django Central</title>
        <link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">
        <meta name="google" content="notranslate" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
            crossorigin="anonymous" />
    </head>

    <body>
        <style>
            body {
            font-family: "Roboto", sans-serif;
            font-size: 17px;
            background-color: #fdfdfd;
        }
        .shadow {
            box-shadow: 0 4px 2px -2px rgba(0, 0, 0, 0.1);
        }
        .btn-danger {
            color: #fff;
            background-color: #f00000;
            border-color: #dc281e;
        }
        .masthead {
            background: #3398E1;
            height: auto;
            padding-bottom: 15px;
            box-shadow: 0 16px 48px #E3E7EB;
            padding-top: 10px;
        }
    </style>

        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg navbar-light bg-light shadow" id="mainNav">
            <div class="container-fluid">
                <a class="navbar-brand" href="{% url 'home' %}">Django central</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">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarResponsive">
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">About</a>
                        </li>
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">Policy</a>
                        </li>
                        <li class="nav-item text-black">
                            <a class="nav-link text-black font-weight-bold" href="#">Contact</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        {% block content %}
        <!-- Content Goes here -->
        {% endblock content %}
        <!-- Footer -->
        <footer class="py-3 bg-grey">
            <p class="m-0 text-dark text-center ">Copyright &copy; Django Central</p>
        </footer>
    </body>
</html>

This is a regular HTML file except for the tags inside curly braces { } these are called template tags.

The {% url 'home' %} Returns an absolute path reference, it generates a link to the home view which is also the List view for posts.

The {% block content %} Defines a block that can be overridden by child templates, this is where the content from the other HTML file will get injected.

Next, we will make a small sidebar widget which will be inherited by all the pages across the site. Notice sidebar is also being injected in the base.html file this makes it globally available for pages inheriting the base file.

{% block sidebar %}

<style>
        .card{
            box-shadow: 0 16px 48px #E3E7EB;
        }
       
</style>

<!-- Sidebar Widgets Column -->
<div class="col-md-4 float-right ">
<div class="card my-4">
        <h5 class="card-header">About Us</h5>
    <div class="card-body">
        <p class="card-text"> This awesome blog is made on the top of our Favourite full stack Framework 'Django', follow up the tutorial to learn how we made it..!</p>
        <a href="https://djangocentral.com/building-a-blog-application-with-django"
           class="btn btn-danger">Know more!</a>
    </div>
</div>
</div>

{% endblock sidebar %}

Next, create the index.html file of our blog that’s the homepage.

{% extends "base.html" %} 
{% block content %}
<style>
    body {
        font-family: "Roboto", sans-serif;
        font-size: 18px;
        background-color: #fdfdfd;
    }
    
    .head_text {
        color: white;
    }
    
    .card {
        box-shadow: 0 16px 48px #E3E7EB;
    }
</style>

<header class="masthead">
    <div class="overlay"></div>
    <div class="container">
        <div class="row">
            <div class=" col-md-8 col-md-10 mx-auto">
                <div class="site-heading">
                    <h3 class=" site-heading my-4 mt-3 text-white"> Welcome to my awesome Blog </h3>
                    <p class="text-light">We Love Django As much as you do..! &nbsp
                    </p>
                </div>
            </div>
        </div>
    </div>
</header>
<div class="container">
    <div class="row">
        <!-- Blog Entries Column -->
        <div class="col-md-8 mt-3 left">
            {% for post in post_list %}
            <div class="card mb-4">
                <div class="card-body">
                    <h2 class="card-title">{{ post.title }}</h2>
                    <p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on}} </p>
                    <p class="card-text">{{post.content|slice:":200" }}</p>
                    <a href="{% url 'post_detail' post.slug  %}" class="btn btn-primary">Read More &rarr;</a>
                </div>
            </div>
            {% endfor %}
        </div>
        {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
    </div>
</div>
{%endblock%}

With the {% extends %} template tag, we tell Django to inherit from the base.html template. Then, we are filling the content blocks of the base template with content.

Notice we are using for loop in HTML that’s the power of Django templates it makes HTML Dynamic. The loop is iterating through the posts and displaying their title, date, author, and body, including a link in the title to the canonical URL of the post.

In the body of the post, we are also using template filters to limit the words on the excerpts to 200 characters. Template filters allow you to modify variables for display and look like {{ variable | filter }}.

Now run the server and visit http://127.0.0.1:8000/ you will see the homepage of our blog.

blog made with django

Looks good..!

You might have noticed I have imported some dummy content to fill the page you can do the same using this lorem ipsum generator tools.

Now let’s make an HTML template for the detailed view of our posts.

Next, Create a file post_detail.html and paste the below HTML there.

{% extends 'base.html' %} {% block content %}

<div class="container">
  <div class="row">
    <div class="col-md-8 card mb-4  mt-3 left  top">
      <div class="card-body">
        <h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
        <p class="card-text ">{{ object.content | safe }}</p>
      </div>
    </div>
    {% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
  </div>
</div>

{% endblock content %}

At the top, we specify that this template inherits from.base.html Then display the body from our context object, which DetailView makes accessible as an object.

Now visit the homepage and click on read more, it should redirect you to the post detail page.

Blog detail page with django

Extending The Application

Adding Comments System – https://djangocentral.com/creating-comments-system-with-django/

Adding Pagination to the Index page – https://djangocentral.com/adding-pagination-with-django/

Integrating PostgreSQL with Django – https://djangocentral.com/using-postgresql-with-django/

Configuring static assets – https://djangocentral.com/static-assets-in-django/

Integrating Summernote WYSIWYG Editor – Integrating Summernote WYSIWYG Editor in Django 

Creating Sitemap – https://djangocentral.com/creating-sitemaps-in-django/

Creating Feeds – https://djangocentral.com/creating-feeds-with-django/

Uploading Images – How To Upload Images With Django

Deploy Django Application – How To Deploy Django App with Nginx, Gunicorn, PostgreSQL and Let’s Encrypt SSL on Ubuntu

We have come to the end of this tutorial. Thank you for reading this far. This post is just the tip of the iceberg considering the number of things you could do with Django.

We have built a basic blog application from scratch! Using the Django admin we can create, edit, or delete the content and we used Django’s class-based views, and at the end, we made beautiful templates to render it out.

If you are stuck at any step, refer to this GitHub repo

Support Django Central

If you appreciate my work, or if it has helped you along your journey. It would mean a lot to me if you could write a message on my wall and share a cup of coffee (or tea) with me.
Buy Me a Coffee at ko-fi.com

109 thoughts on “Building A Blog Application With Django”

    • Let me teach you some manners.

      You first start with:”Thank you for your great post, It’s been really helpfull”.
      Then you make a suggestion: “I was thinking that a comment feature in a blog would be really useful. I hope one day you could add it”.

      You end up with a thank you note: “Thanks again for sharing your knowledge with us. Looking forward to most post of yours”.

      Stop being an ungrateful idi*t..

      Reply
  1. Thanks for the great start to a blog. How would you go about defining a function for not displaying the “draft” posts from the index page in the views.py? I was trying something like the following but I’m not sure where to enter either the value of 1 or Publish.

    def get_queryset(self):
    self.status = get_object_or_404(Status, name=self.kwargs[‘status’])
    return Post.objects.filter(status=self.status)

    As a note in the section where adding the “TEMPLATES_DIR” the “S” is missing from the word Template in the code example (github has it correctly). Secondly how would you go about defining a function for hiding the “draft” posts from the index page in the view?

    Reply
  2. Hello there, amazing work.
    This is my first-time with django and you made it very easy to understand. Thank you.
    The only problem i have is my homepage is still showing the default page and not the blog home page, even after i created the templates folder.

    Reply
  3. please note that in a fresh django installation, you have to create superuser first then import and use User from auth.models.

    it seems that User is not created before you runb and create admin user (superuser)

    Reply
    • That’s not the suggested way to retrieve the active user Model.

      I always suggest using `from django.contrib.auth import get_user_model`
      then following the import statements with `User = get_user_model()`

      Reply
  4. How do i make a post like this, because on the example is all text, and i’d like to have images, titles, li, and more, as this one.

    Reply
  5. Thanks for a good description on how to use build things in Django. I am totally new in this language, but so far I like it!

    I do have a problem in the section “Adding Models To The Administration Site”
    I have written this in the file:
    from django.contrib import admin
    admin.site.register(Post)

    But I get a NameError: name ‘Post’ is not defined
    Can some one help me with what I am missing?

    Reply
  6. I cannot wait to try out this tutorial. I’m coming over from Flask and Django seems to really tie things together well.

    Reply
  7. hello sir thank u for this tremendous work………………………..am requesting for your help am stack some where but i dont why……..
    TEMPLATES_DIR = os.path.join(BASE_DIR,’templates’) where exactly a we supposed to put this code because am pasting it but doesnt work below is where am pasting it but its showing an error when you run the server that invalid syntax help me pliz am new in this MAY GOD BLESS YOU WITH MORE KNOWLEDGE
    DATABASES = {
    ‘default’: {
    ‘ENGINE’: ‘django.db.backends.sqlite3’,
    ‘NAME’: os.path.join(BASE_DIR, ‘db.sqlite3’),
    ‘TEMPLATES_DIR’ = os.path.join(BASE_DIR,’templates’)
    }
    }

    Reply
  8. Hey thanks man for this great tutorial 🙂 i am gonna give it try. i will try to extend it. i wanna ask did you develop this your personal blog using django?

    Reply
  9. This is an awesome article and I have lerant a lot but I am not clear on this part: {% for post in post_list %}
    where did the post_list variable come from?

    Reply
  10. Hey, thank you for your wonderful article!

    I’m trying to create a blog from your code. However, seems like this code has a problem. The navigation toggle is not working. I search everywhere but still can’t fix the problem. Can you take a look at this bug?

    Reply
  11. In settings.py
    from
    # Add ‘TEMPLATE_DIR’ here
    ‘DIRS’: [TEMPLATE_DIR],
    make it
    # Add ‘TEMPLATES_DIR’ here
    ‘DIRS’: [TEMPLATES_DIR], <==

    so variable stays consistent throughout.

    Reply
  12. Instead of {% block sidebar %} {% include ‘sidebar.html’ %} {% endblock sidebar %} you should use {% include ‘sidebar.html’ %}

    Reply
    • WordPress is open-source, updated regularly and it saves time. If I create my own CMS, I will have to deal with vulnerabilities, script and compatibility issues with browsers and a full-fledged blog like this requires a lot of plugin for optimum performance which would take a lot of time to develop so as I was already familiar with WordPress so instead of reinventing the wheel I choose this as my blogging platform.

      Reply
  13. Hi there. Thanks for such a detailed guide.

    I a have a problem with the last step: it shows empty site without the posts I made in the admin panel.

    I guess it might be because I use PostgresQL and not standard Django DB.
    Migrations are ok, I can see all my articles in the database.

    But how do I make them appear on the site?
    Thanks.

    Reply
  14. In the database models section, what python file are we editing? I searched around and couldn’t find it referenced. Is this still in settings.py?

    Reply
    • I went the the GitHub code and downloaded it. If anyone was wondering on the answer to this question, it is in the models.py file.

      Reply
  15. Hi man sorry for disturbing but i’m getting this error when i run my page after usning the base and the index.html
    can you help with this error, i am new to django Please

    ImproperlyConfigured at /
    PostList is missing a QuerySet. Define PostList.model, PostList.queryset, or override PostList.get_queryset().
    Request Method: GET
    Request URL: http://127.0.0.1:8000/
    Django Version: 2.2.6
    Exception Type: ImproperlyConfigured
    Exception Value:
    PostList is missing a QuerySet. Define PostList.model, PostList.queryset, or override PostList.get_queryset().
    Exception Location: C:\Users\Charles\AppData\Local\Programs\Python\Python37-32\lib\site-packages\django\views\generic\list.py in get_queryset, line 39
    Python Executable: C:\Users\Charles\AppData\Local\Programs\Python\Python37-32\python.exe
    Python Version: 3.7.1
    Python Path:
    [‘D:\\Django Project\\MySite’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\lib’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\win32’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\win32\\lib’,
    ‘C:\\Users\\Charles\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\Pythonwin’]
    Server time: Tue, 19 Nov 2019 05:05:27 +0000

    Reply
  16. Hi, thanks for the explicit tutorial. However I’d like to see how pictures are incorporated with the models so that a blog post can have a picture also display and not text only. Thanks

    Reply
  17. Hey
    superb tutorial is easy to follow compared to the documentation, i have a problem with the urls
    SystemCheckError: System check identified some issues:

    ERRORS:
    ?: (urls.E004) Your URL pattern [, <URLPattern '/’ [name=’post_detail’]>] is invalid. Ensure that urlpatterns is a list of path() and/or re_path() instances.

    i just copy pasted the url file from the blog so can you please help me

    Reply
  18. Hello
    I can’t deal with the sidebar block. We’ve injected its code into the base.html file, but there is line “include ‘sidebar.html'” in index.html, and we don’t have one. How do I need to make sidebar block visible in my template?
    Thank you

    Reply
  19. Can anyone describe the post_detail.html file. Here he used object.title and post.author simultaneously. i don’t understand object here n its not working in my project either.

    Reply
  20. perhaps it would be better if you added a like toggle button to all of the blog to allow a user upvote or downvote a blog

    Reply
  21. Checked your problem but couldn’t really figured out the solution but you can check things given below:
    *its says ‘ImproperlyConfigured’. So, i think there might be configuration problem.
    or,
    *what i faced following this blog instruction is that there 4 .html pages. base.html, sidebar.html, index.html and post_detail.html (sequentially to the blog .html content). so make sure you have organised those correctly.
    or,
    *might be inner coding structure problem.

    -Good luck

    Reply
  22. Hi there, thanks very much for posting this tutorial. Very helpful.
    Following your steps, I found,

    queryset = Post.objects.filter(status=1).order_by(‘-created_on’)
    in the view.py
    it says, “objects” is not defined, any idea what happened? or it is the version of Django? thanks again.

    Reply
  23. Hey! I keep getting an error that says…

    The included URLconf ‘mysite.urls’ does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

    Please let me know how to fix it.. thanks!

    Reply
  24. Hi! Thanks so much for this article, I’m getting started and it’s really easy to follow.

    I think I spotted a typo: under ‘Creating And Activating A Virtual Environment’ -> ‘Mac and Unix Users’ I think line 3 should read as ‘python3 -m venv django’ rather than ‘python3 -m venv myenv’.

    Thanks 🙂

    Reply
  25. hi Team,
    Yestaerday I created blog and it is working but when I trying run th elocal host it showing below error

    “…can’t open file ‘manage.py’: [Errno 2] No such file or directory”
    ‘I am runing the same directory

    Reply
  26. Great, thank you!

    I found a typo in:
    TEMPLATES_DIR = os.path.join(BASE_DIR,’templates’)
    and
    # Add ‘TEMPLATE_DIRS’ here
    ‘DIRS’: [TEMPLATE_DIRS],

    Reply
  27. Very helpful tutorial, but looking at the Git and the article here it looks like you might have a typo in the section where you create the ‘templates’ directory (not complaining, but it was a sticking point for me as a total newcomer to this). It looks like you meant it to be “TEMPLATES_DIR” in both instances but you define it as “TEMPLATES_DIR” and then reference “TEMPLATE_DIRS” below.
    Found the correct solution in Git, but for ease and clarity wanted to make sure this was brought up so you might be able to adjust for the future.

    Thanks!

    Reply
  28. For some reason, after following your instructions… I don’t get the “db.sqlite3” after running [python manage.py startapp blog]. I believe this is the root of my problem.

    Though, I also tried many times (start from scratch everytime) even experimented, everything seems fine even with that missing but when i [runserver] before [migrate]…. i get error 404 on my browser… something with /catalog and urls.py

    Can you please advice me of what to do. I’m a newbie with no programming related education or background… BUT i’m proficient as a front-end user and able to use finished products applications. Now, I’m trying to learn Python programming.

    Reply
  29. Hey man.

    I’m trying to add a little detail to the site that you built. So basically I want my first blog post to basically be the “About” page, and then I want the “About” link in the base.html template to link to the post_detail page with the slug being my very first post. I’ve been having issues doing that thought. I basically want something like:

    {% if post_list[0] %}
    About →
    {% else %}
    About
    {% endif %}

    But then i get the following error:

    Could not parse the remainder: ‘[0]’ from ‘post_list[0]’

    Is this because the template_name for the PostLIst view is index.html instead of base.html? Would I have to create an entirely different view for this to work?

    Thanks!

    Reply
  30. Thanks for a great tutorial. I still don’t know if i should include the line in the settings file: (more likely not)
    TEMPLATES_DIRS = os.path.join(BASE_DIR,’templates’)

    it works fine without it.

    also: ‘DIRS’: [TEMPLATE_DIRS], line replaced with ‘DIRS’: [‘templates’],

    the template directory you put in the project “mysite” folder or blog folder?

    Reply
  31. Nice article, in index.html where doest “post_list” come from, the view is called PostList.

    If I grep the code base, it’s the only mention of “post_list”. The code appears to work fine, so is this a django thing where it takes a camelcase view and separates it with underscores?

    Reply
  32. hii, i am getting this error….please help!!
    NoReverseMatch at /

    Reverse for ‘post_detail’ with arguments ‘(‘ggggk’,)’ not found. 1 pattern(s) tried: [‘/’]

    Reply
  33. Hello it really helped me but my website has a page for posts and details. I have linked all my html files from views.py and urls.py but when it comes to the post page it is showing me the error I could link this project to my main project. Could you help me with that?

    Reply
  34. Great article! I only have 1 question and it’s been asked a few times here with no real answer.
    where did you get the post_list template variable from in {% for post in post_list %}
    You had said from the views, but there is no mention of post_list anywhere else in the whole project besides in index.html
    Thank you so much, and again great article.

    Reply
  35. Nice work. Thanks a lot.
    However, I encounter one problem when I want to read the detailed news.
    I suppose the problem is due to the “/” in the urls.py.
    With your guideline, I created “My first post” with the slug “my-first-post”. However, we did not create the ./my-first-post directory so far. Therefore, when I want to extend the news by the “read more” button. There is an error and part of the error is shown as follows:
    **********************************************************
    TypeError at /my-first-post/
    __init__() takes 1 positional argument but 2 were given
    Request Method: GET
    Request URL: http://127.0.0.1:6541/my-first-post/
    Django Version: 3.1
    Exception Type: TypeError
    Exception Value:
    __init__() takes 1 positional argument but 2 were given
    **********************************************************
    Of course, I can create the directory by myself. But that is different with your guideline. Can you give me some hints?

    Reply
  36. Thank you for creating and sharing this valuable information. Im new to programming and this is teaching me alot.

    I noticed on the installation of the blog [python manage.py startapp blog] db.sqlite3 was not installed. There was a post with the same problem but there was no reply. Im using VSCode

    Will you be able to assist.

    Thank You.

    Reply
  37. queryset = posts.objects.filter(status=1).order_by(‘-data_created’)
    i have a problem in posts it told me that class posts doesn’t have objects

    Reply
  38. Hi, I am getting this error..
    RuntimeError: Model class blog.models.Post doesn’t declare an explicit app_label and isn’t in an application in INSTALLED_APPS.
    Tried adding blog.models.Post to INSTALLED_APPS but then I get another error saying the it cannot be imported.

    Reply
    • have you tried adding only the name of the app under installed apps, example: ‘blog’. Notice blog is a string and therefore the quotes.

      Reply
  39. Noticed that the content of the blog was on one column, how do you make it span several columns?

    Thanks once again for the tutorial.

    Reply

Leave a Comment