#23473 closed Bug (fixed)
Django prompts to create new migrations when none are needed when a class is used in a field declaration
| Reported by: | Dan Loewenherz | Owned by: | Markus Holtermann |
|---|---|---|---|
| Component: | Migrations | Version: | 1.7 |
| Severity: | Normal | Keywords: | |
| Cc: | info+coding@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Create a model like so:
from django.db import models
from django.utils.deconstruct import deconstructible
@deconstructible
class IgnoreFormatString(object):
def __init__(self, s):
self.s = s
def __str__(self):
return self.s
def __mod__(self, k):
return self
class Product(models.Model):
name = models.CharField(max_length=32, blank=True, null=True, error_messages={'invalid': IgnoreFormatString('Err, this is invalid.')})
Create a migration, and then run it. If you run "./manage.py migrate" once again, you'll get prompted with
Your models have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
Running makemigrations will create another migration, yet this message will continue to appear if the migration has already been applied.
Change History (10)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
| Description: | modified (diff) |
|---|
comment:3 by , 11 years ago
I believe this is related to #22959 in that IgnoreFormatString must be comparable (add an __eq__ method). If so, we can probably add this to the documentation that should be added for that ticket.
comment:4 by , 11 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
I can confirm this behavior. I suggest to document the requirement for a __eq__ method.
comment:5 by , 11 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
follow-up: 7 comment:6 by , 11 years ago
Is there any way we could also make the ./manage.py makemigrations command fail unless __eq__ is implemented? Otherwise, users might not know where to look to fix the problem.
comment:7 by , 11 years ago
Replying to dlo:
Is there any way we could also make the
./manage.py makemigrationscommand fail unless__eq__is implemented? Otherwise, users might not know where to look to fix the problem.
This is rather complicated as object itself has a __eq__ method. and would require some crazy comparisons. For what I've tested, this seems to work.
Two solutions that somehow work, but that I'm not really a friend of. The if clause is really error-prone.
- Fails even on
manage.py shell:
-
django/utils/deconstruct.py
diff --git a/django/utils/deconstruct.py b/django/utils/deconstruct.py index a51a169..b0443ee 100644
a b def deconstructible(*args, **kwargs): 49 49 klass.__new__ = staticmethod(__new__) 50 50 klass.deconstruct = deconstruct 51 51 52 if not hasattr(klass, '__eq__') or klass.__eq__ == object.__eq__: 53 raise ValueError( 54 "Cannot deconstruct class %s since no __eq__ method exists or " 55 "__eq__ is inherited from 'object'. This method is required " 56 "to prevent infinit migration creation" 57 % klass.__name__) 58 52 59 return klass 53 60 54 61 if not args:
- Fails only when
__eq__is called:
-
django/utils/deconstruct.py
diff --git a/django/utils/deconstruct.py b/django/utils/deconstruct.py index a51a169..7c3abac 100644
a b def deconstructible(*args, **kwargs): 49 49 klass.__new__ = staticmethod(__new__) 50 50 klass.deconstruct = deconstruct 51 51 52 if not hasattr(klass, '__eq__') or klass.__eq__ == object.__eq__: 53 def __eq__(obj, other): 54 raise ValueError( 55 "Cannot deconstruct class %s since no __eq__ method " 56 "exists or __eq__ is inherited from 'object'. This method " 57 "is required to prevent infinit migration creation" 58 % obj.__class__.__name__) 59 60 klass.__eq__ = __eq__ 61 52 62 return klass 53 63 54 64 if not args:
comment:8 by , 11 years ago
| Has patch: | set |
|---|
I added a pull request with documentation updates: https://github.com/django/django/pull/3271
comment:9 by , 11 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Example project available at: https://github.com/dlo/django-migration-bug-23473
Thanks!