Skip to content

2. CRUD

Django provides an Object-Relational Mapper (ORM) that allows us to perform CRUD (Create, Read, Update, Delete) operations on database models easily.

You can insert data using:

  • .save()
  • .create()
  • .bulk_create()
from myapp.models import Post
post = Post(title="New Post", content="This is a new blog post.")
post.save() # Saves data to the database
Post.objects.create(title="Another Post", content="Created using create()")
Post.objects.bulk_create([
Post(title="Post 1", content="Content 1"),
Post(title="Post 2", content="Content 2"),
])

You can retrieve data using:

  • .all()
  • .filter()
  • .get()
  • .values()
  • .count()
posts = Post.objects.all()
for post in posts:
print(post.title, post.content)
post = Post.objects.get(id=1) # Get the post with ID = 1
print(post.title)

⚠️ .get() raises an error if no object is found.

posts = Post.objects.filter(title="New Post") # Filter by title
posts = Post.objects.values('title', 'content') # Returns a dictionary-like QuerySet
count = Post.objects.count() # Count total number of records

You can update data using:

  • Modify an object and call .save()
  • Use .update() for multiple records
post = Post.objects.get(id=1)
post.title = "Updated Title"
post.save()
Post.objects.filter(title="Old Title").update(title="New Title")

You can delete data using:

  • .delete()
  • .filter().delete() for multiple records
post = Post.objects.get(id=1)
post.delete()
Post.objects.filter(title="Old Title").delete()
Post.objects.all().delete()
views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post
from .forms import PostForm
# Create a new post
def create_post(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('post_list') # Redirect to post list
else:
form = PostForm()
return render(request, 'blog/create_post.html', {'form': form})
# Read all posts
def post_list(request):
posts = Post.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts})
# Update a post
def update_post(request, post_id):
post = get_object_or_404(Post, id=post_id)
if request.method == 'POST':
form = PostForm(request.POST, instance=post)
if form.is_valid():
form.save()
return redirect('post_list')
else:
form = PostForm(instance=post)
return render(request, 'blog/update_post.html', {'form': form})
# Delete a post
def delete_post(request, post_id):
post = get_object_or_404(Post, id=post_id)
if request.method == 'POST':
post.delete()
return redirect('post_list')
return render(request, 'blog/delete_post.html', {'post': post})
create_post.html, update_post.html
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
post_list.html
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
<a href="{% url 'update_post' post.id %}">Edit</a>
<a href="{% url 'delete_post' post.id %}">Delete</a>
{% endfor %}
delete_post.html
<form method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ post.title }}"?</p>
<button type="submit">Yes, Delete</button>
</form>
urls.py
from django.urls import path
from .views import create_post, post_list, update_post, delete_post
urlpatterns = [
path('', post_list, name='post_list'),
path('create/', create_post, name='create_post'),
path('update/<int:post_id>/', update_post, name='update_post'),
path('delete/<int:post_id>/', delete_post, name='delete_post'),
]