16👍
For Django 2.1 I had to import apps from global registry because passed apps into migration were instances of django.db.migrations.state.AppConfigStub
without populated models_module
attribute. And create_contenttypes
is checking this attribute.
from django.apps.registry import Apps, apps as global_apps
from django.contrib.contenttypes.management import create_contenttypes
from django.db import migrations
def add_permision(apps: Apps, schema_editor):
my_app_config = global_apps.get_app_config('my_app')
create_contenttypes(my_app_config)
...
- [Django]-Generic many-to-many relationships
- [Django]-Django create userprofile if does not exist
- [Django]-Variable subtraction in django templates
8👍
Since, I ended up spending 3-4 hours on this I am adding my solution.
The problem was ContentType and Permission objects were not getting created when I ran multiple migrations together. Since I was referencing these content type and migration in next migration, this was causing problem.)
However they work fine if I run them one by one using migration number. (which were referenced in future migrations)
To solve it I added a extra migration in between to create ContentType and Permission objects.
# -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2017-03-11 05:59
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations
def update_all_contenttypes(**kwargs):
from django.apps import apps
from django.contrib.contenttypes.management import update_contenttypes
for app_config in apps.get_app_configs():
update_contenttypes(app_config, **kwargs)
def create_all_permissions(**kwargs):
from django.contrib.auth.management import create_permissions
from django.apps import apps
for app_config in apps.get_app_configs():
create_permissions(app_config, **kwargs)
def forward(apps, schema_editor):
update_all_contenttypes()
create_all_permissions()
def backward(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
('MY_APP', '0123_LAST_MIGRATION'),
]
operations = [
migrations.RunPython(forward, backward)
]
- [Django]-How to create a Django FloatField with maximum and minimum limits?
- [Django]-Django. A good tutorial for Class Based Views
- [Django]-How to update user password in Django Rest Framework?
7👍
Having a similar issue when writing a data migration that spans several apps. Turns out Django only loads those models into the app registry that are affected by what the “dependencies” member of the migration states: https://code.djangoproject.com/ticket/24303
Had to basically add an entry to the migration dependencies that I use that is not directly related by e.g. a ForeignKey to the app that is currently being migrated.
- [Django]-Django: show the count of related objects in admin list_display
- [Django]-Django Programming error column does not exist even after running migrations
- [Django]-Django.db.utils.OperationalError Could not connect to server
2👍
I faced the same issue today (Django 3.2.12). ContentTypes were present while running the migrate
command, however, they were missing on test
, though.
I managed to solve it by calling ContentType.objects.get_for_model
(which is an alternative solution to those given above). E.g.:
ContentType = apps.get_model("contenttypes", "ContentType")
YourModel = apps.get_model("app_name", "model_name")
content_type = ContentType.objects.get_for_model(YourModel)
It works because get_for_model
creates a ContentType if it doesn’t exist. See the Django implementation below:
def get_for_model(self, model, for_concrete_model=True):
"""
Return the ContentType object for a given model, creating the
ContentType if necessary. Lookups are cached so that subsequent lookups
for the same model don't hit the database.
"""
opts = self._get_opts(model, for_concrete_model)
try:
return self._get_from_cache(opts)
except KeyError:
pass
# The ContentType entry was not found in the cache, therefore we
# proceed to load or create it.
try:
# Start with get() and not get_or_create() in order to use
# the db_for_read (see #20401).
ct = self.get(app_label=opts.app_label, model=opts.model_name)
except self.model.DoesNotExist:
# Not found in the database; we proceed to create it. This time
# use get_or_create to take care of any race conditions.
ct, created = self.get_or_create(
app_label=opts.app_label,
model=opts.model_name,
)
self._add_to_cache(self.db, ct)
return ct
- [Django]-How do I create sub-applications in Django?
- [Django]-405 POST method not allowed
- [Django]-Django Broken pipe in Debug mode
1👍
update_contenttypes(apps.app_configs['contenttypes'])
will update the contenttypes app’s content types.
I believe you would want to do this…
update_contenttypes(apps.app_configs['app_label'])
where app_label is the app label for the app where the Invitation model lives.This will update your single app’s content types so it will be available to query as per your original code.
- [Django]-Easily rename Django project
- [Django]-Referencing multiple submit buttons in django
- [Django]-How do i pass GET parameters using django urlresolvers reverse
0👍
from django.db import migrations
from django.db.migrations import RunPython
from django.apps.registry import Apps, apps as global_apps
from django.contrib.contenttypes.management import create_contenttypes
def add_content_type_records(apps: Apps, schema_editor):
my_app_config = global_apps.get_app_config('my_1_app')
my_app_config.models_module = True
create_contenttypes(my_app_config)
my_app_config.models_module = None
my_app_config = global_apps.get_app_config('my_2_app')
my_app_config.models_module = True
create_contenttypes(my_app_config)
my_app_config.models_module = None
def create_setup_data(apps, schema_editor):
...
def delete_setup_data(apps, schema_editor):
...
class Migration(migrations.Migration):
dependencies = [
('my_1_app', '....'),
('my_2_app', '....'),
('contenttypes', '__latest__'),
]
operations = [
RunPython(add_content_type_records, RunPython.noop),
RunPython(create_setup_data, delete_setup_data),
]
- [Django]-__init__() got an unexpected keyword argument 'mimetype'
- [Django]-Is there any difference between django.conf.settings and import settings?
- [Django]-How do I get the current date and current time only respectively in Django?
0👍
I’m unwilling to depend on an undocumented private interface like create_contenttypes
, so I chose a different solution.
Context: I have a migration that adds a field and then populates the field. The field is a GenericForeignKey, so I need access to ContentType data to populate it. That data is absent in the test database, which is created automatically during the execution of the test suite.
Therefore, resting on the assumption of "test DB = empty", I implemented the following check at the top of my forward
function, which is passed to RunPython
:
def forward(apps, schema_editor):
MyModel = apps.get_model("myapp", "MyModel")
if MyModel.objects.count() == 0:
return
# code that depends on ContentType here...
It still runs properly in a regular context, and no longer fails in a test context.
PS – The Django Project really ought to implement a proper solution to this problem in the core.
- [Django]-How to set True as default value for BooleanField on Django?
- [Django]-How can I serialize a queryset from an unrelated model as a nested serializer?
- [Django]-Check for pending Django migrations