On 8 kesä, 02:43, Russell Keith-Magee <[email protected]> wrote:
> Good idea. I haven't tried to see what it actually does; I'm guessing
> you're going to get Table Does Not Exist errors. A nicer error
> wouldn't hurt.
Yes, that is what happens.
> > - 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?
>
> Ah - I think I see the problem now. The swappable Meta option isn't
> visible to to end user -- ever -- unless they go spelunking in the
> source code for auth.models.
>
> If I define MyUser, I *dont'* need to define it as swappable. I just
> need to define AUTH_USER_MODEL in my settings file to point at my
> replacement model definition. The only place where swappable is
> defined is on the base model that is being swapped out -- in this
> case, auth.User.
>
> I'm expecting that there will be *no* documentation of the swappable
> option (unless, at some point in the future, we decide to make
> swappable models an official feature). It exists purely to make the
> internals clean, and avoid making auth.User a special case in code.
The real problem comes when you have multiple swappable models defined
for the same swappable "slot". This could happen in a CMS for example
- they might define a couple of classes to use, you can choose which
one to use by using a setting. Or, maybe you have some library
installed which defines some reusable User models. Problem is, every
one of these models will be installed unless they provided the
swappable = 'AUTH_USER_MODEL' meta option. If you don't provide that
option, nothing ties the models to the same slot.
> > - 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).
>
> If MY_SETTING isn't defined, all the code I've written should be
> assuming that the model isn't swapped out (i.e., it's effectively
> getattr(settings, 'MY_SETTING', model_label_of_default_model) ). As
> proof of concept, it certainly wouldn't hurt to drop out the
> AUTH_USER_MODEL setting from globals.
The model_label_for_default_model can't be defined anywhere in the
current implementation. The Model._meta.swapped uses:
return self.swappable and getattr(settings, self.swappable, None)
not in (None, model_label)
> >> > 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.
>
> I can see two approaches here.
>
> The first is the full audit of admin that I've mentioned previously.
> That will reveal everything that admin is depending on, and will allow
> us to define a full "admin user interface" that any swappable user
> must define.
>
> The second is to abstract away the ordering field in the same was as
> we've abstracted get_short_name -- i.e., don't specify what the field
> needs to be called, just require that the user provide an option that
> defines how it can be retrieved. This is similar to what we've done
> with get_short_name(), but at a model level.
I am not so much afraid of how the Admin works, but more generally
about the lookups available using the ORM. I would want to do:
Document.objects.all().order_by('creator__full_name')
But I can't do that.
Similar problem is there if you want to do:
Document.objects.filter(creator__full_name__ilike=q)
In my own projects I know I can do something like:
Q(creator__last_name__ilike=q)|Q(creator__first_name__ilike=q)
because I control the User model. But on the User interface level
there isn't anything like this available.
So, luckily this is only problem for 3rd party apps, and even then if
there is need to override the default ordering for the User model.
- 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.