On Thursday 09 January 2014 01:10:09 Raphaël Barrois wrote:
> On Wed, 8 Jan 2014 20:27:54 +0200
>
> Shai Berger <
sh...@platonix.com> wrote:
> > 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
>
Yes, I stand corrected.
>
> 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
As I've said in response to another mail in this thread, a variation on
Russell's suggestion, where the migration adds a ForeignKey with
swappable=True, should allow this to be done.
> 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).
>
I don't think related migrations should be generated automatically. There are
too many issues -- besides third-party apps, there are non-migrated apps.
Editing an app's models under its feet is very bad practice.
> 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)``.
No, such apps should be using the same getattr call in their migrations --
that is, this is one of the cases where editing migration files manually should
be required; and it doesn't matter if the default target model happens to be
swappable. It is enough that a referenced model is decided by settings.
On a related note, this strengthens the case for explicit references to
dynamic dependencies; a migration for such an app should, IMO, look something
like:
from django.db import migrations, models
from django.conf import settings
my_target_model = getattr(settings, 'MY_TARGET_MODEL',
settings.AUTH_USER_MODEL)
class Migration(migrations.Migration):
dependencies = [("migrations", "0001_initial"),
migrations.model_created(my_target_model)]
operations = [
migrations.DeleteModel("Tribble"),
migrations.AddField("MyModel", "target",
models.ForeignKey(my_target_model)),
]
On swappable models, the dynamic dependency could be inferred automatically
from the operations; in this case, where the target model is not (or at least
not necessarily) swappable, the placeholder reference is required.
Shai.