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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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