title: How to exclude django model fields during a save?
body: <p>I've got a fairly complicated Django model that includes some fields that should only be saved under certain circumstances. As a simple example,</p>
  
  <pre><code>from django.db import models
  
  class MyModel(models.Model):
      name = models.CharField(max_length=200)
      counter = models.IntegerField(default=0)
  
      def increment_counter(self):
          self.counter = models.F('counter') + 1
          self.save(update_fields=['counter'])
  </code></pre>
  
  <p>Here I'm using <a href="https://docs.djangoproject.com/en/1.8/ref/models/expressions/#django.db.models.F" rel="noreferrer">F expressions</a> to avoid race conditions while incrementing the counter. I'll generally never want to save the value of counter outside of the <code>increment_counter</code> function, as that would potentially undo an increment called from another thread or process.</p>
  
  <p>So the question is, what's the best way to exclude certain fields by default in the model's save function? I've tried the following</p>
  
  <pre><code>def save(self, **kwargs):
      if update_fields not in kwargs:
          update_fields = set(self._meta.get_all_field_names())
          update_fields.difference_update({
              'counter',
          })
          kwargs['update_fields'] = tuple(update_fields)
      super().save(**kwargs)
  </code></pre>
  
  <p>but that results in <code>ValueError: The following fields do not exist in this model or are m2m fields: id</code>. I could of course just add <code>id</code> and any m2m fields in the difference update, but that then starts to seem like an unmaintainable mess, especially once other models start to reference this one, which will add additional names in <code>self._meta.get_all_field_names()</code> that need to be excluded from <code>update_fields</code>.</p>
  
  <p>For what it's worth, I mostly need this functionality for interacting with the django admin site; every other place in the code could <em>relatively</em> easily call <code>model_obj.save()</code> with the correct <code>update_fields</code>.</p>