How to show multiple objects in Django detailview

I have two models created, one Topic and another Entries. Listview showing all the Topics link. Clicking on each topic link will show all the entries related to that particular topic. I have created multiple entries for each Topic. DetailView only showing single entries for each topic link. How to show multiple entries for each topic link using DetailView?

Models.py

class Topic(models.Model):
    '''A topic that user will add the content about.'''
    title = models.CharField(max_length=200)

class Entries(models.Model):
    '''Entries and Topic will have many to one relationship'''
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
    text = models.TextField()
    image = models.ImageField(upload_to='images', blank=True)
    date_added = models.DateTimeField(auto_now_add=True)

views.py

class TopicListView(ListView):
    model = Topic
    template_name = 'cms_app/topic_list.html'
    context_object_name = 'topic'

class ContentDetailView(DetailView):
    model = Entries

urls.py

urlpatterns = [
    path('', TopicListView.as_view(), name = 'all-topic'),
    path('content/<int:pk>', ContentDetailView.as_view(), name = 'all-content'),
]

Topic.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>All Topics</title>
</head>
<body>
    <h1>Topic List</h1>
    <h3>
    {% for data in topic %}
        <p><a href="{% url 'all-content' data.id %}">{{ data.title }}</a></p>
    {% endfor %}
    </h3>
</body>
</html>

Entries.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>All Contents</title>
</head>
<body>
        <p>{{object.text }}</p>
        <p>{{object.image }}</p>
        <p>{{object.date_added }}</p>
</body>
</html>

You have configured ContentDetailView with model = Entries. A DetailView only looks up a single object from the database and makes that available in the context, so it is only giving you one Entries object. Further, you are passing a Topic ID value in the URL to ContentDetailView. That means you are passing something like Topic ID 1 to the URL, but it is then looking up the Entries object with an ID of 1 and displaying that Entries object, even though that Entries object may not even be related to the Topic that was clicked.

You need to change ContentDetailView to look up the Topic that was clicked:

class ContentDetailView(DetailView):
    model = Topic
    context_object_name = 'topic'

And then change Entries.html to iterate over the Entries in the selected Topic:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>All Contents</title>
</head>
<body>
    <div>Topic: {{ topic.title }}<div>

    {% for entry in topic.entries_set.all %}
        <p>{{object.text }}</p>
        <p>{{object.image }}</p>
        <p>{{object.date_added }}</p>
    {% endfor %}
</body>
</html>

I have got the resolution for my code and sharing the same here. Below code allowing me to add multiple instances of each model through DetailView in Django.

So for my Entries model if I have 10 instances created. Below code allowing me to show all those 10 instances on the detail View page which I wanted to do when user will click on the Topic link.

class ContentDetailView(DetailView):
    model = Entries

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        c_id = get_object_or_404(Topic, pk = self.kwargs['pk'])
        context['content'] =  Entries.objects.filter(topic_id = c_id)
        return context
 
Now we have to loop through this content key in the template to get all the instance data we have created for single model.

entries_detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>All Contents</title>
</head>
<body>
    {% for obj in content %}
        <p>{{ obj.text }}</p>
        <p>{{ obj.image }}</p>
        <p>{{ obj.date_added }}</p>
    {% endfor %}
</body>
</html>
Вернуться на верх