-
-
Save vdboor/e3754e19551f2fbbcc31b01eec99ee8e to your computer and use it in GitHub Desktop.
""" | |
Patch the creation of database migrations in Django | |
Import this early from `__init__.py``. | |
- Don't want verbose_name changes in the migrations file. | |
- Don't want help_text in the migrations file. | |
""" | |
from functools import wraps | |
from django.db.models import Field | |
def patch_deconstruct(old_func, condition): | |
""" | |
Patch the ``Field.deconstruct`` to remove useless information. | |
This only happens on internal apps, not third party apps. | |
""" | |
@wraps(old_func) | |
def new_deconstruct(self): | |
name, path, args, kwargs = old_func(self) | |
# AutoField has no model on creation, but can be skipped | |
if hasattr(self, 'model') and condition(self): | |
kwargs.pop('verbose_name', None) | |
kwargs.pop('help_text', None) | |
return name, path, args, kwargs | |
return new_deconstruct | |
Field.deconstruct = patch_deconstruct(Field.deconstruct, lambda self: self.model.__module__.startswith('apps.')) |
Just to note that the solution provided by @rixx is better because importing from __init__.py
will cause django test to fail due to infinite recursion problem.
from django.core.management.commands.makemigrations import Command
Why import Command if it is not used?
The unused import is a bit of a hack – Django needs a Command
subclass to be present in the file to know what to do. If we simply import Command
, Django will find it and try to run it (which means that nothing happens, as Command
doesn't take any action).
It's a bit hacky to just import Command
– you could also do something more explicit, which I do in my code, and I've updated the snippet above to reflect that: Import Command as SomeOtherName
, and define your class Command(SomeOtherName): pass
, so that it's clear from reading the code that you need to have this class present.
Now I understand.
Will this option still work correctly for django 4.1 version? Because I didn't find another solution to exclude some data from the migration. I use the dynamic field verbose_name_plural in the admin panel, after the model name I display the amount of some filtered data
I have not used the command with Django 4.1 yet. You'll have to look at the changelog to see if there's anything to suggest that the API changed.
Just as a note in case others find their way here: Defining a custom manage command can be a bit cleaner in terms of inheritance and monkeypatching. in
app/management/commands/makemigrations.py
, write: