0

I'm working on my first Django app. My goal is to have two models, one for offices and one for employees, and when a person record is created (in the admin site), creating and specifying the room also populates that room with that person.

I was able to create the models, but now I'm stuck in a catch-22 where when I add a person, I have to create a room, but to create a room I have to add a person, etc...

How can I create and automatically populate a room like this?

Here is the relevant code from models.py:

class Room(models.Model):
    number = models.CharField('Room number', primary_key=True, max_length=50)
    occupant = models.ManyToManyField('Person', blank=True) # Can have multiple occupants

class Person(models.Model):
    name = models.CharField('Full name', max_length=200)
    office = models.ForeignKey(Room, on_delete=models.SET_NULL, null=True) # Some offices may not have an occupant

Update: I added blank=True to office so I can create an office with no occupant. But, even when I add a person and assign their office to that number, and it shows that in the admin page, the detail-view page doesn't seem to grab that, unless I manually go into the Room admin page and select the person. Can that part be automated?

Evan
  • 1,960
  • 4
  • 26
  • 54
  • 2
    1. You do not need the field `office`, the relation is created by the M2M field `occupant`. By convention you should name `occupant`, `persons`. 2. You are having a semantic error imo, you cannot add a person to room until the person object is created. 3. I suggest you let Django set the pk on Room, vice using a charfield, which could be problematic. I would add `unique=True` to number. – diek Jun 22 '18 at 23:14
  • Thanks for pointing out the convention and semantic errors, great to correct those. Some of the `office` entries might not have a `person` associated, so I think I need to keep it (edited question); maybe i have its type incorrect. – Evan Jun 22 '18 at 23:37
  • When you create a m2m, 3 tables are created. look at the tables created, there are 3, office, person and persons. The persons table (many to many) consists of 3 fields id, office_id and person_id. http://i67.tinypic.com/sbt0s1.png – diek Jun 23 '18 at 02:13
  • as the above comments suggested, you dont need the `office` field, if you want the `Room` of an `Person` you can use [reverse](https://stackoverflow.com/questions/9352662/how-to-use-the-reverse-of-a-django-manytomany-relationship) relation look-up – Bijoy Jun 23 '18 at 07:16
  • To use reverse relation look-up do I have to include multiple models in `views`? I changed the person-detail view to display their room to: `{{ room.persons_set.all() }}` (as shown in the linked example), and that returns `Could not parse the remainder: '()'`. Clearly I'm not understanding something. – Evan Jun 25 '18 at 17:41
  • Did you fix you model, and remove the foreign key? Next I suggest you open up the django shell, and try a few examples, like this: https://dpaste.de/FHaj – diek Jun 28 '18 at 18:25
  • @diek I tried removing `office` from `Person` and the reverse relation look-up above. I tried your example code, but I just get an error `'Person' object has no attribute 'rooms'` when I try `Bird.rooms.add(B104)`. I tried adding the `office` field again and my site seems to work fine -- why is it bad to have that field, is it because of redundancy? – Evan Jun 29 '18 at 17:44
  • @Bird I have modified my code, moving the m2m to the room to mirror your example https://dpaste.de/kHGB, here is a template with the room and occupants, https://dpaste.de/3qGU – diek Jun 30 '18 at 03:09

0 Answers0