Flamiooo
Flamiooo

Reputation: 69

How to Get Items in a model connected to another model using a foreign key in detail view in django?

I am trying to create a cartoon streaming website in which when a user clicks on their cartoon of choice(Eg:Pokemon), they get to see the seasons as a list as well as the detail of the cartoons.

from django.db import models

class Cartoon(models.Model):
    name = models.CharField(max_length=200)
    cover = models.ImageField()
    description = models.TextField()
    start_date = models.CharField(max_length=50)
    end_date = models.CharField(max_length=50)
    
    def __str__(self):
        return self.name 


class CartoonSeason(models.Model):
    cartoon = models.ForeignKey(Cartoon, null=True, on_delete=models.SET_NULL)
    number = models.IntegerField()
    season_cover = models.ImageField(blank=True, null=False)
    season_name = models.CharField(max_length=200, blank=True, null=True)
    season_description = models.TextField(blank=True, null=False)

Here I have linked the Cartoon model with the CartoonSeason model using a Foreign Key so when a new season is to be added, it automatically gets linked with the corresponding Cartoon

from django.shortcuts import render
from django.http import HttpResponse
from  django.views.generic import ListView, DetailView
from .models import CartoonSeason, Cartoon

class CartoonListView(ListView):
    model = Cartoon
    template_name = "index.html"


class CartoonSeasonView(DetailView):
    queryset = CartoonSeason.objects.filter()
    model = CartoonSeason
    template_name = "season.html"

I am using a detail view to display the CartoonSeason model so that it displays the Cartoons details as well, but when I try to load the seasons, it only displays the season with the Primary Key of 1. I want it to display all of the seasons added to the cartoon. Here's my seasons.html

{% extends 'base.html' %}
{% block title %}
    test
{% endblock %}
{% block content %}
    <main>
        <section class="cartoon-description">
            <div class="season_head">
                <img src="{{object.cartoon.cover.url}}" width="260px" alt="">
                <div class="cartoon-name">
                    <h1>{{object.cartoon.name}}</h1>
                    <small >{{object.cartoon.start_date}} - {{object.cartoon.end_date}}</small>
                    <br>
                    <div class="description">
                        <strong>Description:</strong>
                        <br>
                        <p>{{object.cartoon.description}}</p>
                    </div>
                </div>
                
            </div>
        </section>
        <hr>
    </main>
{% endblock %}

Here is My urls.py

from .views import CartoonListView, CartoonSeasonView


urlpatterns = [
    path('', CartoonListView.as_view(), name="home"),
    
    path('cartoon/<int:pk>' , CartoonSeasonView.as_view(), name="cartoon"),
    
 
]

This is my main template

{% extends 'base.html'%}

{% block title %}
    Home - CartoonsPalace
{% endblock %}
{% block content %}

<main>
    <section class="cartoon-list">
        <div class="select-text">
            <h1>Pick Your Cartoon Series of Choice:-</h1>
        </div>
        {% for cartoon in object_list %}
        <div class="list">
            <a href="{% url 'cartoon' cartoon.pk %}"><div class="list-object">
                
                <img src="{{cartoon.cover.url}}" alt="" width="184px">
                <h3>{{cartoon.name}}</h3>
                <span>{{cartoon.start_date}} - {{cartoon.end_date}}</span>
            </div>
        </a>
        </div>
        {% endfor %}
    </section>
</main>



{% endblock %}


Any help would be appreciated.

Upvotes: 0

Views: 52

Answers (1)

Roohollah Mozaffari
Roohollah Mozaffari

Reputation: 96

Ok when you want to access all the objects related to another objects through foreign key , you have two simple options : 1.set query using the cartoon(reverse relation):

cartoon = Cartoon.objects.get(id = 'pk') # get the pk by passing in url
cartoon_season = cartoon.cartoonseason_set.all()
# object.(name of model CartoonSeason must be in lowercase )._set.all()

or set query using the CartoonSeason(recommended):

#before this you must have the id of the cartoon :
cartoon = Cartoon.objects.get(id = pk)
seasons = CartoonSeason.objects.filter(cartoon = cartoon)

I dont know about you cartoon template or urls, but I assume in you cartoon template where you show your cartoon detail you have a link to the season of the cartoon ,so there you should pass the id of the cartoon : {{cartoon.id}} and in you urls you get this id to use in your season detail : but note that when you are using DetailView and want to use that id passing by url you shoud define a get_queryset like this :

class CartoonSeasonView(DetailView):
    model = CartoonSeason
    template_name = "season.html"
    def get_queryset(self, *args, **kwargs):
        #before this you must have the id of the cartoon :
        cartoon = Cartoon.objects.get(id = self.kwargs['pk'])
        seasons = CartoonSeason.objects.filter(cartoon = cartoon)

and remember no need to user have query_set anymore. by this you can show the name of the cartoon or the poster in the cartoonseason page. and remember we user detail view in order to show detials of only one object not 7 ( like season of a cartoon ).You can use ListView or if you want to show different data in one template use TemplateView.

Upvotes: 1

Related Questions