Evan
Evan

Reputation: 2038

Look up field from a different Django model given another model field

I have two models in Django: Room for offices, and Person for employees. One office could have multiple employees. I'm trying to make a detail-view html page that shows a person's details, like their name and office number. I can get the details from the Person model fine, but I'm having trouble doing a reverse look-up to the Room model. How can I get a person's office given the following code?

#models.py
class Room(models.Model):
    number = models.CharField('Room number', unique=True)
    persons = models.ManyToManyField('Person', blank=True)
    #...

class Person(models.Model):
    name = models.CharField('Full name', max_length=200)
    #...


#views.py
from django.views import generic
class PersonDetailView(generic.DetailView):
    model = Person


#person_detail.html
{% extends "base_generic.html" %}

{% block content %}

    <h1>Name: {{ person }}</h1>
    <p>Room: {{ Room.number }}</p>


{% endblock %}

All that currently does is return a name, but "Room" is left blank.

Upvotes: 0

Views: 49

Answers (1)

Alexandre Cox
Alexandre Cox

Reputation: 528

You could overload the get_context_data method

class PersonDetailView(DetailView):
model = Person
context_object_name = 'person'
template_name = 'person_detail.html'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # woops, typo
    # context['room'] = Room.objects.filter(person=context['object']).first()
    context['room'] = Room.objects.filter(persons=context['object']).first()
    return context

And the template:

#person_detail.html
{% extends "base_generic.html" %}

{% block content %}

    <h1>Name: {{ person }}</h1>
    <p>Room: {{ room.number }}</p>


{% endblock content %}

Edit: But you might be better off with Person having a models.ForeignKey pointing to a Room, so a Person can only have one Room, but many Person can have the same Room.

You could then keep your orginal view and change your template:

    #person_detail.html
{% extends "base_generic.html" %}

{% block content %}

    <h1>Name: {{ person }}</h1>
    <p>Room: {{ person.room.number }}</p>


{% endblock content %}

Upvotes: 1

Related Questions