DEV Community

Yasser Cherfaoui
Yasser Cherfaoui

Posted on

How to make CMS with Django ?

Hello all dev.to community,
I hope that you receive my post in a good health in a good conditions.
Today we are going to make a CMS(Content Management System) with Django and that covers all the CRUD(Create, Read, Update, Delete) operations and how to do them with Django, and you will see how easy it is.

If you don't like reading, check my video on my YouTube Channel : https://youtu.be/H_iW3Z2ozYE

You can find the final code for this project here : https://github.com/yassercher/CRUD-Django

Enough talk, let's start coding...
First of all we create our project and let's name it crud:

django-admin startproject crud
Enter fullscreen mode Exit fullscreen mode

Then we create our first app:

cd crud
Enter fullscreen mode Exit fullscreen mode
py manage.py startapp main
Enter fullscreen mode Exit fullscreen mode

Now as you see I have named our app main, then we should go to crud/settings.py and declare it inside INSTALLED_APPS list variable like this:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'main' #add this line 
]
Enter fullscreen mode Exit fullscreen mode

Now our projects knows that we have an app called main and it should call it whenever we run the server.
First of all we create our first model Post:
crud/main/models.py

from django.db import models

# Create your models here.


class Post(models.Model):
    title = models.CharField(max_length=255, blank=False, null=False)
    content = models.TextField(blank=False, null=False)

    def __str__(self):
        return self.title

Enter fullscreen mode Exit fullscreen mode

And then we make our URL paths,
_crud/main/urls.py _

from django.urls import path
from .views import index, read, create, delete, update
app_name = 'main'


urlpatterns = [
    path('', index, name='index'),
    path('create/', create, name='create'),
    path('update/<int:post_id>', update, name='update'),
    path('read/<int:post_id>', read, name='read'),
    path('delete/<int:post_id>', delete, name='delete'),
]

Enter fullscreen mode Exit fullscreen mode

Then we need to include them in crud/urls.py:

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

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

Enter fullscreen mode Exit fullscreen mode

For now we code the views:
crud/main/views.py

from django.http import HttpResponse
from django.shortcuts import redirect, render
from .models import Post
# Create your views here.


def index(request):
    data = Post.objects.all()
    return render(request=request, template_name='main/index.html', context={'data': data})


def read(request, post_id):
    if post_id:
        post = Post.objects.filter(pk=post_id)

    return render(request=request, template_name='main/read.html', context={'post': post.get()})


def update(request, post_id):
    if post_id:
        post = Post.objects.filter(pk=post_id)
    if request.POST:
        n_t = request.POST['title']
        n_c = request.POST['content']
        post.update(title=n_t, content=n_c)
        return redirect('/')
    return render(request=request, template_name='main/update.html', context={'post': post.get()})


def delete(request, post_id):
    if post_id:
        p = Post.objects.filter(pk=post_id)
        p.delete()
        return HttpResponse('Post has been successfully deleted')
    return HttpResponse('insert a post id to delete')


def create(request):
    if request.POST:
        title = request.POST['title']
        content = request.POST['content']
        Post.objects.create(title=title, content=content)
        return redirect('/')
    return render(request=request, template_name='main/create.html', context={})

Enter fullscreen mode Exit fullscreen mode

So far we have worked only on the backend, we should make our frontend now:

  1. Create a directory on /main/ with the name templates.
  2. Create a subdirectory with the name main.
  3. Create four HTML files: index.html, create.html, read.html, update.html Now paste the code there: crud/main/templates/main/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"
    />
    <title>CRUD Project</title>
  </head>
  <body>
    <h1 class="title is-2">Welcome to the CRUD Project</h1>
    {% for post in data %}
    <div class="card">
      <header class="card-header">
        <p class="card-header-title">{{post.title}}</p>
        <button class="card-header-icon" aria-label="more options">
          <span class="icon">
            <i class="fas fa-angle-down" aria-hidden="true"></i>
          </span>
        </button>
      </header>
      <div class="card-content">
        <div class="content">{{post.content}}</div>
      </div>
      <footer class="card-footer">
        <a href="{% url 'main:read' post.id %}" class="card-footer-item"
          >Read</a
        >
        <a href="{% url 'main:update' post.id %}" class="card-footer-item"
          >Update</a
        >
        <a href="{% url 'main:delete' post.id %}" class="card-footer-item"
          >Delete</a
        >
      </footer>
    </div>
    {% endfor %}
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

crud/main/templates/main/create.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"
    />
    <title>Create a new Post</title>
  </head>
  <body>
    <h1 class="title is-3">Create a new post</h1>
    <form method="POST">
      {% csrf_token %}
      <div class="field">
        <label class="label">Title</label>
        <div class="control">
          <input
            class="input"
            type="text"
            placeholder="Text input"
            name="title"
          />
        </div>
      </div>

      <div class="field">
        <label class="label">Content</label>
        <div class="control">
          <textarea
            class="textarea"
            placeholder="Textarea"
            name="content"
          ></textarea>
        </div>
      </div>

      <div class="field is-grouped">
        <div class="control">
          <button class="button is-link">Submit</button>
        </div>
        <div class="control">
          <button class="button is-link is-light">Cancel</button>
        </div>
      </div>
    </form>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

crud/main/templates/main/update.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"
    />
    <title>Update Post</title>
  </head>
  <body>
    <h1 class="title is-3">Update Post</h1>
    <form method="POST">
      {% csrf_token %}
      <div class="field">
        <label class="label">Title</label>
        <div class="control">
          <input
            class="input"
            type="text"
            placeholder="Text input"
            name="title"
            value="{{post.title}}"
          />
        </div>
      </div>

      <div class="field">
        <label class="label">Content</label>
        <div class="control">
          <textarea class="textarea" placeholder="Textarea" name="content">
{{post.content}}
        </textarea
          >
        </div>
      </div>

      <div class="field is-grouped">
        <div class="control">
          <button class="button is-link" type="submit">Update</button>
        </div>
        <div class="control">
          <button class="button is-link is-light">Cancel</button>
        </div>
      </div>
    </form>
  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

crud/main/templates/main/read.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Read Post {{post.id}}</title>
  </head>
  <body>
    <h1>{{post.title}}</h1>
    <p>{{post.content}}</p>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now all what we have to do is to make migrations so that the database creates new tables for our models, and then apply them:

py manage.py makemigrations
Enter fullscreen mode Exit fullscreen mode
py manage.py migrate
Enter fullscreen mode Exit fullscreen mode

Finally run the server and that's it :)

py manage.py runserver
Enter fullscreen mode Exit fullscreen mode

That was everything for today, thank you so much for your time if you like the post, give it a like and follow me for more content like this.

Top comments (0)