Go – how to design model for the case with django

djangomodel

Here are two roles: Trainer and Trainee. Trainer may have multiple trainees. While each trainee may have only one trainer or have no trainer.

Here is my model:

class TrainerShip(models.Model):
    trainer = models.ForeignKey('Trainer')
    trainee = models.ForeignKey(User)
    request_date = models.DateTimeField(auto_now_add=True)
    accept_date = models.DateTimeField(auto_now_add=True)
    expiration_date = models.DateTimeField(auto_now_add=True)

class Trainer(models.Model):
    user = models.ForeignKey(User, unique=True)
    trainee = models.ManyToManyField(User, through=TrainerShip)
    introduction = models.TextField(max_length=500)
    certification = models.TextField(max_length=300)
    specialties = models.TextField(max_length=300)
    contact = models.TextField(max_length=100)
    active = models.BooleanField(default=False)

I was getting following error when trying to create db:

shen@shen-laptop:~/django/sutifang$ ./manage.py syncdb
Error: One or more models did not validate:
registration.trainer: Accessor for field 'user' clashes with related m2m field 'User.trainer_set'. Add a related_name argument to the definition for 'user'.
registration.trainer: Accessor for m2m field 'trainee' clashes with related field 'User.trainer_set'. Add a related_name argument to the definition for 'trainee'.

Anyone has the idea to solve this problem? Is there a better way to model this kind of relationship?

Best Answer

The problem is that a Foreign key established a bidirectional relationship. This means you can do User.trainer_set to get all of the Trainer models under a User, which means you have a circular reference back to the user database (getting the Trainer models gets all of its fields, one of those fields being the original User model.

So, to fix this, add a related name argument to the Foreign key to stop this circular dependency:

user = models.ForeignKey(User, unique=True, related_name='traineruser')

You can replace traineruser with something that does not already have a table in the database.

Related Topic