4

I've been trying to implement hashids in django models. I want to acquire hashid based on model's id like when model's id=3 then hash encoding should be like this: hashid.encode(id). The thing is i can not get id or pk until i save them. What i have in my mind is get the latest objects id and add 1 on them. But it's not a solution for me. Can anyone help me to figure it out???

django model is:

from hashids import Hashids
hashids = Hashids(salt='thismysalt', min_length=4)



class Article(models.Model):
    title = models.CharField(...)
    text = models.TextField(...)
    hashid = models.CharField(...)

    # i know that this is not a good solution. This is meant to be more clear understanding.
    def save(self, *args, **kwargs):
        super(Article, self).save(*args, **kwargs)
        self.hashid = hashids.encode(self.id)
        super(Article, self).save(*args, **kwargs) 
Zorig
  • 585
  • 1
  • 10
  • 26

2 Answers2

1

I would only tell it to save if there is no ID yet, so it doesn't run the code every time. You can do this using a TimeStampedModel inheritance, which is actually great to use in any project.

from hashids import Hashids


hashids = Hashids(salt='thismysalt', min_length=4)


class TimeStampedModel(models.Model):
    """ Provides timestamps wherever it is subclassed """
    created = models.DateTimeField(editable=False)
    modified = models.DateTimeField()

    def save(self, *args, **kwargs):  # On `save()`, update timestamps
        if not self.created:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super().save(*args, **kwargs)

    class Meta:
        abstract = True  


class Article(TimeStampedModel):
    title = models.CharField(...)
    text = models.TextField(...)
    hashid = models.CharField(...)

    # i know that this is not a good solution. This is meant to be more clear understanding.
    def save(self, *args, **kwargs):
        super(Article, self).save(*args, **kwargs)
        if self.created == self.modified:  # Only run the first time instance is created (where created & modified will be the same)
            self.hashid = hashids.encode(self.id)
            self.save(update_fields=['hashid']) 
Hybrid
  • 6,741
  • 3
  • 25
  • 45
0

I think hashids always return the same value for a specific id. So you can just calculate it before displaying it (using template tags).

But if you still want to save it, one way is to save the hashid field in the views like this:

instance = Article()
instance.title = 'whatever...'
instance.text = 'whatever...'
instance.save()

hashids = Hashids()    
instance.hashid = hashids.encode(instance.id)
instance.save()

(I don't know if it's the best approach, but it worked for me!)

S_M
  • 290
  • 3
  • 18