Work listing page
Add a page to list works.
In this section
Adding a view and template to list all works
How to link to an expression
Getting the latest expression for a work
Work listing view
On our app's homepage, we're going to list all the works.
Let's create the View code to handle this in views.py
. We'll use Django's generic ListView
view which does all the work for us.
from django.views.generic import ListView
from .models import Work
class WorkListView(ListView):
model = Work
Now create the matching template. Django will automatically look for a file called templates/reader/work_list.html
:
<html>
<head><title>All my works</title></head>
<body>
<h1>Cape Town By-laws</h1>
<table>
{% for work in work_list %}
<tr>
<td>{{ work.title }}</td>
<td>{{ work.frbr_uri }}</td>
</tr>
{% endfor %}
</table>
</body>
Finally, let's add this view legislation/urls.py
:
from django.urls import path
from reader.views import *
urlpatterns = [
path('', WorkListView.as_view(), name="home"),
]
Now we need to run our server:
python manage.py runserver
Visit http://localhost:8000 and see you list of by-laws!
We now have a basic listing page that shows the titles and FRBR URIs of all the works.
How can we create a link to read the content of a by-law? If we change the table to make the title a link, what exactly are we linking to?
Linking to an expression
Recall that a work may have multiple expressions. For example, there could be different languages and different amended versions of a work.
When we link to the content of a work, which expression are we linking to?
For our app, we want to link to the latest version of a work. We're also going to add a DEFAULT_LANGUAGE_CODE
setting for the site. We'll look for expressions that are in that language first, and then fall back to any language.
Let's add a helper method latest_expression
to the Work model to help us fetch the latest expression for the work.
from django.db import models
from django.conf import settings
default_language_code = settings.READER_APP_SETTINGS['DEFAULT_LANGUAGE_CODE']
class Work(models.Model):
frbr_uri = models.CharField(max_length=512, unique=True)
title = models.CharField(max_length=512)
metadata = models.JSONField()
def __str__(self):
return f'{self.title} ({self.frbr_uri})'
def default_expression(self):
# first, try to get the latest expression in the default language
expression = self.expressions.filter(language_code=default_language_code).first()
# otherwise, get the latest expression in any other language
if not expression:
expression = self.expressions.first()
return expression
Let's add the new DEFAULT_LANGUAGE_CODE
to legislation/settings.py
:
# ...
READER_APP_SETTINGS = {
'DEFAULT_LANGUAGE_CODE': 'eng',
}
Now we can update the template to link to the latest expression.
<html>
<head><title>All my works</title></head>
<body>
<h1>Cape Town By-laws</h1>
<table>
{% for work in work_list %}
<tr>
<td>
{% with work.default_expression as expr %}
{% if expr %}
<a href="{% url 'expression' expr.frbr_uri %}">{{ expr.title }}</a>
{% else %}
{{ work.title }}
{% endif %}
{% endwith %}
</td>
<td>{{ work.frbr_uri }}</td>
</tr>
{% endfor %}
</table>
</body>
We need to add the view and URL configuration for the expression
URL before these changes will work. We'll do that in the next section.
Last updated