Search code examples
djangodjango-modelsslug

When are django model id's generated?


I am creating an application where I want the pictures to be accessible via a hash string (to prevent people from guessing/accessing other photos). For this I am using the following approach:

class PhotoModel(models.Model):
    name = models.CharField(max_length=256)
    slg = models.SlugField()

    def save(self, *args, **kwargs):
        if not self.slg:
            self.slg = slugify(my_own_hash_function(str(self.id)))
        super(PhotoModel, self).save(*args, **kwargs)

The approach is working but I can't figure out why. When in the django model 'id' generated? And is this the right way to create an unguessable url for an object? (I will add a salt to the hashing function for added security later)


Solution

  • If the id field is an auto increment field, the ID is actually generated by the database. It is returned to django by the mechanisms available in the database for example in mysql this maybe LAST_INSERT_ID()

    If you override the save method in the model as you have done, the id will be undefined before you do super(PhotoModel, self).save(*args, **kwargs) but it will be defined afterwards.

    Another way to generate IDs is to use UUID fields. In this case django generates the id with a call to uuid.uuid4

    UUID fields are unguessable and if you had a uuid field as your primary key you wouldn't need your slug field but there are other disadvantages of using UUID. The pros and cons of UUIDs are widely discussed elsewhere on stackoverflow and I don't think I need to discuss further.

    As for the question "is this the right way to create an unguessable url for an object?" This question cannot be answered properly without looking at your hash function. And that reallyl ought to be posted in a separate question anyway.