django-hashid-field
django-hashid-field copied to clipboard
python-hashids is replaced by python-sqids
The old hashids package is replaced by sqids (https://sqids.org/python).
Although this happened very recently I wanted to open this issue to discuss the path forward for the django-hashid-field package.
What are your thoughts on this?
I'm in favor of forking the repo and maintaining both repo's as the are incompatible. That's why I went ahead and created a fork, see https://github.com/gabn88/django-sqids-field. If @nshafer wants ownership I'm happy to give it up :)
Another options is to make the imported package (sqids vs hashids) a setting. This might make maintenance easier. See for example this code (I can make a PR for this): https://github.com/gabn88/django-sqids-field/tree/patch-1
I was not aware of sqids until you opened this PR, so thank for letting me know.
Actually, I'm thinking that this might be a good time to retire this module completely. Don't get me wrong, this module works fine for what it does, but I think that django-hashids (https://pypi.org/project/django-hashids/) is probably a better overall architecture. This module fit the specific need I had at the time, and I still use it in some maintenance projects, but there are a few issues:
- The descriptor that returns Hashid instances causes a lot of compatibility issues with other modules. I thought I was being clever and making the interface easier to work with, but since I released this module I read somewhere that a core tenent of the Django ORM is that the attributes of an instance are normal python data types. I'm guessing this was in response to some other ORM that came before Django that had issues like this.
- Replacing the primary key field also causes compatibility issues with modules that expect an AutoField.
- There are performance issues when working with large lists of objects where the constant encoding of hashids is being performed whether you want it or not.
Further, I'm not very involved with Django in my day-to-day any more. I've been slowly migrating all of my web dev work to Elixir/Phoenix and I don't plan on going back. I have fewer and fewer projects in maintenance mode that use Django, and all new projects are Elixir/Phoenix.
As a corollary, I recently wrote a custom Ecto.Type (Ecto is the database interface for Elixir applications, and is heavily used in Phoenix projects) that serves the same function as this module (including prefixes) but uses nanoid (https://hexdocs.pm/nanoid/readme.html) and just stores the nanoid in a separate column. This means joins still use the fast integer ID, there is no performance penalty for every row (and in fact you can just not select it at all if you don't need it) and it works in distributed scenarios. This module was also only about a dozen lines of Elixir.
If I were still involved in Django dev and wanted to create a new module that uses Sqids, I would probably use the same architecture as django-hashids, which is to create a proxy field instead of replacing the primary key. I might still use a Descriptor so that it only encodes the squid when you access the field, but that descriptor just returns the string, not an instance of a class. Also, maybe have an option for it to be precalculated and actually stored in the table instead of being a proxy.
So those are my thoughts.
Thank you so much for you post! I was implementing this package and I needed to patch for example django-guardian to make it work. This made me wonder if there isn't a better way forward, and it seems Django-hashids does not require this kind of patching.
I will use our feedback and switch to that package. Thank you!
Given the above sentiment it might be worth to archive this repo, and link to django-hashids? That would make it clear in the outset that this library is only for maintenance. (and thanks for mentioning django-hashids!)