Ahsaan-566
Ahsaan-566

Reputation: 603

How to access foreign key in a django template? (ListView)

In my project, the Profile model has Foreign Key relation with Education instance. Here are my models:

class Profile(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, null=True, blank=True)
    full_name = models.CharField(max_length=30, null=True, blank=True)
    education = models.ForeignKey(Education, on_delete=models.SET_NULL, null=True, blank=True, related_name="education")

class Education(models.Model):
    degree = models.CharField(max_length=100, null=True, blank=True)
    school = models.CharField(max_length=100, null=True, blank=True)
    edu_start_date = models.DateField(null=True, blank=True)
    edu_end_date = models.DateField(null=True, blank=True)

    def __str__(self):
        return str(self.degree)

Now, using the Django ListView, I am not being able to display the data of foreign key. My views:

class EducationView(CreateView):
    form_class = EducationForm
    pk_url_kwarg = 'pk'
    template_name = "profile_settings.html"

class EducationList(ListView):
    model = Profile
    queryset = Profile.objects.all()
    context_object_name = 'object'
    pk_url_kwarg = 'pk'
    template_name = "profile_settings.html"

Template

{% for obj in profile.education.all %}
    <div class="col-lg-12">
        <h2>{{ obj.degree }}</h2>
        <br>
        <div>
            {{ obj.school }}
        </div>
    </div>
    <br>
{% endfor %}

Education form saves data to the database but I couldn't fetch it using the template code.

Note: I'm using single template for CreateView and ListView.

Upvotes: 0

Views: 921

Answers (2)

sarathkumar P M
sarathkumar P M

Reputation: 131

In ListView you specified context_object_name as 'object'. So inside the template, the context is referred to an object.

So the code look like

{% for each_profile in object %}
    {% for obj in each_profile.education.all %}
        <div class="col-lg-12">
            <h2>{{ obj.degree }}</h2>
            <br>
            <div>
                {{ obj.school }}
            </div>
        </div>
        <br>
    {% endfor %}
{% endfor %}

Upvotes: 1

ruddra
ruddra

Reputation: 51988

You need to do it like this:

{% for obj in object %}  <!-- as your context_object_name is `object` -->
    <div class="col-lg-12">
        <h2>{{ obj.education.degree }}</h2>  <!-- accessed foreign key -->
        <br>
        <div>
            {{ obj.education.school }}  <!-- accessed foreign key -->
        </div>
    </div>
    <br>
{% endfor %}

Update

If you are using this template in create view then update the View like this:

class EducationView(CreateView):
    form_class = EducationForm
    pk_url_kwarg = 'pk'
    template_name = "profile_settings.html"

    def get_context_data(self, **kwargs):
        context = super(EducationView, self).get_context_data(**kwargs)
        context['profiles'] = Profile.objects.all()  # I don't want to mix up `object` here. so using profiles
        return context

Now in ListView and template, we are going to update context object as well:

# view
class EducationList(ListView):
    model = Profile
    queryset = Profile.objects.all()
    context_object_name = 'profiles'
    template_name = "profile_settings.html"

# template

{% for obj in profiles %}
    <div class="col-lg-12">
        <h2>{{ obj.degree }}</h2>
        <br>
        <div>
            {{ obj.school }}
        </div>
    </div>
    <br>
{% endfor %}

Upvotes: 1

Related Questions