CRUD in Django - potatoscript/django GitHub Wiki

🍩 CRUD Operations – Create, Read, Update, Delete

CRUD means:

  • πŸ†• Create something new
  • πŸ‘€ Read and show data
  • ✏️ Update what’s already there
  • ❌ Delete stuff when you don’t need it

With Django, this is actually fun to build! Let's create a small blog-like app to understand everything 🌱


πŸ”§ Step 1: Setup – Let's Create a Model

In models.py, we make a model called Post.

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

πŸ—‚οΈ Step 2: Make Migrations & Migrate

python manage.py makemigrations
python manage.py migrate

Now Django creates a database table for Post βœ…


✨ Step 3: Create Sample Data (Optional)

In the Django admin panel or shell:

python manage.py shell
from yourapp.models import Post
Post.objects.create(title='My First Post', content='Hello Django!')

🎯 CRUD Operations in Django Using CBVs (Class-Based Views)


πŸ†• C = Create a New Post

πŸ‘©β€πŸ« View (in views.py)

from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Post

class PostCreateView(CreateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'post_form.html'
    success_url = reverse_lazy('post-list')

🌐 URL (in urls.py)

path('post/new/', PostCreateView.as_view(), name='post-create'),

πŸ“„ Template (post_form.html)

<h1>πŸ†• Create New Post</h1>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Create</button>
</form>

πŸ‘€ R = Read (View All Posts or One Post)

πŸ“‹ List View – Show All Posts

from django.views.generic import ListView

class PostListView(ListView):
    model = Post
    template_name = 'post_list.html'
    context_object_name = 'posts'
path('', PostListView.as_view(), name='post-list'),

πŸ“ post_list.html

<h1>πŸ“ƒ All Posts</h1>
<ul>
  {% for post in posts %}
    <li>
      <a href="{% url 'post-detail' post.pk %}">{{ post.title }}</a>
    </li>
  {% endfor %}
</ul>
<a href="{% url 'post-create' %}">βž• Add New Post</a>

πŸ”Ž Detail View – Show One Post

from django.views.generic import DetailView

class PostDetailView(DetailView):
    model = Post
    template_name = 'post_detail.html'
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),

πŸ“ post_detail.html

<h2>{{ object.title }}</h2>
<p>{{ object.content }}</p>
<p><a href="{% url 'post-update' object.pk %}">✏️ Edit</a></p>
<p><a href="{% url 'post-delete' object.pk %}">❌ Delete</a></p>

✏️ U = Update a Post

from django.views.generic.edit import UpdateView

class PostUpdateView(UpdateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'post_form.html'
    success_url = reverse_lazy('post-list')
path('post/<int:pk>/edit/', PostUpdateView.as_view(), name='post-update'),

βœ… We reuse the same post_form.html template!


❌ D = Delete a Post

from django.views.generic.edit import DeleteView

class PostDeleteView(DeleteView):
    model = Post
    template_name = 'post_confirm_delete.html'
    success_url = reverse_lazy('post-list')
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),

πŸ“ post_confirm_delete.html

<h2>πŸ—‘οΈ Are you sure you want to delete "{{ object.title }}"?</h2>
<form method="post">
    {% csrf_token %}
    <button type="submit">Yes, delete</button>
    <a href="{% url 'post-list' %}">Cancel</a>
</form>

🧠 Full CRUD Flow Summary

Action URL View Template
Create /post/new/ PostCreateView post_form.html
Read All / PostListView post_list.html
Read One /post/1/ PostDetailView post_detail.html
Update /post/1/edit/ PostUpdateView post_form.html
Delete /post/1/delete/ PostDeleteView post_confirm_delete.html

πŸ›  Tips

  • πŸ” Use LoginRequiredMixin if users must log in
  • 🎨 Style with Bootstrap or Tailwind CSS
  • πŸ§ͺ Test with python manage.py runserver

⚠️ **GitHub.com Fallback** ⚠️