[Django] #33538: Migrations autodetector change for djangopolymorphicmodel

71 views
Skip to first unread message

Django

unread,
Feb 23, 2022, 11:55:55 AM2/23/22
to django-...@googlegroups.com
#33538: Migrations autodetector change for djangopolymorphicmodel
-------------------------------------+-------------------------------------
Reporter: markp2 | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: | Version: 4.0
Migrations |
Severity: Normal | Keywords: Migrations
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
We use Django-polymorphic and now get spurious migration AlterField
operation. We note that this is referenced in the 4.0 release notes:

Migrations autodetector changes¶
The migrations autodetector now uses model states instead of model
classes. Also, migration operations for ForeignKey and ManyToManyField
fields no longer specify attributes which were not passed to the fields
during initialization.
As a side-effect, running makemigrations might generate no-op AlterField
operations for ManyToManyField and ForeignKey fields in some cases

However, we de not understand what is a model state [vs a model class]?

The auto-generated migration looks like this:

{{{
operations = [
migrations.AlterField(
model_name='polymorphicmodel',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name='polymorphic_%(app_label)s.%(class)s_set+',
to='contenttypes.contenttype'),
),
]
}}}

Presumably based on our [simple] sub-class of PolymorphicModel:


{{{
class PolymorphicModel(poly_models.PolymorphicModel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.__class__ == PolymorphicModel:
return
tag = self.get_polymorphic_tag()
if not tag and args:
tag = args[self.get_polymorphic_tag_index() + 1]
setattr(self, self.get_polymorphic_tag_name(), tag)

@classmethod
def get_polymorphic_tag(cls) -> str:
baseclass = cls.get_polymorphic_concrete_base_model()
assert cls.__name__.startswith(baseclass.__name__)
return cls.__name__[len(baseclass.__name__):]

@classmethod
def get_polymorphic_tag_name(cls) -> str:
i = cls.get_polymorphic_tag_index()
return cls.get_polymorphic_base_model()._meta.fields[i + 1].name

@classmethod
def get_polymorphic_tag_index(cls) -> int:
internal_fields = len(cls.get_polymorphic_internal_model_fields())
return internal_fields + 1

@classmethod
def get_polymorphic_submodels(cls) -> List[Type['PolymorphicModel']]:
baseclass = cls.get_polymorphic_concrete_base_model()
submodels = [m for m in apps.get_models() if issubclass(m,
baseclass) and m != baseclass]
return submodels

@classmethod
def get_polymorphic_submodel(cls, tag) -> Type['PolymorphicModel']:
models = [m for m in cls.get_polymorphic_submodels() if
m.get_polymorphic_tag() == tag]
return models[0]

@classmethod
def get_polymorphic_base_model(cls):
raise NotImplementedError()

@classmethod
def get_polymorphic_concrete_base_model(cls):
raise NotImplementedError()

@classmethod
def get_polymorphic_internal_model_fields(cls):
return cls.polymorphic_internal_model_fields

@classmethod
def fqn(cls):
return cls.__module__ + '.' + cls.__name__
}}}

Is there any way to resolve this and not have the migration auto
generated?

--
Ticket URL: <https://code.djangoproject.com/ticket/33538>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 23, 2022, 12:08:00 PM2/23/22
to django-...@googlegroups.com
#33538: Migrations autodetector change for djangopolymorphicmodel
-------------------------------------+-------------------------------------
Reporter: markp2 | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Migrations | Version: 4.0
Severity: Normal | Resolution: invalid
Keywords: Migrations | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid


Comment:

> Is there any way to resolve this and not have the migration auto
generated?

Unfortunately no, all auto-generated migrations should contain only no-op
operations so no SQL statements are issued. If you're having trouble
understanding how Django works, see
TicketClosingReasons/UseSupportChannels for ways to get help.

--
Ticket URL: <https://code.djangoproject.com/ticket/33538#comment:1>

Reply all
Reply to author
Forward
0 new messages