nshafer / django-hashid-field

Django Model Field that uses Hashids to obscure the value
MIT License
370 stars 40 forks source link

Hashid value changes after saving instance #72

Closed radokristof closed 2 years ago

radokristof commented 2 years ago

Hi!

Thanks for this plugin. I have a little problem with it.

I'm using Django Rest Framework. Basically what I want to do is generate a HashId from another integer value in the perform_create function of the ModelViewSet use that ID (generate a QR code) and save both of them.

perform_create(self, serializer):
    uid = Hashid(454)
    qr_code = create_qr_code(uid.hashid)
    serializer.save(uid=uid, qr_code=ImageFile(qr_code, name="qr.png"))

It works correctly. The Hashid is generated, qr code generated and both of them gets saved. However the returned Hashid is too short. Re-querying the object(s) created before, the Hashid changes, and adapts to its normal, defined length. Leaving the Hashid in the QR code wrong. It seems that manually creating a Hashid instance is not working correctly?

Thanks for your help!

radokristof commented 2 years ago

Setting the salt and min_length parameter explicitly helped with this one. However I don't know if this is the best approach...

nshafer commented 2 years ago

You are correct, the Hashid object defaults to salt="", min_length=0, alphabet=Hashids.ALPHABET, prefix="" in the constructor. All of those values are set by the field either directly or through the descriptor. So you have to set them to match the field's settings for salt, min_length, alphabet and prefix, or else the Hashid object will generate different hashids. However, a much easier way than duplicating the settings would just be to just ask the HashidField to generate a Hashid object for you. So something like MyModel._meta.get_field('uid').get_hashid(454) will return a properly initialized Hashid object.

radokristof commented 2 years ago

@nshafer Thanks it works and it is a much cleaner than explicitly setting the parameters. Thanks for your fast help :)