5

I have the following model, which when saved calculates hash_id field based on the pk:

class MyTable(models.Model):
    something = models.CharField(max_length=255)
    reported = models.IntegerField(default=0, blank=True)
    hash_id = models.CharField(max_length=32, db_index=True, unique=True, blank=True)

    def save(self, *a, **kw):
        super().save(*a, **kw)
        self.hash_id = hash_fn(self.pk)
        super().save(*a, **kw)

In one of my views I have the following lines, which are supposed to increment reported field by 1, however reported is incremented by 2, because of the overridden save method:

my_table_ins.reported = F('reported') + 1
my_table_ins.save()

Ideally I would like something among the lines:

    def save(self, *a, **kw):
        super().save(*a, exclude=['reported'], **kw)
        self.hash_id = hash_fn(self.pk)
        super().save(*a, **kw)
NarūnasK
  • 4,564
  • 8
  • 50
  • 76
  • this was asked before [here](https://stackoverflow.com/questions/33225000/how-to-exclude-django-model-fields-during-a-save) – N. Ivanov Sep 21 '17 at 14:58

2 Answers2

9

Adding to @martin-castro-alvarez answer, if you want to update all fields except for a few, you can do this:

fields_to_exclude = {'reported','another_field'}
# automatically populate a list with all fields, except the ones you want to exclude
fields_to_update = [f.name for f in MyTable._meta.get_fields() if f.name not in fields_to_exclude and not f.auto_created]
my_table_ins.save(update_fields=fields_to_update)

this will work in Django>=1.8. In older versions you can use model._meta.get_all_field_names()

samad montazeri
  • 1,203
  • 16
  • 28
6

According to the Oficial Documentation you can specify which fields you want to save using the update_fields parameter:

my_table_ins.reported = F('reported') + 1
my_table_ins.save(update_fields=['reported', ])  # This will only save 'reported'

The documentation is available here:

https://docs.djangoproject.com/en/1.11/ref/models/instances/#specifying-which-fields-to-save