On Jun 6, 9:20 am, Russell Keith-Magee <[email protected]>
wrote:
> <[email protected]> wrote:
> > Understood & agreed (the "this model is dynamic made explicit" part
> > seems really important specifically).
>
> > I am afraid of the hard-coding of meta.swappable must be 'SOME_VAR'
> > which then references settings.SOME_VAR, and that this is made part of
> > the public API by the error messages. I would imagine that after app-
> > loading refactor one would make the swappable an app-level constant,
> > but the use of settings.AUTH_USER_MODEL directly in the code makes
> > this change backwards incompatible. Any chance of making what the
> > "swappable" contains more abstract? Something like suggesting making
> > foreign keys point to auth_user_ref() instead of
> > settings.AUTH_USER_MODEL.
>
> > Another idea would be to change the "swappable" to contain a method
> > reference, and then hint in the foreign key error message that "point
> > to User._meta.swappable() instead". (Or, make that Model property, so
> > that you could say to point to User.swapped_by instead, and
> > User.swapped_by would contain the real reference by checking where
> > User._meta.swappable points to).
>
> I can see the problem you're driving at, but I'm not sure it will
> actually be a problem in practice.
>
> Of course, it's impossible to know for sure without knowing the final
> App-refactor API, but based on the most recent discussions, the idea
> is to define a class that defines the App. I imagine that swappable
> models would be a part of this definition -- something like:
>
> auth_app = App(
>    …
>    swappable_models = {
>       'User': 'myauth.MyUser'
>    })
>
> The exact syntax may be different, but the point should be clear --
> the App provides the point where the substituted User model can be
> configured, replacing the need for an AUTH_USER_MODEL setting.
>
> If this is the case, the requirement for "Meta: swappable" reduces
> from needing to name a specific setting, to just providing a boolean
> that defines the fact that the App is allowed to accept overrides.
> Conveniently, 'AUTH_USER_MODEL' (or any other string value) evaluates
> as True, so AUTH_USER_MODEL will be a slightly non-sensical value, but
> a perfectly legal on. It also means that the app can exist in both
> worlds (a settings-overridden model, and an App-defintion overridden
> model. There's some prioritisation logic required there, but thats a
> relatively minor detail). Long term, the syntax can reduce to 'class
> Meta: swappable=True'.

There is still something to not like about the "swappable is a
settings variable" system. Specifically, I am afraid of the fact that
the settings.AUTH_USER_MODULE will be spread all over user code, and
will thus be hard to deprecate. In addition, there is the possibility
some users might want to use another system than settings (like Andrew
Ingram's mention of Oscar). Maybe the settings variable is the
simplest thing that works.

Still, yet another API idea:

class SwappableUser(models.Model):
    class Meta:
        swappable = somemethod
        # for example "lambda: getattr(settings, 'AUTH_USER_MODULE')

class User(models.Model):
    class Meta:
        swaps = 'auth.SwappableUser'

class AdvancedUser(models.Model):
    class Meta:
         swaps = 'auth.SwappableUser'

in settings.py:
AUTH_USER_MODULE = 'auth.AdvancedUser'

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. The "swaps" argument tells that this
model is meant as a swap-in for 'auth.SwappableUser'. The "swap-in"
models would be directly usable only when they happen to be configured
to be the chosen swap-in model (thus, ForeignKey(User) would still
work as long as the AUTH_USER_MODULE would be set to 'auth.User'). If
trying to use a swap-in model which isn't chosen, you would get a
validation error.

The user could use SwappableUser with the knowledge (through naming)
that it might be something else than the default user model. This
would be the user code:

from django.contrib.auth.models import SwappableUser

class MyObj(models.Model):
    user = models.ForeignKey(SwappableUser)

> > As for the User model as an ORM object - what lookups can be assumed
> > to exist? It seems the only requirement is that it has a numeric
> > primary key called 'id', otherwise there isn't anything that can be
> > assumed of it?
> However, if your requirement is to work with Admin, there are a couple
> more requirements. I *think* the minimum requirement is a definition
> for the following:
>
>  * get_full_name
>  * get_short_name
>  * __unicode__
>  * has_perm
>  * has_module_perms
>  * is_staff
>  * is_active

What is the format of "perm" for has_perm? I guess it is the
app_label.permission_code, instead of "write", "modify" etc. Maybe
there is no way to change this now, but the app_label.permission_code
will make it somewhat hard to write generic "this user has view
permissions to all objects, except for models in set
RESTRICTED_MODELS, and no modify permissions at all".

As is, the has_perm allows you to check the permissions through
something else than the default permissions application, yet the
permissions asked themselves are coded in the way the permissions
application expects them. While it isn't exactly rocket science to
extract the wanted "operation permission" from the
app_label."operation permission"_objname format, it would be nice if
Django internally used simpler format where possible.

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...

 - 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.

Reply via email to