Setup

Run these commands to setup a base project:

python3 -m venv venv
source venv/bin/activate
pip install django
django-admin startproject mysite .
python manage.py startapp blog
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Edit the mysite/settings.py file and add the following line:

INSTALLED_APPS = [
    'blog.apps.BlogConfig', # HERE
    'django.contrib.admin',
    'django.contrib.auth',
    # ...
  ]

Edit the blog app models.py file and add a new class called Post to it:

from django.db import models

class Post(models.Model):
    title = models.TextField(default='',
                             blank=True)

Run the following commands:

python manage.py makemigrations
python manage.py migrate

Edit the blog app admin.py file and add these lines to it:

from django.contrib import admin

from blog.models import Post

admin.site.register(Post)

Create form

Create a file called forms.py in the blog app directory and add these lines to it:

from django.forms import ModelForm
from blog.models import Post

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ['title']

Edit the blog/views.py file and add a new view function called create to it:

from django.shortcuts import render, redirect
from blog.models import Post
from blog.forms import PostForm

def create(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('blog_create')
    else:
        form = PostForm()
    return render(request,
                  'blog/create.html',
                  {
                      'form': form
                  })

Edit the main urls.py file and add these lines to it:

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

import blog.views

urlpatterns = [
    path('create/', blog.views.create, name='blog_create'),
    path('admin/', admin.site.urls),
]

Create a file called create.html in the blog/templates/blog directory and add these lines to it:

<h1>Add new post</h1>
<form action="{% url 'blog_create' %}"
      method="post">
      {% csrf_token %}
      {{ form.as_p }}
<button class="button" type="submit">Create</button>
</form>

Visit /create/ to create items:

Edit form

Edit the blog/views.py file and add a new view function called edit to it:


from django.shortcuts import render, redirect, get_object_or_404

def edit(request, pk=None):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST,
                        instance=post)
        if form.is_valid():
            form.save()
            return redirect('blog_create')
    else:
        form = PostForm(instance=post)

    return render(request,
                  'blog/edit.html',
                  {
                      'form': form,
                      'post': post
                  })

Create a file called edit.html in the blog/templates/blog directory and add these lines to it:

<h1>Edit post</h1>
<form action="{% url 'blog_edit' post.pk %}"
      method="post">
      {% csrf_token %}
      {{ form.as_p }}
<button class="button" type="submit">Update</button>
</form>

Edit the main urls.py file and add this line to it:

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

import blog.views

urlpatterns = [
    path('create/', blog.views.create, name='blog_create'),
    # START
    path('edit/<int:pk>/', blog.views.edit, name='blog_edit'),
    # END
    path('admin/', admin.site.urls),
]

Visit /edit/<id>/ to edit an item:

Delete form

Edit forms.py file in the blog app directory and add these lines to it:

from django.forms import ModelForm
from blog.models import Post

class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ['title']

# START
class PostDeleteForm(ModelForm):
    class Meta:
        model = Post
        fields = []
# END

Edit the blog/views.py file and add a new view function called delete to it:

from blog.forms import PostForm, PostDeleteForm

def delete(request, pk=None):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostDeleteForm(request.POST,
                              instance=post)
        if form.is_valid():
            post.delete()
            return redirect('blog_create')
    else:
        form = PostDeleteForm(instance=post)

    return render(request, 'blog/delete.html',
                  {
                      'form': form,
                      'post': post,
                  })

Create a file called delete.html in the blog/templates/blog directory and add these lines to it:

<h1>Delete post</h1>
<form action="{% url 'blog_delete' post.pk %}" method="post">

    {% csrf_token %}
    {{ form }}

    Are you sure you want to delete post:
    <br><br>
    {{ post.title }}?
    <br><br>

    <button class="button" type="submit">Delete</button>

    <a href="{% url 'blog_create' %}">Cancel</a>

</form>

Edit the main urls.py file and add this line to it:

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

import blog.views

urlpatterns = [
    path('create/', blog.views.create, name='blog_create'),
    path('edit/<int:pk>/', blog.views.edit, name='blog_edit'),
    # START
    path('delete/<int:pk>/', blog.views.delete, name='blog_delete'),
    # END
    path('admin/', admin.site.urls),
]

Visit delete/<id>/ to delete an item: