Are we really sure that we can or should stomach a swappable User model as 
a special case?

It's highly likely that I am missing something (or a few things), but 
aren't the main benefits of swapping the User model just to avoid making a 
backwards incompatible change, and to avoid making `select_related()` 
queries?

I'm not suggesting that backwards incompatibility is not important, but I'm 
not convinced by the argument about inefficient `select_related()` queries, 
and whatever we do will involve manual schema migration for many users.

Do we really need to allow users to swap in their own model with a 
combination of additional project level fields as well as additional fields 
required by various pluggable apps as the primary `User` model, instead of 
simply stripping out authentication and identifying fields from the primary 
`User` model and allowing users to implement whatever they need as app or 
project level profile models?

The more I think about it, the more I think this will just lead to more 
fragmentation and incompatibilities with pluggable apps, when the user 
"interface" is abused or causes conflicts.

What's going to happen when this is rolled out and people start developing 
an eco-system of pluggable apps without a concrete `User` model in Django? 
All they can rely on is that there will be some form of `User` model and 
that it *should* provide at least a minimal set of fields and behaviours as 
specified by some guidelines in Django docs?

Won't we just be back at square 1 in deciding what to include in the 
minimal fields and guidelines for the this "contract"? Isn't the only 
sensible minimal set of fields, no fields at all?

Pluggable apps will have to either dictate to developers in the 
installation instructions that their particular `User` model must have 
certain fields or behaviours that are required by the pluggable app, which 
may even conflict with other pluggable apps. Or they will still have to 
fallback to using an app-profile model, which brings us back to using 
`select_related()` anyway. I don't like the idea that a pluggable app might 
require users to change their existing models like this.

If pluggable apps will still need to use app-profile models anyway, if we 
can get past the backwards incompatibility issue, what is so bad about 
simply having a `User` model which has no auth or identity data in it, but 
is just there as glue for for apps to share data for a single "user"?

Bundled apps like the admin would define `AdminProfile` and any pluggable 
apps that require or support the admin could access `user.admin_profile`. 
Pluggable apps that don't use the admin and/or have their own auth or 
identifying requirements can just ship with their own profile and/or auth 
models and optional auth backend.

The only real issue I have with Django users/auth as it is right now is 
that there are redundant (for me) or non-compliant (with RFC) fields in 
`auth.User` that are required and that I have to fake in order to hook into 
the admin, groups and permissions or re-specify in my own profile for 
RFC-compliance.

The other problem I have seen mentioned with the profile approach is 
managing common fields (e.g. two pluggable apps that have a "name" field). 
I'm quite happy for this to be managed by the developer at a project level, 
either using signals or forms or a `save()` method on their profile model 
or whatever else they like to keep that data in sync, if it needs to be 
kept in sync.

I don't think pluggable apps requiring that developers have a "name" (for 
example) field on their primary `User` model is really a good solution to 
this problem, because the pluggable app doesn't know what other purpose 
that field is used for, and doesn't know if it is changed in app1 if it 
will have any consequences for app2.

If developers really want a single project level `User` model, they can 
still create that (with an FK back to Django's `User` model), and simply 
update it's `save()` method to sync any common fields on all the pluggable 
app's profile models (which may even have different field names). E.g. 
`project.User` could have `first_name` and `last_name`, but app1 has only 
`name`, and app2 has `given_name` and `family_name`. In 
`project.User.save()`, the developer of a project can determine how to sync 
this data.

Cheers.
Tai.


On Thursday, 5 April 2012 00:57:57 UTC+10, Jacob Kaplan-Moss wrote:
>
> On Wednesday, April 4, 2012 at 9:44 AM, Russell Keith-Magee wrote:
>
> My point is that there is nothing about this problem that is unique to 
> User. Django's own codebase contains another example of exactly the same 
> pattern -- Comments. 
>
> As the original author and designer of that pattern, I should probably 
> point out that I now think it's a mistake. Have you actually tried using 
> it? It doesn't really work very well. Every time I've introduced any sort 
> of "swappable model" mechanism I've come to regret it.
>
> I'm -1 on the idea of generalized "swappable model" mechanism. I can 
> stomach it for User because in this context it's not any worse than the 
> alternatives, but as a generalized mechanism it makes me really, really 
> unhappy. Decoupling is a laudable goal, but providing a mechanism to reach 
> in and effect code not under your control isn't good design. We use 
> derisive terms like "monkeypatching" for a reason.
>
> I'm sure there are good reasons for wanting swappable models. Russ, I know 
> you're smarter than me, so the fact that you want LazyForeignKey so much 
> probably indicates that you've got some really solid use cases in mind. But 
> really this is a hard veto from me; I just can't be convinced that this 
> sort of mechanism is anything but bad news. 
>
> However, I don't see why we should actively prevent this sort of thing 
> being done externally, so if there's anything in Django that's precluding 
> the creation of a LazyForeignKey as an external add-on let's consider that 
> limitation a bug and get it fixed.
>
> Jacob
>

On Thursday, 5 April 2012 00:57:57 UTC+10, Jacob Kaplan-Moss wrote:
>
> On Wednesday, April 4, 2012 at 9:44 AM, Russell Keith-Magee wrote:
>
> My point is that there is nothing about this problem that is unique to 
> User. Django's own codebase contains another example of exactly the same 
> pattern -- Comments. 
>
> As the original author and designer of that pattern, I should probably 
> point out that I now think it's a mistake. Have you actually tried using 
> it? It doesn't really work very well. Every time I've introduced any sort 
> of "swappable model" mechanism I've come to regret it.
>
> I'm -1 on the idea of generalized "swappable model" mechanism. I can 
> stomach it for User because in this context it's not any worse than the 
> alternatives, but as a generalized mechanism it makes me really, really 
> unhappy. Decoupling is a laudable goal, but providing a mechanism to reach 
> in and effect code not under your control isn't good design. We use 
> derisive terms like "monkeypatching" for a reason.
>
> I'm sure there are good reasons for wanting swappable models. Russ, I know 
> you're smarter than me, so the fact that you want LazyForeignKey so much 
> probably indicates that you've got some really solid use cases in mind. But 
> really this is a hard veto from me; I just can't be convinced that this 
> sort of mechanism is anything but bad news. 
>
> However, I don't see why we should actively prevent this sort of thing 
> being done externally, so if there's anything in Django that's precluding 
> the creation of a LazyForeignKey as an external add-on let's consider that 
> limitation a bug and get it fixed.
>
> Jacob
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/p2gpf3R9evsJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to