Thank you very much for the great answer! 
You are correct, I didn't had a clear understanding of the RelatedObject 
Principle. I think I added this when I was fiddling with the rest framework.
Of course, I also had thought about making MasterUser a boolean, but I need 
to ensure that there is only one MasterUser. I thought about doing it in 
the Code, but I thought it might be better to enforce it at Database Level. 
However, I think your solution is much better. 
I also thought having a separate Table for the MasterUser Relationship, 
like you suggested. I tried to some find some suggestions on how to model a 
relationship like that. I think, I will go for the boolean field but my 
intuitive assumption would be to overwrite the pre_save method. post_save 
kinda sounds like it is too late at that point. 

Anyway, thanks a lot for you recommendations!

On Friday, May 19, 2017 at 5:50:42 PM UTC+2, Melvyn Sopacua wrote:
>
>  
>
> Yep, let me see if I got it right:
>
> - The User model is defined as AUTH_USER_MODEL in settings.py
>
> - User points to institute
>
> - Institute points to User
>
>  
>
> So it is in fact a circular dependency on the model level as well. And one 
> you don't need.
>
>  
>
> From the way you defined the related_name it is also clear you don't get 
> the RelatedObject principle of Django.
>
>  
>
> A ForeignKey creates a bridge between two models: you can travel in both 
> directions. Using your models:
>
>  
>
> class User(AbstractBaseUser, PermissionsMixin):
>
> username = ...
>
>  
>
> class Institute(models.Model):
>
> master_user = models.ForeignKey(settings.AUTH_USER_MODEL, 
> related_name='institute')
>
> members = models.ManyToManyField(settings.AUTH_USER_MODEL)
>
>  
>
> Because of the ForeignKey on Institute, Django creates an attribute on 
> User, called 'institute'. It uses institute, because I specified that as 
> related_name. You could use a different name there, but it has to be a name 
> that can be used on the model you point to.
>
>  
>
> However, this isn't a good representation of realitity, given your own 
> description.
>
> So this is a better way to do it:
>
>  
>
> class User(AbstractBaseUser, PermissionsMixin):
>
> institute = models.ForeignKey('port.Institute', related_name='members')
>
> is_master_user = models.BooleanField(default=False)
>
>  
>
> class Institute(models.Model)
>
> name = models.CharField(max_length=255)
>
> # members is now created by the foreign key
>
> @property
>
> def master_user(self):
>
> return self.members.get(is_master_user=True)
>
>  
>
> This model is much simpler. All you need to do is to verify that when 
> someone is made master user, that all other members of the institute are 
> *not* master user.
>
>  
>
> You can do this in a post_save signal or in the clean method of User , 
> both with its own caveats.
>
>  
>
> Another way would be to define a MasterUser model, which is easier to 
> maintain in the admin:
>
>  
>
> class MasterUser(models.Model):
>
> # Assume one person can be master user of many institutes
>
> # if not, this also has to be a OneToOneFIeld
>
> user = models.ForeignKey(settings.AUTH_USER_MODEL)
>
> institute = models.OneToOneField(Institute, related_name='master_user')
>
> -- 
>
> Melvyn Sopacua
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/8c82ccfa-769f-4218-bff5-5adb7d851f97%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to