On Jun 7, 11:57 am, Florian Apolloner <[email protected]> wrote:
> Hi,
>
> On Wednesday, June 6, 2012 4:32:02 PM UTC+2, Anssi Kääriäinen wrote:
>
> > Still, yet another API idea: [snip]
>
> Then, Model.__new__ will replace the SwappableUser class with the
>
> > swapped in class. The 'swappable' in model.Meta tells which concrete
> > model implementation to use.
>
> I'd rather not dynamically replace models. The system proposed by Russell
> is clean and requires no extra magic. The only thing which might look a bit
> odd is inheriting from a swapped model, eg like:
>
> class MyUserProxy(get_user_model()):
> class Meta:
> proxy = True
>
> etc… (Which obviously can get a bit nicer by using User = get_user_model()
> and then inheriting from that).
I just don't see it as a good idea to hard-code meta.swappable to be a
settings variable in user-visible way, without any option to use
anything else. I see I am in minority here, so I will let this issue
be.
Review issues spotted:
- Queries using a swapped-out model should be prevented (probably at
"execute sql" time).
- For documentation: It should be suggested that the example MyUser
should define class Meta: swappable = 'AUTH_USER_MODEL'. Otherwise it
will be synced to the database even if it is not the chosen user model
for the project, which is likely not wanted. Maybe AbstractBaseUser
should define swappable = 'AUTH_USER_MODEL' so that anybody who
inherits from that gets the setting automatically?
- Creating a "class UserDerived(User)" will not succeed if the User
is swapped out. So, you can't make a swappable derived class.
Documenting this limitation is IMO enough.
- Create model UserProxy(auth.User), swap out auth.User, and make a
foreign key to UserProxy - you get an error that "DatabaseError:
relation "auth_user" does not exist" instead of a mention that
UserProxy is swapped out. The error should probably say something like
"UserProxy derives from swapped out model auth.User - can't reference
this model.", as telling to point to settings.AUTH_USER_MODEL in this
case is incorrect.
- The abstract user class defines two fields: password, and
last_login. Is the last_login really a core requirement?
- Assume a 3rd party developer was going to use the swappable Meta
attribute. The developer provides a couple of different swappable
implementations to use, each defining swappable = 'MY_SETTING'.
However, by default settings.MY_SETTING is None, and thus each of
these models will be synced into the DB. How does the 3rd party
developer designate the default implementation? For auth.user this is
easy, as global_settings can contain the default setting. A 3rd party
developer doesn't have this option. (This one isn't important for the
auth.User case, only for making this feature someday publicly
available).
> > About the ORM capabilities of the interface: It seems there can not be
> > any assumptions about the swapped in model here: for example
> > SomeModel.filter(user__is_staff=True) or
> > SomeModel.order_by('user__lastname', 'user__firstname') works
> > currently, but there are no such lookups available for the interface.
> > Maybe there should be some way to order by "full_name" and
> > "short_name" at least. But, this gets us quickly to virtual fields or
> > virtual lookups territory...
>
> Imo it's fine if we require some fields on a Usermodel to be compatible
> with admin and friends. (eg a first/last_name field which is nullable [or
> not required in the form validation sense] shouldn't hurt anyone, the admin
> could check if the field is filled and if not display something else like
> the username).
Admin is actually somewhat easy to make work re the ordering, because
in there you can use get_full_name.admin_order_field =
'somemodelfield'. This doesn't work outside Admin. This isn't a major
issue, it prevents things like ordering comments on the commenter's
"get_short_name" output. Even then, this is only an issue for reusable
code - in your project you know the concrete user model you have in
use, and can thus use the specific lookups your model has.
- 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 at
http://groups.google.com/group/django-developers?hl=en.