26. Deleting and updating records

We’ve now seen Django ORM operations that map to table creation in our migrations, row insertion in the script that we made, and stable querying in the views that we’ve been writing with the GET and filter operations.

The last two ORM operations of note are deleting records or updating them. Deleting will of course, permanently remove records from your database and updating will permanently change records. Let’s start by looking at updating.

Let’s say we are interested in our application keeping track of some access statistics. Say the number of times that users access our gene records. Let’s jump over to VSC, navigate to the genedata application, open the models file and navigate to the gene. Then we can add a new field to our gene table – let’s call it access.

So in models.py, in the Gene class, add this line under ec = …

access = models.IntegerField(null=False, blank=False, default=0)

If we go back to views.py, we will note the gene function which returns the gene.html template. We can change this so that the function also increments the new access field in the gene table by 1.

def gene(request, pk):
    gene = Gene.objects.get(pk=pk)
    gene.access += 1
    print("Gene record:", pk, "access count:", str(gene.access))
    gene.save()
    return render(request, 'genedata/gene.html', {'gene': gene})

This makes the query to get the object where the primary key in the table matches the number sent in the function parameters, increments gene.access by 1, prints a record of the new access count, and then saves it, before rendering the gene page requested.

Now we need to save all page and stop the server if it’s still running.

Because we added a column to the database, we need to do makemigrations again. When we do, we’ll get a result like this:

Migrations for 'genedata':
  genedata\migrations\0003_gene_access.py
    - Add field access to gene

Then you can apply the migration by running python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, genedata, sessions
Running migrations:
  Applying genedata.0003_gene_access... OK

Now we can restart the server and go to http://127.0.0.1:8000/ again

If we click on gene1, we’ll see the record for gene1. But now if we look at the server logs in the CMD window, we can see this printed out:

Gene record: 2 access count: 1
[03/Nov/2021 15:40:35] "GET /gene/2 HTTP/1.1" 200 978

We could also now add a delete button to every record.

In the gene template gene.html we can add this link:

DELETE RECORD

Next in urlpatterns in urls.py we need to add a new path for the delete URL we just mentioned above.

path('delete/', views.delete, name='delete'),

views.delete promises there is a delete function in views, but this is yet to be written. So we need to go to views.py and add it:

def delete(request, pk):
    GeneAttributeLink.objects.filter(gene_id=pk).delete()
    Gene.objects.filter(pk=pk).delete()
    return HttpResponseRedirect("/")

This is deleting the gene not just from the gene table but also in the link table where that record exists. We have to delete the link first.

We can see return HttpResponseRedirect which sends us back to the menu. We also need to import this in our page to make it work:

from django.http import HttpResponseRedirect

Quick quiz!

Given the following SQL statements, what would you expect the Django code to be?

1. SELECT * FROM Genes;
2. SELECT * FROM People WHERE name=’jack’;
3. SELECT * FROM Books WHERE publication_date >= ‘1980-01-01’ AND publication_data <= '2000-01-01'; Answers: 1. genes = Gene.objects.all() 2. people = People.objects.filter(name='jack') 3. books = Book.objects.filter(publication_data__gte='1980-01-01', publication_data__lte='2000-01-01')

Wednesday 3 November 2021, 15 views


Leave a Reply

Your email address will not be published. Required fields are marked *