On Wed, 8 Jan 2014 20:27:54 +0200
Shai Berger <[email protected]> wrote:

> On Wednesday 08 January 2014 20:00:25 Andrew Godwin wrote:
> > > Instinctively, I'm almost -1 on 2); I'm not too happy about 1)
> > > either. If a model says it has a FK to auth.User, that shouldn't
> > > mean anything other than
> > > auth.User. I don't see that as cleanliness -- it's effectively
> > > monkeypatching.
> > > 
> > > 1b seems to me like the most reasonable option.
> > 
> > It's also the least user-friendly option. I don't see the same
> > problem with 2) - sure, the model says it has an FK to auth.user,
> > and your settings say that auth.user is swapped out in favour of
> > another model. I think it would actually be worse if we kept it
> > like it is - since auth.user is swapped out, it shouldn't have a
> > table made for it, so how are you even going to make an FK to it?
> > (this is how migrations currently fails - there's no auth.user left
> > for it to refer to).
> > 
> 
> I don't see how "you need to remember that auth.User really means
> some model defined in settings" is more user friendly than "you need
> to remember that __swappable__.X means that X is swappable". More so,
> as people already use auth.get_user_model() -- so, you can
> monkeypatch *that* when generating migrations, and let them just keep
> doing what they do today.

Actually, people don't use auth.get_user_model() in their models declaration, 
they use ``settings.AUTH_USER_MODEL``,
as described in the documentation: 
https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#referencing-the-user-model

The actual user model may not be prepared at the time the ``models.py`` is 
loaded, thus failing to import.
>From a migrations point of view, this means that the ForeignKey is declared 
>exactly as if the user had actually, manually written 
>``ForeignKey('auth.User')`` instead of ``settings.AUTH_USER_MODEL``.

I think that's why Andrew suggests to either use a special placeholder 
(``__swapped__.X``) or to automatically detect swapped models from their actual 
``class Meta: swappable=True`` declaration.

> 
> > > However, I've had a different thought about this:
> > > > As long as you're not using any third-party apps, then
> > > > everything works fine
> > > 
> > > No, it doesn't really. You can't change the user model as part of
> > > the project
> > > evolution. Supporting this raises a whole set of additional
> > > problems -- even
> > > with 1b, not to mention the scenarios where we try to guess
> > > swappables from concrete models that happen to be their sources
> > > or targets.
> > 
> > Changing the user model during the project's lifespan is a
> > different task. Migrations will nominally support it - in that
> > it'll change all your FK constraints to immediately point to the
> > new table - but you still have to manage moving the data into that
> > table yourself, and I'm not sure we can do it any other way.
> > Migrations sees you changing the user model as an actionable
> > change, since as far as it's concerned you changed a load of "to"
> > arguments of foreignkeys when you changed the setting, and so it
> > can make migrations for that.
> > 
> 
> No, not with any of the three suggestions. The migrations machinery
> doesn't introspect the database to find the FK targets -- it re-rolls
> the migrations in memory; and if any of the suggestions is taken,
> then when you run the migrations with the setting pointing at some
> model, it will seem like it has always been that way.
> 
> > The problem is when the migrations are pre-made - i.e. from
> > third-party apps - and that's the issue I'm trying to solve.
> > 
> 
> The two problems are in conflict -- for evolving the user model,
> history must matter; for pre-made migrations, the choice of user
> model needs to look like it has always been the way it is "now" (at
> the time the migrations are run).

Actually, you have two problems with a third-party app:

- It needs to have a way to specify "I want a FK to whatever the user has 
chosen for a AUTH_USER_MODEL", no matter the *type* of its PK field.
        => This mustn't depend on what the third-party-app developer's actual 
AUTH_USER_MODEL setting was while generating the migration
- Ideally, if the user changes the model, this should be helped by migrations, 
for instance by put a warning e.g "Looks like you're changing a swappable 
model, where should I put automatic related migrations ? (these migrations 
shouldn't go into the app with the FKey to AUTH_USER_MODEL, which may be out of 
the user's control — e.g third party apps).

Another problem is apps that provide a swappable model whose default is 
AUTH_USER_MODEL but that may be customized through their own setting,
for instance ``return getattr(settings, 'MY_TARGET_MODEL', 
settings.AUTH_USER_MODEL)``.


-- 
Raphaël

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/20140109011009.4f2d126b%40ithor.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to