Part 6: Django CRUD, Update

Continued from Part 5: Django CRUD, Delete

Full code on https://github.com/shanegibney/djangoCRUD

We may wish to update the model ‘Members’. Let us start by adding an edit icon to the table in ‘index.html’.

<td><a href="{% url 'edit_new' item.id %}"><span class="glyphicon glyphicon-pencil"></span></a></td>

If you are not using Bootstrap replace the span tags with ‘edit’.

<td><a href="{% url 'edit_new' item.id %}">edit</a></td>

This will bring us to a url named ‘edit_new’ and also will pass the ‘id’. Create this url in urls.py,

url(r'^edit/(?P\d+)/$', home.edit_new, name='edit_new'),

Django then brings us to the view ‘edit_new’ which we will now create in ‘views.py’,

def edit_new(request, id):
    post = get_object_or_404(Members, pk=id)
    if request.method == "POST":
        form = MemberForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False) 
            post.save()
            return redirect('init')
    else:
        form = MemberForm(instance=post)
    return render(request, 'member_edit.html', {'form': form})

This is almost identical to the view ‘member_new’ which we used to create a new instance of the model ‘Members’. But this time we use ‘id’ and ‘pk=id’. Again we the ‘.save()’ method to update the model. It is important to use ‘instance=post’ so that the ‘else’ part of the if statement return the current instance of the model ‘Members’ to ‘edit.html’, otherwise we will have a blank form and nothing to edit.
Django then passes the dictionary {‘form’:form} to ‘member_edit.html’ and everything after that works the same as it did when we used the from to create an instance of the model ‘Members’.
This completes the ‘U’ for ‘update’ in CRUD.

Part 5: Django CRUD, Delete

Continued from Part 4: Django CRUD, Create

Full code on https://github.com/shanegibney/djangoCRUD

Next we will delete an instance, or row from the model ‘Members’. First we will place an icon at the end of the row in the table, which we want to delete. Add the following data cell to the table in ‘index.html’,

<td><a href="{% url 'delete_new' item.id %}"><span class="glyphicon glyphicon-trash"></span></a></td>

If you are not using Bootstrap simply replace the span tags with ‘Delete’.

<td><a href="{% url 'delete_new' item.id %}">Delete</a></td>

We can see here that the hyper-link takes us to a url called ‘delete_new’. Also the ‘id’ of the row is passed. We need to create this url in ‘urls.py’ add the following,

url(r'^delete/(?P\d+)/$', home.delete_new, name='delete_new'),

This creates a url for example ‘delete/27’ where 27 is the ‘id’ and this is then passed to the view ‘delete_new’.
Let’s create this view in ‘views.py’. We will need to import ‘get_object_or_404’.

from django.shortcuts import render, get_object_or_404
........
 
def delete_new(request, id):
     post = get_object_or_404(Members, pk=id)
     post.delete()
     return redirect(init)

Here we see that we have passed ‘id’ along with ‘request’. ‘post’ is passed the instance of the ‘Members’ model with pk=id. This object ‘post’ has a method ‘.delete()’, which in the case deletes an instance of the ‘Members’ model. An instance of a class, i.e. ‘Members’ is a row in the database. Next we use ‘redirect’ to go back to the ‘init’ view which renders ‘index.html’.

Now we have an example of the ‘D’ for ‘delete’ in CRUD.

Part 6: Django CRUD, Update

Part 4: Django CRUD, Create

Continued from Part 3: Django CRUD, Display Models

Full code on https://github.com/shanegibney/djangoCRUD

Before starting this section it would be a good idea to include Bootstrap to make use of the classes in the html, but it is not necessary. It is only to make it look nice! To do that add the following lines inside the head tags of index.html.

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

CRUD is an acronym for Create, Read, Update and Delete. First we would like to make a form and send this data to the database or our ‘Members’ model. This will be the Create part of CRUD.
First we need to create a form. But to do that we need to tell Django which fields from the model members to put in the form. Create a new file called ‘forms.py’ and place it in the same place as ‘models.py’.

‘forms.py’ must import forms from Django and your model Members from models. This done by adding to the top of ‘forms.py’

from django import forms
from .models import Members

We create a new model here for the form, but it takes from the current model ‘Members’. This is done with a ‘class Meta’ and we can choose which fields from ‘Members’ we want in the form,

 class MemberForm(forms.ModelForm):
    class Meta:
        model = Members
        # which fields to put in form
        fields = ('first_name', 'last_name', 'description')

