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>