CRUD

Create

Creating a record in Django usually involves a form, a view to handle the form submission, and a template for the user interface.

Step 1: Add a “Create” Button or Link

In an exisiting template, provide a way to go to a "create new item" page:

<a href="{% url 'add' %}">Add New Item</a>

Step 2: Create a Template for Adding Items

In add_item.html:

<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Add Item</button>
</form>

Step 3: Define the view

In views.py:

from django.shortcuts import render, redirect
from .forms import ItemForm

def add_item(request):
    if request.method == 'POST':
        form = ItemForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('get_todo_list')  # Redirect to your list page
    else:
        form = ItemForm()
    return render(request, 'todo/add_item.html', {'form': form})

Step 4: Add the url

In urls.py:

from . import views
path('add/', views.add_item, name='add'),

Read

Reading records means fetching data from the database and rendering it in a template.

Step 1: Query the Database

In views.py:

from django.shortcuts import render
from .models import Item

def get_todo_list(request):
	# Fetch all the items
    items = Item.objects.all()  # Fetch all items
	# Add to context
	context = {
		'items': items,
}
    return render(request, 'todo/todo_list.html', context)

Step 2: Create the Template

In todo_list.html:

<h1>My To-Do List</h1>
<ul>
    {% for item in items %}
        <li>{{ item.name }} - {% if item.done %}Done{% else %}Pending{% endif %}
            <a href="{% url 'edit' item.id %}">Edit</a>
            <a href="{% url 'delete' item.id %}">Delete</a>
        </li>
    {% empty %}
        <li>No items found.</li>
    {% endfor %}
</ul>
<a href="{% url 'add' %}">Add a new item</a>

Step 3: Add URL

In urls.py:

from . import views
path('', views.get_todo_list, name='get_todo_list'),

Update

Updating records in Django involves:

  • Retrieving an existing database object
  • Populating a form with its current data
  • Saving changes back to the database

This process is commonly used for features like editing items in a Model instance, updating user profiles, or managing content in a web app.

Step 1: Add an Edit Button in Your Template

To let users access an edit page, add a button or link in your template that points to the edit view. Pass the object's ID in the URL so Django knows which record to edit:

Step 2: Create an Edit Template

The edit template is usually similar to your create template, but this form is populated with the current data of the record (handled in the view).

<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save Changes</button>
</form>

You don't need to specify a form action attribute. By default, the form posts to the current URL (which is what we want for editing).

Step 3: Define the Edit View

In views.py, create a function-based view that retrieves the object to edit, pre-populates a form with its current data, and handles the submission of updated values.

from django.shortcuts import render, get_object_or_404, redirect
from .models import Item
from .forms import ItemForm

def edit_item(request, item_id):
    item = get_object_or_404(Item, id=item_id)
    
    if request.method == 'POST':
        form = ItemForm(request.POST, instance=item)
        if form.is_valid():
            form.save()
            return redirect('get_todo_list')  # Redirect to a list or detail view
    else:
        form = ItemForm(instance=item)

    context = {'form': form}
    return render(request, 'todo/edit_item.html', context)
  • get_object_or_404() retrieves the item by its ID or returns a 404 error if not found.
  • instance=item tells the form to pre-fill with the existing item's data.
  • If the form is valid on POST, form.save() updates the record in the database.
  • On success, we redirect to another page (often the item list or detail page).

Step 4: Update urls.py

In your app's urls.py, define a path for the edit page.

from django.urls import path
from .views import edit_item

urlpatterns = [
    path('edit/<int:item_id>/', edit_item, name='edit'),
]

This matches URLs like /edit/3/ to edit the item with ID 3.

Delete

Deleting items is easy. Simply add a button to the HTML page linked to a URL that is in turn linked to a view. It is best practice not to link the first delete link to this URL but instead send it to a new template or modal with a confirm/cancel button to introduce some defensive programming and prevent accidental deletion of instances in your database.

Step 1: Add a Button in Your Template

The button will need to pass an identifier through to the URL. In the following case we will delete an instance of the item, identified by it's ID value.

<a href="{% url 'delete' item.id %}">Confrim</a>

Step 2: Create a Delete View

The delete view will take the identifying value (here the item ID) and use it to query the database to get the correct instance. It will then delete the item and redirect the user.

def delete_item(request, item_id):
    item = get_object_or_404(Item, id=item_id)
    item.delete()
    return redirect('get_todo_list')

Step 3: Add URL

In urls.py:

from . import views
path('delete/<int:item_id>/', views.delete_item, name='delete'),

Deleting as a form:

If you decide that you want to use the delete function as a submission of a form present on a delete.html page. The form will have the syntax of:

<form method="post" action="{% url 'delete_item' item.id %}">

You will need to add in a check for the method being POST in the view, with the deletion functionality in the if statement and the page rendering in the else statement.