We need a link to the url which we are calling ‘member_new’. So in urls.py add in,

url(r'^post/new/$', home.member_new, name='member_new'),

This gives the url a name of ‘member_new’. To get to this url you need a hyper-link in ‘index.html’,

<a href="{% url 'member_new' %}">Add a post</a>

This causes Django to look in urls.py for a url named ‘member_new’ where it is associated with the url ‘post/new/’. Note that is not actually a path called ‘post/new/’. Then Django looks through all these urls again to find the url ‘post/new/’ and see what view it is associated with. In this case the view is ‘home.members_new’. Now will create this view in ‘views.py’,

def member_new(request):

Django first checks if the “POST” method exists. Of course it doesn’t because we haven’t used a form yet. Therefore this section is ignored and Django carries on to the ‘else’.

    if request.method == "POST":
        ..... we will come here after the form is sent ......
    else:
        form = MemberForm()
    return render(request, 'member_edit.html', {'form': form})

The ‘MemberForm’ which we created earlier and has the fields in it is now passed to ‘form’, and the last line renders ‘member_edit.html’ by sending it {‘form’: form}.
We need to create ‘member_edit.html’ in the templates folder. This file will extend ‘index.html’. To create the form itself we only need to wrap in form tags {{ form.as_p }} like this,

{% extends 'index.html' %}

{% block content %}
    <th1>Member form&lt/h1>
    <form method="POST" class="post-form">{% csrf_token %}
        {{ form.as_p }}in the form
        <button type="submit" class="save btn btn-default">Save<button>
    <form>
{% endblock %}

This creates a block called ‘content’ which will be placed by Django in ‘index.html’ if we add to ‘index.html’ the following,

{% block content %}
{% endblock %}

When you run the server you should have a link on the ‘index.html’ page to a form with fields. But you won’t be able to submit because we haven’t finished writing the view ‘member_new’, which is where this form will submit to.

But this time “POST” does exist and so the if statement is not ignored. We need to fill this view in so that completed it looks like this,

def member_new(request):
    if request.method == "POST":
        form = MemberForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = MemberForm()
    return render(request, 'member_edit.html', {'form': form})

Note that we are using ‘redirect’, this needs to be imported by placing the following line at the top of ‘views.py’,

from django.shortcuts import redirect

You can see this passes everything in “POST” to form and validates ‘form’ with ‘.is_valid’. The line ‘form.save…’ saves the form data to memory, not to the database yet. ‘post.save()’ does that. Therefore this is where a new row is added to the database or where the actual ‘create’ in CRUD happens. The next line redirects us to the ‘init’ view. Which recreates the home page and the table of data from the ‘Members’ model.
This concludes the ‘C’ or ‘create’ in CRUD and we have already dealt with the ‘R’ for ‘read’.

Part 5: Django CRUD, Delete

Part 3: Django CRUD, Display Models

Continued from Part 2: Setting up Django, URL’s & Views

Full code on https://github.com/shanegibney/djangoCRUD

Add to the crudapp/models.py file

from django.db import models

In the same file create a model called ‘Members’ with columns for ‘first_name’, ‘last_name’ and ‘description’. This is equivalent to a table called ‘Members’ with fields for ‘first_name’, ‘last_name’ and ‘description’.

class Members(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    description = models.CharField(max_length=600)
    # pub_date = models.DateTimeField('date published')
    def __str__(self):
        return ' '. join([ self.first_name, self.last_name, ])

Give the model an admin interface, in crudapp/admin.py

from .models import Members

admin.site.register(Members)

Go to http://localhost:8000/admin and you will see a model called ‘Memberss’ with effectively rows of the database or as we say in Django instances of the class Member. Note Django places an extra ‘s’ on the class name in admin. Using the Django admin you can now view, edit and delete this model.

Next we will change the cruduapp/views.py file so that it takes data from the model or class Members

from django.shortcuts import render
from .models import Members
# Create your views here.

def init(request):
    details = Members.objects.all()
    context = {'details': details}
    return render(request, 'index.html', context)

This passes all the data in the class Members to index.html where we can display it,

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
  {% if details %}
  <ul>
    {% for item in details %}
    <li>{{ item.description}}</li>
    {% endfor %}
  </ul>
  {% else %}
  <p>No polls are available.</p>
  {% endif %}
</body>

Part 4: Django CRUD. Create