0

I'm trying to display the chapters of the bible using the bible package available here. Some of the codes are deprecated and I have refactored some. I have the JSON file of the bible loaded in my database. I'm also able to display a list of the books of the Bible.

The problem is how to display the chapters of each book by clicking on the name of the book (which is a link). I have tried the following:

models.py

from django.db import models
from .managers import BookManager

class Book(models.Model):
    """
    Book of the Bible
    """
    number = models.PositiveIntegerField(primary_key=True, unique=True,
            db_index=True)
    slug = models.SlugField(unique=True)
    name = models.CharField(max_length=64, db_index=True)
    is_new_testament = models.BooleanField()
    
    objects = BookManager()

    
    def get_absolute_url(self):
        """
        Returns the absolute url
        """
        return reverse('book_detail', [self.slug,])
    
    def __unicode__(self):
        return self.name
    
    class Meta:
        ordering = ['number',]

    
class Chapter(models.Model):
    """
    Chapter of the Bible
    """
    book = models.ForeignKey(Book, related_name='chapters', on_delete=models.CASCADE)
    number = models.PositiveIntegerField(db_index=True)
    
    def __unicode__(self):
        return '%s %s' % (self.book.name, self.number)
    
    def get_next_chapter(self):
        try:
            return Chapter.objects.filter(
                book=self.book,number__gt=self.number).order_by(
                'number')[0]
        except IndexError:
            return None
        
    def get_previous_chapter(self):
        try:
            return Chapter.objects.filter(
                book=self.book,number__lt=self.number).order_by(
                '-number')[0]
        except IndexError:
            return None
    
   
    def get_absolute_url(self):
        """
        Returns the absolute url
        """
        return reverse('chapter_detail', [self.book.slug, self.number])
    
    class Meta:
        ordering = ['number',]
        unique_together=(('book','number',),) 

views.py

from django.http import HttpResponse, Http404
from .models import Book, Chapter, Verse
from django.shortcuts import render
from .context_processors import books_processor, book_processor, \
        chapter_processor


def book_index(request):
    """Show all books of the Bible."""
    books = Book.objects.order_by('number')
    context = {'books': books}
    return render(request, "bible/book_index.html", context)


def book_detail(request, slug):
    """Show a single book and all its chapters."""
    book = Book.objects.get(id=chapter_id)
    chapters = book.chapter_set.order_by('number')
    context = {'book': book, 'chapters': chapters}
    return render(request, 'bible/book_detail.html', context)

Template

{% extends 'app/base.html' %}

{% block page_header %}
<h2>Chapters</h2>
{% endblock page_header %}

{% block content %}
<h5>{{ book }}</h5>

<ul>
    {% for chapter in chapters %}
    <li>
        <p>{{ chapter.number|linebreaks }}</p>
    </li>
    {% empty %}
    <li>There are no chapters for this book yet.</li>
    {% endfor %}
</ul>

{% endblock content %}

urls.py

"""URL patterns for bible."""
from django.urls import path
from . import views

app_name = 'bible'
urlpatterns = [
    # Home page 
    path('book_index/', views.book_index, name='book_index'),
    # Other pages
    path('book_detail/<int:chapter_id>/', views.book_detail, name='book_detail'),

]

The books displays well but when I try to show the chapters of each book, it throws the error:

Template error:
In template... error at line 13
   Reverse for 'book_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['book_detail/(?P<chapter_id>[0-9]+)/\\Z']
   3 : 
   4 : {% block page_header %}
   5 : <h2>Books of the Bible</h2>
   6 : {% endblock page_header %}
   7 : 
   8 : {% block content %}
   9 : <ul>
   10 :     {% for book in books %}
   11 :     <li>
   12 :         <h5>
   13 :             <a href=" {% url 'bible:book_detail' chapter.id %} ">{{ book.name }}</a>
   14 :         </h5>
   15 :     </li>
   16 :     {% empty %}
   17 :     <li>
   18 :         <h5 class="font-italic">No books have been added yet.</h5>
   19 :     </li>
   20 :     {% endfor %}
   21 : </ul>
   22 : 
   23 : {% endblock content %}

I want to be able to see the list of chapters when I click on a book. I've looked at similar tracebacks on Stack Overflow such as this and that but none seemed to help. Would appreciate any help. Thank you.

0 Answers0