All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
- Add
lookup_name
hints to Lookups for some third party tools, such as DRF Spectacular, django-filter, etc. (Thanks Chris Muthig) - Add logic in subqueries to only use the PK. (Thanks Chris Muthig)
- Retirement of the module.
3.4.0 - 2024-01-09
- Add support for Django 5.0
- Drop support for Django < 3.2, 4.0, 4.1
3.3.7 - 2022-10-18
- #74: Fix regression introduced in 3.3.2 that allowed integer lookups even when allow_int_lookups was set to False, in the specific case that the integer being looked up was equal to or fewer characters than the prefix for the field. This does not affect cases where no prefix was used, or if the prefix was fewer characters than the base-10 string representations of any valid IDs in the database. But if you DID have a Hashid*Field where you had a prefix specified and set allow_int_lookups=False (default), then lookups for base-10 integers that were equal or shorter in length than the prefix would succeed. For example, if the prefix was "o_", then lookups for integers 0-99 would succeed. (Thanks Tomáš Daniš for the Issue)
3.3.6 - 2022-10-11
- #73: Hashid object now implements arithmetic operators: +, -, *, /, //, %, divmod(), pow(), **, <<, >>, &, ^, | (Thanks Kenneth Lim )
- #55 and #71: Hashid object will now include the computed hashid string when being pickled, so that it doesn't need to compute it again when being unpickled. Care has been taken to ensure that unpickling old pickled Hashid objects should still work, and this should be backwards compatible. (Thanks svartalf for PR and Akbar Rifai for reporting the issue)
3.3.5 - 2022-06-17
3.3.4 - 2022-02-11
- #69: Override IntegerField's min/max validators to clean the hashid before validating
when
enable_hashid_object==False
. (Thanks Eric Carmichael)
- #68: Migrate to Github Actions for CI. (Thanks a ton! Bruno Alla)
3.3.3 - 2021-10-27
- #66: Allow lookups for related fields in DRF Serializers when the related field's value is a hashid with all numeric characters and allow_int_lookups is off. Related to previous fix in 3.3.2. (Thanks (again!) Adrian Shelley)
3.3.2 - 2021-10-08
- #66: Fixed issues for hashids that happen to encode to all-numbers, ie. int(428697) encodes to str("3557953"). There was a false assumption that this wasn't possible with alphabets including letters. Depending on the salt, this happens about 22 times per million IDs with default min_length and alphabet. It's more likely to happen with smaller alphabets that include a higher ratio of numbers to letters. This was a regression when prefix support was added in version 3.2.0. (Thanks Adrian Shelley)
3.3.1 - 2021-05-11
- #65: Fixed HashidSerializerCharField to not allow deserializing from integers if
allow_int_lookup
is disabled. (Thanks frossigneux)
3.3.0 - 2021-05-11
- #60: Fixed regression (from 3.1.2) that caused a
Hashid
instance to not be reversible, such as for pickling. This requires a change in the interface for theHashid
class, in that salt, min_length and alphabet are no longer derived from a givenhashids.Hashids
class (as it's impossible, due to hashids.Hashids pulling characters out of the provided alphabet to populate separators and guards, and randomizing the lists based on the salt.) The givenhashids
argument is for optimization only, so if it is given without also giving a salt, min_length and alphabet that match, the behavior of the class is incorrect and will now throw an exception. (Thanks sgex) - This may also fix issues with url
reverse
as reported in #44, however I have been unable to duplicate the problem myself, so this is just a guess. - Fixed sandbox tests.
3.2.1 - 2021-04-14
- #58: Fixed regression in ALLOW_INT_LOOKUP allowing integer lookups with string representation of an int, e.g. "123" (Thanks François Rossigneux)
- Add official support for Django 3.2.
- Dropped official support for Django 3.0 as it is past EOL, though it will probably still work.
3.2.0 - 2021-03-15
- Added optional string prefixes to generated hashids. e.g. "rec_8ghK0LM". (Thanks Brendan McCollam)
- Added BigHashidField and AutoBigHashidField
- Added new global and per-field option to disable the Hashid object, and instead return plain hashid strings for increased compatibility.
- Added new global and per-field option to disable the descriptor for increased compatibility.
- Added Global HASHID_FIELD_MIN_LENGTH and HASHID_FIELD_ALPHABET settings.
- Added Support for Django 3.1
- Added (BETA) support for Django 3.2, which is currently in Beta.
- Added a note per Issue #51 about the hashids-python library only caring about the first 43 characters. Thanks Ralph Bolton.
- Documented per-field salt usage for unique hashids.
- Optimized Hashid instantiation by testing for integer before hashid decode.
- Optimized lookups by testing for integer instead of hashid decode.
- Removed deprecation warnings for HASHID_FIELD_ALLOW_INT and
allow_int
- Removed support for Django 1.11 which is EOL
3.1.3 - 2020-06-05
- Check passed alphabet for length and that the characters are unique.
3.1.2 - 2020-05-28
- #40: Use a single instance of the Hashids class for all instances of a given Hashid*Field. In testing, this decreased time taken to instantiate those rows by about 63%, and memory usage is drastically decreased. (Thanks Alexandru Chirila)
3.1.1 - 2020-01-15
- Fixed security bug where comparison operators (gt, gte, lt, lte) would allow integer lookups regardless of ALLOW_INT_LOOKUP setting.
- Fixed tests that were relying on allow_int_lookup to be set in other tests.
3.1.0 - 2020-01-14
- Added support for
gt
,gte
,lt
andlte
lookups.- Example:
MyModel.objects.filter(id__gt=100)
(Ifallow_int_lookups
is True) - Example:
MyModel.objects.filter(id__gt="Ba9p1AG")
- (Thanks for report from frossigneux in Issue #38
- Example:
3.0.0 - 2019-12-05
- Dropped Python 2.7 support.
- Added Python 3.8 support.
- Added official support for Django 3.0
- Added official support for Django Rest Framework 3.10.
- (Thanks hhamana)
2.1.6 - 2019-04-02
- Added official support for Django 2.2 LTS.
- Added official support for Django Rest Framework 3.9.
- Deprecated support for Django 2.0 as it is no longer a maintained version of Django. However, the library will most likely continue to work with it for the time being as nothing else has changed.
2.1.5 - 2018-10-31
2.1.4 - 2018-10-05
- #27: Fixed PendingDeprectationWarning for
context
infrom_db_value()
. (Thanks Adam Johnson)
2.1.3 - 2018-09-21
- #26: Fixed version import error. (Thanks Dido Arellano)
2.1.2 - 2018-09-11
- #24: Added official support for Django 2.1. (Thanks Adam Tokarski)
- Deprecated support for Python 3.5, Django 1.8 - 1.10. Next major release will drop support completely.
- Updated Django Rest Framework support to 3.8.
- Clarified README (Issue #23)
2.1.1 - 2018-03-15
- Update documentation for DRF integration
2.1.0 - 2017-12-10
- Added support for pickling Hashid instances (Thanks Oleg Pesok)
- Add
long
comparisons for python2 (Thanks Oleg Pesok) - Add support for Django 2.0. (Thanks Paul Nakata)
Please note: 1.8 will be supported until April at least (same as Django), but after that we may support only Django 1.11 and 2.0, per Django's recommendations and release schedule.
Django Rest Framework has dropped support for Django 1.8 and 1.9 as of their 3.7.x line, and there are import bugs with 1.11 and DRF 3.7.3, so we are supporting (and testing) DRF 3.6.4 for Django 1.8 -> 1.11, and DRF 3.7 for 2.0.
2.0.1 - 2017-10-04
- Field option 'allow_int' renamed to 'allow_int_lookup' to be more descriptive. Using 'allow_int' will print a DeprecationWarning and will be removed in a future version.
- Global setting
HASHID_FIELD_ALLOW_INT
renamed toHASHID_FIELD_ALLOW_INT_LOOKUP
to be more descriptive. SettingHASHID_FIELD_ALLOW_INT
will print a DeprecationWarning and will be removed in a future version. - Instances of the Hashid class are now immutable to conform to the Python Data Model and hashing behavior. This should be invisible to any typical uses.
- Integer lookups are now disabled by default. Set
HASHID_FIELD_ALLOW_INT_LOOKUP=True
orallow_int_lookup=True
to revert to previous behavior. Saving integers is always supported regardless of the setting or parameter. - Lookups with invalid Hashids strings (or integers if integer lookups is disabled) now returns no results by default
instead of throwing an exception. This will mean fewer exceptions being throw due to user input, and will also allow
Hashid*Fields to be used in the Django ModelAdmin
search_fields
parameter without throwing exceptions. Set the new global settingHASHID_FIELD_LOOKUP_EXCEPTION=True
to revert to the older behavior of throwing an exception when an invalid Hashid string or integer is given in lookups. Saving an invalid hashid string will always result in a ValueError being thrown. - The field will now throw a ValueError instead of TypeError when attempting to save (or lookup, if lookup exceptions are enabled) an invalid hashid string.
- Integer lookups are now disabled by default, so if you are setting it to False, then you can just remove the setting and/or parameters.
- Rename the setting
HASHID_FIELD_ALLOW_INT=True
toHASHID_FIELD_ALLOW_INT_LOOKUP=True
- Rename any instances of the parameter
allow_int=True
toallow_int_lookup=True
in Hashid*Field definitions. - You can remove any traps for TypeError when doing lookups, or conversely if you rely on the behavior, then set
HASHID_FIELD_LOOKUP_EXCEPTION=True
in your project settings, and catch ValueError now instead of TypeError.
1.3.0 - 2017-09-25
- Created custom Lookup system that supports Int, String and better restricts Int lookups if ALLOW_INT=False Thanks to Oskar Persson (https://github.com/OskarPersson)
- Allow comparison with strings. Thanks to Gordon Wrigley (https://github.com/tolomea)
- Updated dependencies to latest versions (Hashids 1.2.0, DRF 3.6.4)
- Added documentation for setting up Development environment.
- Added official LICENSE (MIT)
- Fixed hashing functionality to conform to Python Data Model.
- Fixed bug when setting descriptor after a set operation failed.
1.2.3 - 2017-07-22
- Added ability for Hashid instances to be typecast to integers. Thanks to Michael Lavers (https://github.com/kolanos)
1.2.2 - 2017-06-13
- Fixed bug with Django 1.11.2 causing the error "AttributeError: 'NoneType' object has no attribute 'dict'" Thanks to Kit La Touche (https://github.com/wlonk)
1.2.1 - 2017-02-21
- Fixed bug with Django Admin on 1.11 not using correct Widget
1.2.0 - 2017-02-21
- Added setting for turning off integer lookups
- Added documentation on how to use Hashid*Fields with DRF's PrimaryKeyRelatedField
1.1.0 - 2017-01-25
- Added support for Django REST Framework serializers.
1.0.1 - 2016-12-28
- Updated install documentation to suggest adding HASHID_FIELD_SALT on install.
1.0.0 - 2016-12-27
- (Breaking change) Salt no longer uses settings.SECRET_KEY
- HashidField and HashidAutoField use
salt=settings.HASHID_FIELD_SALT
by default
- HASHID_FIELD_SALT in Django settings for global salt value for all HashidFields and HashidAutoFields
- Django checks warning if salt is not specified globally or on each individual field.
- If you already specified
salt
in fields, likeid = HashidField(salt="something")
everywhere then you're already set, and can upgrade worry-free. - If you instead let the module fallback to
salt=settings.SECRET_KEY
(default behavior) then this upgrade will change all of your existing fields. It has been pointed out by @fjsj that it's possible to discover the salt used when encoding Hashids, and thus it is very dangerous to use settings.SECRET_KEY, as an attacker may be able to get your SECRET_KEY from your HashidFields. - If you absolutely MUST maintain backwards-compatibility and continue to support your old hashed
values, then you can set
HASHID_FIELD_SALT = SECRET_KEY
in your settings. But this is VERY DISCOURAGED.
- Initial release