django-fields
django-fields copied to clipboard
Wrong max_length value when using south
I'm not sure why max_length is calculated this way: kwargs['max_length'] = max_length * 2 + len(self.prefix)
When I use south I get field length max_length * 2 + len(self.prefix) in my migration file and (max_length * 2 + len(self.prefix))*2 + len(self.prefix) in database.
In my opinion max_length shouldn't be changed if it is in kwargs and another key value like 'unencrypted_max_length' should be used:
max_length = kwargs.pop('unencrypted_max_length', 40)
...
kwargs['max_length'] = kwargs.get('max_length', max_length * 2 + len(self.prefix))
Please, provide a patch with unittest.
I didn't manage to pass django_fields tests. Output from manage.py test django_fields:
ERROR: test_date_encryption (example.django_fields.tests.DateEncryptTests)
Traceback (most recent call last): File "/home/srk/Devel/git/django-fields/src/example/../example/django_fields/tests.py", line 149, in test_date_encryption obj.save() File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 460, in save self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 543, in save_base for f in meta.local_fields if not isinstance(f, AutoField)] File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/init.py", line 276, in get_db_prep_save return self.get_db_prep_value(value, connection=connection, prepared=False) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) File "/home/srk/Devel/git/django-fields/src/example/django_fields/fields.py", line 153, in get_db_prep_value return super(BaseEncryptedDateField, self).get_db_prep_value(date_text, connection, prepared) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) TypeError: get_db_prep_value() got multiple values for keyword argument 'connection'
ERROR: test_date_time_encryption (example.django_fields.tests.DateEncryptTests)
Traceback (most recent call last): File "/home/srk/Devel/git/django-fields/src/example/../example/django_fields/tests.py", line 161, in test_date_time_encryption obj.save() File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 460, in save self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 543, in save_base for f in meta.local_fields if not isinstance(f, AutoField)] File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 28, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/init.py", line 276, in get_db_prep_save return self.get_db_prep_value(value, connection=connection, prepared=False) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) File "/home/srk/Devel/git/django-fields/src/example/django_fields/fields.py", line 153, in get_db_prep_value return super(BaseEncryptedDateField, self).get_db_prep_value(date_text, connection, prepared) File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/subclassing.py", line 53, in inner return func(_args, *_kwargs) TypeError: get_db_prep_value() got multiple values for keyword argument 'connection'
Ran 22 tests in 0.122s
I use Django 1.3.1
The problem was in my code
Hi.
@DXist why did you reopened this issue?
Hi! I figured out that south introspects wrong value for max_length (see https://github.com/svetlyak40wt/django-fields/pull/20). It should honour initial max_length value (maximum length of unencrypted data) that is saved in unencrypted_length field attribute. The resulting max_length value is changed to hold encrypted data with padding so it shouldn't be introspected.
The pull request contains an introspection rule to fix this problem for EncryptedCharField and subclasses.