Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove a default value function in Django

In a comment to this question answer I asked how to remove a field with a default value function. To sum up, the example code is:

def get_deadline():
    return datetime.today() + timedelta(days=20)

class Bill(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(User, related_name='bills')
    date = models.DateField(default=datetime.today)
    deadline = models.DateField(default=get_deadline)

and my question to the code is:

How do you remove the deadline field again while also deleting the get_deadline function? I have removed a field with a function for a default value, but now Django crashes on startup after removing the function. I could manually edit the migration, which would be ok in this case, but what if you simply changed the default function, and wanted to remove the old function?

I ended up removing the default part of the migration that referred to it, but how do you remove it nicely?

The only way I can think of is to squash the migrations, such that the migration using the function disappears, but that is not always an option.

like image 650
beruic Avatar asked Nov 29 '16 15:11

beruic


2 Answers

Following the documentation from Historical Models:

References to functions in field options such as upload_to and limit_choices_to and model manager declarations with managers having use_in_migrations = True are serialized in migrations, so the functions and classes will need to be kept around for as long as there is a migration referencing them. Any custom model fields will also need to be kept, since these are imported directly by migrations.

.....

To remove old references, you can squash migrations or, if there aren’t many references, copy them into the migration files.

Using a method to get the value of default field option is same as what is described for upload_to field. The documentation itself provide two options to you if you want to remove the method:

  1. Squash migrations - if you don't need those anymore
  2. Edit migration file: Copy functions to migration files and edit the reference in migration.

Updates from comments:

In Step 2 of Edit migration file, I have just included the way described in the documentation. How exactly you edit the migration is your choice. You could copy the function in the migration file and edit the reference or you could just remove the default field from the migration file, or you could use another function from a different file.

like image 163
AKS Avatar answered Oct 18 '22 21:10

AKS


It looks like you've pretty much figured out the answer for yourself. Before you remove the get_deadline function, you must remove it from any migrations that use it. There are two ways to do this:

  1. editing the migrations that use get_deadline to use a different default.
  2. squashing migrations to remove the migrations that refer to get_deadline.
like image 29
Alasdair Avatar answered Oct 18 '22 21:10

Alasdair