Daniel van Flymen Daniel van Flymen -4 years ago 67
Python Question

How to tell if a model instance is new or not when using UUIDField as a Primary Key

I have a model that requires some post-processing (I generate an MD5 of the

body
field).

models.py

class MyModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
body = models.TextField()
md5 = models.CharField(max_length=32)
...

def save(self, *args, **kwargs):
if self.pk is None: # Only for create (edit disabled)
self.md5 = get_md5(self.body)
super(MyModel, self).save(*args, **kwargs)


The problem is that the final block won't execute because I don't see a way to check if the instance is new or not:
self.pk
is never
None
because a UUID is populated before saving.

I'd like to know what the best practice is for handling this.

Thanks in advance.

Update:

The only solution I can think of is to call the database directly and:


  1. Check if the
    id
    exists

  2. Compare the
    modified
    and
    created
    fields to tell if it's an edit


Answer Source

Looks like the cleanest approach to this is to make sure that all your models have a created date on them by inheriting from an Abstract model, then you simply check if created has a value:

models.py

class BaseModel(models.Model):
    """
    Base model which all other models can inherit from.
    """
    id = fields.CustomUUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        # Abstract models are not created in the DB
        abstract = True

class MyModel(BaseModel):
    my_field = models.CharField(max_length=50)

    def save(self, *args, **kwargs):
        if self.created:
            # Do stuff
            pass
        super(MyModel, self).save(*args, **kwargs)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download