Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django models referencing each other

I have two models and I want to put an if condition in my template to get the desired output.
I have the first model

class Subject(models.Model):
    name = models.CharField(max_length=50)
    books = models.ForeignKey('Books')

And the second one

class Books(models.Model):
    name = models.CharField(max_length=50)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)

And a view

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

def View(request):
    subjects = Subject.objects.all()
    return render('my_html.html",{'subjects':subjects})

In my model, I have wanted to do this.

{% for subject in subjects %}
    {% if subject.books.count > 0 %}
        {{ subject.name }}
    {% endif %}
{% endfor %}

I thought the only way is to have the models referencing each other for my plan to work but I also think that looping will require more resources. Is there a better way of doing this either thro’ the view or just in the models?

>Solution :

You only need to ForeignKey from Book to Subject, so:

class Subject(models.Model):
    name = models.CharField(max_length=50)
    # no books

class Books(models.Model):
    name = models.CharField(max_length=50)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)

then you can filter the subjects such that it only retrieves Subjects with at least one book:

def view(request):
    subjects = Subject.objects.filter(books__isnull=False).distinct()
    return render(request, 'my_html.html', {'subjects': subjects})

this will make a LEFT OUTER JOIN on the table of the Book model, and check if there is at least one book. You thus do not need to filter in the template (which is not a good idea anyway).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading