title: Problem Overriding the save() method in Django
body: <p>I have a peculiar type of model where <code>table_fields</code> needs to set to default depending on the value of its <code>report_type</code> field.</p>
  <pre><code>class Report(models.Model):
      ALL_TABLE_FIELDS = (
          'local_ordered_date', 'card', 'country', 'customer', 'supplier',
          'amount', 'currency', 'quantity', 'quantity_unit', 'invoice_total',
          'payment_total', 'balance', 'owner', 'lost_reason', 'lost_description', 'result',
          'local_result_updated_at', 'local_delivery_deadline', 'board', 'stage', 'order_number',
          'product', 'incoterms', 'destination_port', 'loading_port', 'payment_terms',
          'other_terms'
      )
      DEFAULT_TABLE_FIELDS = {
          'OrderTrendReport': ('card', 'board', 'customer', 'amount',
                               'currency', 'stage', 'owner', 'country',
                               'local_ordered_date', 'local_delivery_deadline',
                               'order_number'),
          'RevenueTrendReport': ('card', 'customer', 'invoice_total',
                                 'payment_total', 'balance', 'currency',
                                 'owner', 'order_number', 'board'),
          'DealSuccessRateReport': ('card', 'board', 'customer', 'amount',
                                    'currency', 'owner', 'result',
                                    'local_result_updated_at'),
          'DealLostReasonReport': ('card', 'board', 'customer', 'amount',
                                   'currency', 'owner',
                                   'local_result_updated_at', 'lost_reason',
                                   'lost_description'),
          'OrderByCategoryReport': ('card', 'board', 'customer', 'amount',
                                    'currency', 'stage', 'owner', 'country',
                                    'local_ordered_date', 'local_delivery_deadline',
                                    'order_number')
      }
  
      &quot;&quot;&quot;
      The proper way to set a field's default value to a function call/callable
      is to declare a function before the field and use it as a callable in default_value named arg
      https://stackoverflow.com/questions/12649659/how-to-set-a-django-model-fields-default-value-to-a-function-call-callable-e
      &quot;&quot;&quot;
  
      class ReportType(models.TextChoices):
          # hard-coded in order to avoid ImportError and AppRegistryNotReady
          OrderTrendReport = 'OrderTrendReport', 'Order Trend report'
          RevenueTrendReport = 'RevenueTrendReport', 'Revenue Trend report'
          DealSuccessRateReport = 'DealSuccessRateReport', 'Deal Success Rate report'
          DealLostReasonReport = 'DealLostReasonReport', 'Deal Lost Reason report'
          OrderByCategoryReport = 'OrderByCategoryReport', 'Order By Category report'
  
      user = models.ForeignKey(User, on_delete=models.CASCADE)
      report_type = models.CharField(choices=ReportType.choices,
                                     max_length=50,
                                     default=ReportType.OrderTrendReport)
      table_fields = ArrayField(models.CharField(max_length=50),
                                default=list)
  
      @property
      def all_table_fields(self):
          return self.ALL_TABLE_FIELDS
  
      def save(self, *args, **kwargs):
          if not self.pk: # this will ensure that the object is new
              self.table_fields = self.DEFAULT_TABLE_FIELDS[self.report_type]
          super().save(*args, **kwargs)
  </code></pre>
  <p>After finishing the code for <code>models.py</code>, I went on and made a migration file. Then I edited this like so:</p>
  <pre><code>import django.contrib.postgres.fields
  from django.db import migrations, models
  import django.db.models.deletion
  
  
  def make_report_fields(apps, schema_editor):
      User = apps.get_model(settings.AUTH_USER_MODEL)
      Report = apps.get_model('deal', 'Report')
      ReportTypes = ('OrderTrendReport', 'RevenueTrendReport', 'DealSuccessRateReport',
                     'DealLostReasonReport', 'OrderByCategoryReport')
      report_fields = [Report(user=user, report_type=report_type)
                       for report_type in ReportTypes
                       for user in User.objects.all()]
      Report.objects.bulk_create(report_fields)
  
  class Migration(migrations.Migration):
  
      dependencies = [
          migrations.swappable_dependency(settings.AUTH_USER_MODEL),
          ('deal', '0059_auto_20210610_0948'),
      ]
  
      operations = [
          migrations.CreateModel(
              name='Report',
              fields=[
                  ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                  ('report_type', models.CharField(choices=[('OrderTrendReport', 'Order Trend report'), ('RevenueTrendReport', 'Revenue Trend report'), ('DealSuccessRateReport', 'Deal Success Rate report'), ('DealLostReasonReport', 'Deal Lost Reason report'), ('OrderByCategoryReport', 'Order By Category report')], default='OrderTrendReport', max_length=50)),
                  ('table_fields', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=50), default=list, size=None)),
                  ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
              ],
          ),
          migrations.RunPython(make_report_fields)
      ]
  </code></pre>
  <p>When I ran <code>python migrate deal {# of migration file}</code>, the table was made, with many rows corresponding to the existing users.
  However, the <code>table_fields</code> were all empty.</p>
  <p><a href="https://i.stack.imgur.com/bePdQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bePdQ.png" alt="empty_table_fields" /></a></p>
  <p>How do I fix it so that the <code>table_fields</code> will be set to correct default according to its 'report_type'?</p>