To reproduce, try something a long the following:
1. Start a new project and app with a customer `AUTH_USER_MODEL`, say
`Employee`
2. Set the `db_table` of `Employee` to something, 'store_employee'
3. Create another model in another app
> djbug
> djbug/settings.py -> AUTH_USER_MODEL = 'app.Employee'
> /app1/models.py
{{{#!python
# /app1/models.py
class Employee(models.Model):
class Meta:
db_table = 'store_employee'
# /app2/models.py
class Store(models.Model):
pass
}}}
4. Create and run migrations.
5. Change the `db_table` of `Employee` to the default, 'app_employee'.
6. Create an run the migrations with something like
`migrations.AlterModelTable('Employee', 'accounts_employee')`
7. Add a many to many pointing to Employee
{{{#!python
# /app2/models.py
class Store(models.Model):
employees = models.ManyTomanyField(settings.AUTH_USER_MODEL)
}}}
8. Create a new migration.
The migration generated will include the
`migrations.swappable_dependency(settings.AUTH_USER_MODEL)` dependency,
which expands to `('app1.Employee', '__first__')`. The problem with this,
is that at `__first__`, the `db_table` option is pointing to a now non-
existent table.
I propose that `migrations.swappable_dependency` instead use either
`__latest__`, or find out what the current migration is for the
application containing the `AUTH_USER_MODEL`.
--
Ticket URL: <https://code.djangoproject.com/ticket/23694>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* cc: andrewgodwin (added)
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Comment:
I know there was some things that used `__latest__`, but were later
switched to use `__first__` due to issues. Adding Andrew to comment.
--
Ticket URL: <https://code.djangoproject.com/ticket/23694#comment:1>
* status: new => closed
* resolution: => wontfix
Comment:
Unfortunately, if it's set to `__latest__` you get way more circular
dependencies incredibly easily and other nasty categories of bugs - it's
actually impossible to have a fixed dependency choice for custom user
models that works, as changing the setting can dynamically change the
model set without any detectable change by Django when it next runs.
This limitation (needing to have custom user models in the first
migration) is documented:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a
-custom-user-model
While I'd love to know a way round it, `__latest__` won't work, and
"finding the migration containing the user model" is possible but nasty to
implement. By enforcing this way we at least guarantee a lot less circular
dependency errors later by giving you an error up front if it's wrong.
--
Ticket URL: <https://code.djangoproject.com/ticket/23694#comment:2>
Comment (by Mariusz Felisiak):
#34623 was closed as a duplicate.
--
Ticket URL: <https://code.djangoproject.com/ticket/23694#comment:3>
* cc: Shai Berger (added)
Comment:
Quoting myself from the duplicate ticket:
> Another solution may be to load the app's migrations and look for a
suitable {{{CreateModel}}} operation. That is not ideal, because models
can be created by other operations (obviously the built-in
{{{RenameModel}}}, but even an {{{AddField}}} with a M2M, not to mention
3rd-party operations). \\ \\
> A different approach would be just to check -- when a swappable
dependency is in place, after running the initial migration of the
dependency app, verify that the requested model exists, and if it doesn't,
error out. That may later be extended, by allowing a specific migration to
be marked (explicitly, in its code) as providing a specific model, but
that extension may well be a YAGNI.
The above may justify reopening the ticket, as I believe it provides a
partial answer to Andrew's comment:2 asking for a way around the
limitations.
--
Ticket URL: <https://code.djangoproject.com/ticket/23694#comment:4>