James, Thank you for your long and detailed answer. I agree with you in all of your points and I think that your solution is correct.
2017-10-25 2:52 GMT+02:00 James Schneider <[email protected]>: > > > On Oct 24, 2017 3:46 AM, "Andréas Kühne" <[email protected]> > wrote: > > Hi all, > > I would love to pick your collective brains for a second. I am working on > an application that will be first and foremost an administration system. As > such there will be very few users in the system. It will have a front end > developed in angular 5 and a Django rest framework backend. > > I have got the solution up and running currently and it works as I think > it should. However - now I have another idea that I would like to hear your > opinions on. > > Connected to this system we will also have other portals where a user will > be able to login - NOT the same user as the user that logs onto the > administration system - but an entirely different concept (a participant). > These portals will probably be running on another machine (but not > necessarily) and can have their own user concept. This application will > also be more of a traditional Django project with a standard view and > template driven design. > > I am thinking about creating the Participant model separate from the User > (they are different concepts) and therefore was wondering if it would be > possible to create the Participant model based on an AbstractUser from > django contrib auth and then in the portal project use that as the user > model? > > > Short answer is yes, with caveats, but it may not be recommended. > > The long answer: There's no technical reason that a model defined in one > project cannot serve as a reference for another project. The common code > just needs to be accessible from both projects. This works the same way as > any other Python library, because after all, Django models are just Python > code. > > There are logical and design issues with doing it, though. A change in the > Admin project for the abstract user model will now propagate to the > Participant project, possibly in a negative way. You'll need to execute > tests for both your Admin and Participant projects whenever changes are > made to that model. Adding new features is usually easy, but deprecating > code can be a nightmare, as you now have two code bases that need to be > analyzed rather than one. You've also directly coupled the two projects > together from a semantic versioning standpoint. Even with no changes to the > Participant project, a change to the abstract model in the Admin project > now forces a migration for the Participant project (if a field is > modified), and likely a version bump for the Participant project so that > those running your software pick up the changes, even though there were no > modifications made to the Participant project itself. > > I'd ask how important it is that these two models be coupled in such a > way? Granted, adding common fields between the two is handy, but for the > reasons above, it can be dangerous. It's likely that the Admin project only > needs a very small subset of the fields that the Participant project needs, > and the Admin app has no use for any of the authentication/authorization > backend functionality that gets dragged along with AbstractUser. > I think that your solution here would be perfect for my use. Decoupling the users in such a way would not be a problem. > > Has anyone every done anything similar? Is this idea completely wrong? Any > other things that I should think about? > > > Yes, in the sense that developing a 3rd party app for both projects is > effectively what you are doing. These are the same issues faced by 3rd > party app developers for Django, where a 1-line change in a 3rd party > module requires a migration for anyone that is using the app. > > It's not necessarily wrong, there are just a number of issues to consider > with the coupling between the projects that you'll be creating. > > > My main reason behind this idea is that the applications will share the > database, but be completely different projects and shouldn’t necessarily > share a web app? Is this also a wrong idea or does this sound sane? > > > When you say 'share the database', are you referring to the same database > server but separate database instances? Or are you expecting both projects > to access the same tables in the same database instance? > It will be the same tables in the same database instance. > > > All of those issues aside, I wouldn't start with an abstract model > inheriting from AbstractUser. I would create a clean abstract model > inheriting from models.Model, and copy everything from AbstractUser over to > your new abstract user model. Your Admin project would then define a > concrete user model that inherits directly from your new abstract user > model. Over in the Participant project, your concrete model would inherit > from the abstract model created in the Admin project, and also > from AbstractBaseUser and the PermissionsMixin, just like AbstractUser > does. This way, you have a single model controlling what fields are made > available in both applications, but only the Participant project model > contains the extra machinery to use that model to authenticate/authorize > users. The copy/paste operation probably violates DRY for some purists, but > you'll likely be modifying those fields at some point anyway, so I consider > it a necessary evil. > I agree with this setup - however I would like more fine grained permissions in the admin project. > > IMO, the number of fields that actually need to be shared between the > projects is quite small (less than a dozen), and likely will not change > often (hopefully), so the headache of having both coupled to the same > abstract class is not worth it for me. Having a note in each user model > reminding me to update the other would likely be sufficient, so I wouldn't > recommend doing this unless you plan on the base abstract model changing > dramatically over time where sync between the two projects may be > problematic. > > I'm surprised that Django does not break out the AbstractUser fields like > username, etc. into a separate abstract model that does not inherit all of > the authentication backend functionality, as it forces a code copy for > situations like this. Maybe I should do a PR at some point, since that > wouldn't break any existing functionality. > > -James > > -- > 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/CA%2Be%2BciV9-mXKtrtGb4WXEsis% > 3D7ccsHmsivoBiLz80472RaZhyg%40mail.gmail.com > <https://groups.google.com/d/msgid/django-users/CA%2Be%2BciV9-mXKtrtGb4WXEsis%3D7ccsHmsivoBiLz80472RaZhyg%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > Best regards, Andréas -- 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/CAK4qSCfdpuV53d-MGMZ9FisLj5%2Bv%2BcT%2B1EgtPcCDYVhHi3HtFA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.

