Skip to content

Commit

Permalink
Merge pull request #21 from M1ha-Shvn/limit-id-field/HOTFIX
Browse files Browse the repository at this point in the history
IdField now can be limited with django.conf.ID_FIELD_MAX_VALUE setting
  • Loading branch information
M1ha-Shvn authored Oct 3, 2024
2 parents 1c533e6 + 3a504e9 commit bdfe2e0
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 5 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,20 @@ Parameters:
Resulting value: `Optional[int/float]`

### PositiveIntegerField(*args, with_zero: bool = False, source: Optional[str] = None, **kwargs)
### IdField(*args, with_zero: bool = False, source: Optional[str] = None, **kwargs)
Child of RestIntegerField, validating value as positive integer
Child of RestIntegerField, validating value as positive integer.

Parameters:
* with_zero: bool - if False, 0 will cause validation error
* source: Optional[str] - name of attribute to get data from. Defaults to form attribute name.

Resulting value: `Optional[int]`

### IdField(*args, with_zero: bool = False, source: Optional[str] = None, **kwargs)
Child of PositiveIntegerField, validating integer id value.
Upper value can be limited globally with `ID_FIELD_MAX_VALUE` in `django.conf.settings`.

Resulting value: `Optional[int]`

### TimestampField(*args, in_future: bool = True, source: Optional[str] = None, **kwargs)
Child of RestFloatField. Gets timestamp value and converts it into `datetime.datetime` object in UTC.
Parameter `initial` can be float or `datetime.datetime` value.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setup(
name='django-rest-form-fields',
version='1.3.5',
version='1.4.0',
packages=['django_rest_form_fields'],
package_dir={'': 'src'},
url='https://github.com/M1hacka/django-rest-form-fields',
Expand Down
5 changes: 5 additions & 0 deletions src/django_rest_form_fields/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,12 @@ class IdField(PositiveIntegerField):
"""

def __init__(self, *args, **kwargs):
from django.conf import settings
max_value = getattr(settings, "ID_FIELD_MAX_VALUE", None)
kwargs['with_zero'] = kwargs.get('with_zero', False)
if max_value is not None:
kwargs['max_value'] = kwargs.get('max_value', max_value)

super(IdField, self).__init__(*args, **kwargs)


Expand Down
2 changes: 1 addition & 1 deletion tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
DATABASES = {}

USE_TZ = True
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
82 changes: 81 additions & 1 deletion tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@

from django.core.exceptions import ValidationError
from django.core.validators import BaseValidator
from django.test import override_settings
from django.utils.timezone import now

from django_rest_form_fields.compatibility import to_timestamp
from django_rest_form_fields.fields import RestBooleanField, LowerCaseEmailField, TimestampField, DateUnitField, \
ColorField, IdArrayField, IdSetField, TruncatedCharField, JsonField, ArrayField, UrlField, RestCharField, \
RestChoiceField, RestIntegerField, RegexField, UUIDField, DateTimeField, MonthField, FileField, RestFloatField, \
DateField
DateField, IdField


class TestErrorValidator(BaseValidator):
Expand Down Expand Up @@ -179,6 +180,85 @@ def test_empty_value_validators(self):
f.clean('')


class IdFieldTest(TestCase):
def test_string(self):
f = IdField()
self.assertEqual(1, f.clean('1'))

def test_integer(self):
f = IdField()
self.assertEqual(2, f.clean(2))

def test_zero_invalid(self):
f = IdField()

with self.assertRaises(ValidationError):
f.clean("0")

def test_negative(self):
f = IdField()

with self.assertRaises(ValidationError):
f.clean("-1")

def test_invalid_format(self):
f = IdField()

with self.assertRaises(ValidationError):
f.clean("1.123")

def test_with_zero(self):
f = IdField(with_zero=True)
self.assertEqual(0, f.clean('0'))

def test_settings_max_value_not_set(self):
f = IdField()
self.assertEqual(2 ** 64 + 1, f.clean(2 ** 64 + 1))

@override_settings(ID_FIELD_MAX_VALUE=2**64)
def test_settings_max_value(self):
f = IdField()
with self.subTest("Max value"):
self.assertEqual(2**64, f.clean(2**64))

with self.subTest("Too big value"):
with self.assertRaises(ValidationError):
f.clean(2 ** 64 + 1)

def test_max_value(self):
f = IdField(max_value=100)
with self.subTest("Max value"):
self.assertEqual(100, f.clean(100))

with self.subTest("Too big value"):
with self.assertRaises(ValidationError):
f.clean(101)

def test_min_value(self):
f = IdField(min_value=10)
with self.subTest("Min value"):
self.assertEqual(10, f.clean(10))

with self.subTest("Too small value"):
with self.assertRaises(ValidationError):
f.clean(9)

def test_required(self):
with self.subTest("required=False"):
f = IdField(required=False)
self.assertIsNone(f.clean(None))

with self.subTest("required=True"):
f = IdField()

with self.assertRaises(ValidationError):
f.clean(None)

def test_initial(self):
f = IdArrayField(required=False, initial=1)
self.assertEqual(1, f.clean(None))


class RestFloatFieldTest(TestCase):
def test_correct(self):
f = RestFloatField()
Expand Down

0 comments on commit bdfe2e0

Please sign in to comment.