Skip to content

Instantly share code, notes, and snippets.

@estebistec
Created May 20, 2012 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save estebistec/2759397 to your computer and use it in GitHub Desktop.
Save estebistec/2759397 to your computer and use it in GitHub Desktop.
Base django model
# For anyone random finding this, yeah, I don't like Django performing the extra query to determine insert vs. update
class BaseModel(models.Model):
id = models.CharField(primary_key=True, max_length=512)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
version = models.IntegerField(default=1)
class Meta:
abstract = True
def save(self, *args, **kwargs):
# Determine whether or not this should be an insert or update.
# Don't let Django ORM perform the extra query to find out.
if 'force_insert' not in kwargs and 'force_update' not in kwargs:
force_insert_or_update = ('force_insert' if self.is_new() else
'force_update')
kwargs[force_insert_or_update] = True
# If we're inserting, make sure we have an ID value
if kwargs.get('force_insert', False) and not self.id:
self.id = self.make_id()
# If we're updating, bump the entity version
if kwargs.get('force_update', False):
# TODO here be race conditions!
# TODO should do a WHERE clause that blows up on version mismatch
self.version += 1
super(BaseModel, self).save(*args, **kwargs)
def is_new(self):
return not self.id
def make_id(self):
return uuid.uuid4().hex
@estebistec
Copy link
Author

I would say block and force updates through QuerySet, but I think that's how save is implemented... look into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment