Lewis
Lewis

Reputation: 2798

Django: How to ensure a parent class only has one child instance

This a theoretical question which I want to reapply to my own study. However, say I have three models:

class Person(models.Model)
   first_name = models.CharField(max_length=100)
   last_name = models.CharField(max_length=100)

class Teacher(Person)
   teacher_id = models.IntegerField()

class Student(Person)
   student_id = models.IntegerField()

What database/model restrictions can I put in place to ensure that an instance from both children cannot be created with the same Person parent.

Also, probably haven’t used the best example but assume Person can be created explicitly also.

Note: Obviously I could put a small check when saving but was hoping for something more "Pythonic"

Update (Further Definition)

Note: This is just to demonstrate that children can share the same parent.

Lets say we have a Person.

>>> person = Person.objects.create(first_name="Joe", last_name="Bloggs")
>>> person
<Person: Person object (1)>

And we create a Student.

>>> student = Student.objects.create(first_name="Joe", last_name="Bloggs", student_id=1234)
>>> student
<Student: Student object (1)>

And also create a Teacher

>>> teacher = Teacher.objects.create(first_name="Joe", last_name="Bloggs", teacher_id=12)                                           
>>> teacher                 
<Teacher: Teacher object (1)>

I can assign both the teacher and student to the person instance. Like so:

>>> person.teacher = teacher
>>> person.student = student
>>> person.student
<Student: Student object (7)>
>>> person.teacher
<Teacher: Teacher object (7)>

In some cases a Student may also be a Teacher. However, in my particular scenario a Person in cannot be both a Student and a Teacher.

Upvotes: 0

Views: 367

Answers (1)

Rvector
Rvector

Reputation: 2452

As you described the models above, you don't have to add explicit restriction to check if an instance from both children cannot be created with the same Person parent.

Because : Teacher and Student are also Person objects. It's the multi table inheritance.

Let's test it

from app_name.models import Person, Teacher, Student

p1 = Person.objects.create(first_name='name1', last_name='name2')
p1.id
# output -> 1

t1 = Teacher.objects.create(first_name='name1', last_name='name2', teacher_id=1)
t1.id
# output -> 2 (The previous person id + 1)

s1 = Student.objects.create(first_name='name1', last_name='name2', student_id=1)
s1.id
# output -> 3 (The previous person, because student is a person 2 + 1 = 3)

As you can see all Person child are different Pk. Because all are the same Person object

Upvotes: 1

Related Questions