Loading...

django-developers@googlegroups.com

[Prev] Thread [Next]  |  [Prev] Date [Next]

Re: auth.user refactor: the profile aproach bhuztez Thu Apr 05 22:00:45 2012

I think we need three different kinds of models, Identity, Profile and
Authentication Info.

 * The Identity model should have all fields shared by many apps.
 * Each app can have its own Profile model. If a field is not shared
with other apps, just put it in the Profile model.
 * Since password is never used after an user is authenticated,
authentication backends should declare fields like passwords, OpenID
credentials in their own Authentication Info models.

Having any default fields in the Identity model is not appropriate,
most likely we will find a use case in which a certain field is not
needed. But if the Identity model has only PK field, data
synchronization will be a big problem, for each field shared by
multiple apps, you need a signal, and suppose you have 20 models and
they have 3 fields in common, when you changed these 3 fields in one
object, you will have another 19 objects saved three times each.

Furthurmore, a project may need more than one Identity model. Both
LazyForeignKey and multiple Profile solution do not address this
problem. Since any app may have its own APP_IDENTITY_MODEL setting,
the unpredictable problem if APP_IDENTITY_MODEL changed after initial
syncdb, is unavoidable. IMO, this problem can only be solved schema
migration tool and should be solved by schema migration tool. If
Django ORM assumes that schema would be changed overtime, schema
migration should not be an optional part of it.




On Apr 6, 9:52 am, Tai Lee <[EMAIL PROTECTED]> wrote:
> Thanks Anssi, but I think the interface contract for a pluggable app *should* 
> be on the pluggable app's profile, instead of relying on an assumption that 
> developers will have created a user model that is duck typed to suit every 
> pluggable app installed in the project (which might not be practical or even 
> possible).
>
> For the sake of avoiding duplication, which could be managed with signals and 
> the save() method of a project level profile, you potentially overload fields 
> that are not analogous across pluggable apps by sharing a single namespace. 
> E.g. is_active for the admin may not mean is_active for app2 or app3.
>
> Jacob, by having to define a minimum set of fields that users must implement 
> in their swappable User model to support contrib apps like the admin, don't 
> we end up exactly where we are now? Isn't this exactly what we have already?
>
> The only difference I see then is that the interface would be defined in docs 
> instead of a model and re-implemented by developers for every project, and 
> pluggable apps will often require a schema migration on the swapped-in 
> project level User model when adding a pluggable app to an established 
> project.
>
> In my ideal scenario, User would be a glue model with just a PK, and maybe 
> some convenience methods. AdminProfile would not have username or password 
> fields, but would have is_active, is_superuser, and maybe optionally a name, 
> etc.
>
> Developers would need to create at least one model in their project, which 
> would be a subclass of BaseAuthModel in most cases, which stores 
> authentication credentials.
>
> They would also need to create an auth backend, which would be a subclass of 
> BaseAuthBackend in most cases.
>
> Pluggable apps could also define auth models and backends if they require 
> specific auth to function (e.g. an app that adds twitter integration.)
>
> Then people could login to the admin and any other pluggable apps using 
> whatever credentials and authentication system they like (username/email and 
> password, twitter, Facebook, openid, etc.) Developers wouldn't need to 
> implement a minimal set of fields or do a database schema migration to 
> support or install any pluggable apps.
>
> If app1 or app2 require access to an email address (for example), their 
> profiles should have a required email field. It should be up to the project 
> developer to make sure that an email address is set when creating an app1 or 
> app2 profile for a User, and synchronizing them between app1 and app2 (if 
> appropriate).
>
> I think the data duplication issue is much easier for project developers to 
> manage explicitly without resorting to magic and assumptions than sharing or 
> combining namespaces for profile data, doing database scheme migrations, and 
> duck typing a single model for use with multiple pluggable apps.
>
> Cheers.
> Tai.
>
> On 06/04/2012, at 7:42 AM, Anssi Kääriäinen <[EMAIL PROTECTED]> wrote:
>
>
>
>
>
>
>
> > On Apr 5, 11:29 pm, Tai Lee <[EMAIL PROTECTED]> wrote:
> >> But I still don't see how a swapped in `User` model which *has* to behave 
> >> in a specified way so that it can work with the Django admin and any other 
> >> pluggable apps that might have special requirements, is any better than 
> >> simply allowing the admin and other pluggable apps to have their profile 
> >> and authentication needs self-contained?
>
> >> If Django's `User` model was just a stub (without even username and 
> >> password fields), and Django shipped with an abstract `BaseAuth` model 
> >> with a `username` field that was email compliant and a `password` field, 
> >> and corresponding `BaseAuthForm` and `BaseAuthBackend`, then user's can 
> >> still create their own `User` model with literally *whatever* fields they 
> >> want in it, they can use the standard auth fields, form and backend 
> >> provided by Django, or roll their own.
>
> >> Instead of creating a custom `User` model that quacks like an admin duck, 
> >> and quacks like every pluggable app that is installed as well, all they 
> >> need to do is create/update an an `AdminUser` whenever their custom `User` 
> >> is saved.
>
> >> This is explicit, the admin and other pluggable apps know where to access 
> >> information that they need (from their own models), and the developer has 
> >> control over how the data is kept in sync across the pluggable apps used 
> >> in the project, at the project level.
>
> > If every application provides a profile which matches it needs, you
> > will get a serious case of data-duplication. Every application which
> > needs email-address should then create a profile containing the email.
> > Another way to solve this would be to check the existing profiles for
> > the email field, and now you have introduced some magic, and in
> > addition you have mostly just moved the interface contract from the
> > User model to its profile. So, you have the same problem again. This
> > is the failing of the profile based approach: you don't actually solve
> > anything by it, you just move the problem around (and introduce more
> > problems by doing that). (Yes, I was +1 on the idea. Opinions
> > change...)
>
> > I guess 90% of users will either use the BackwardsCompatibilityUser,
> > or the new shiny FixedUser. For most users they are more than
> > adequate. The issue is only when you really need something completely
> > different for one reason or another. In addition with proxy models and
> > custom managers you can have pretty good profile based approach in the
> > cases where you need it. It is a good approach if you have
> > TwitterUser, FaceBookUser, GooglePlusUser and so on. (Or CustomerUser,
> > EmployeeUser and so on).
>
> > I bet one of the hardest problems will be how to define the ORM
> > interface, and how custom classes can fulfill
> > that. .filter(is_admin=True) can only work if there is a is_admin
> > field. I guess everything will need to go through manager methods, and
> > the "must implement" set must be kept at minimum.
>
> > - Anssi
>
> > --
> > You received this message because you are subscribed to the Google Groups 
> > "Django developers" group.
> > 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 
> > athttp://groups.google.com/group/django-developers?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
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.