Search code examples
djangodjango-modelsdjango-templatesdjango-viewsone-to-many

How to retrieve data from one to many relations in django?


I am making my personal website using django 1.10

Here is models of skill app:

from __future__ import unicode_literals

from django.db import models


# Create your models here.
class Skill(models.Model):
    name = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)

    def __unicode__(self):
        return self.name

    def __str__(self):
        return  self.name


class Subskill(models.Model):
    skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
    name = models.CharField(max_length=256)
    link = models.CharField(max_length=256)
    created_at = models.DateTimeField(auto_now=False, auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True, auto_now_add=False)

    def __unicode__(self):
        return self.name

    def __str__(self):
        return self.name

And view:

from django.shortcuts import render
from skill.models import Skill,Subskill


# Create your views here.
def home(request):        
    skill = Skill.objects.all()
    subskill =Subskill.objects.all()    
    context = {'skills':skill,
               'subskills':subskill}
    return render(request, 'skill.html', context)

This is my template page:

skill.html

{% block skill %}
{% for subskill in subskills %}
{{subskill.skill.name}}
{{subskill.name}}
{% endfor %}
{% endblock skill %}

Let assume, there is a skill named web design which has two subskill named html and css. I want to render in view page as like as skill name and it's two child name:

Web design

Html

CSS

But it renders as like Web design Html Web design CSS

Please help me about this issue.


Solution

  • You can do realted query on skill itself https://docs.djangoproject.com/en/1.10/topics/db/queries/#backwards-related-objects

    # example
    skill_obj = Skill.objects.all()[0]
    subskills = skill_obj.subskill_set.all()
    

    Or in your case

    def home(request):        
        skills = Skill.objects.all().prefetch_related('subskill_set') # optimizing
        context = {'skills':skills}
        return render(request, 'skill.html', context)
    

    In template

    {% for skill in skills %}
        {{skill.name}}
        {% for subskill in skill.subskill_set.all %}
            {{subskill.name}}
        {% endfor %}
    {% endfor %}