|
71 | 71 | LIST_SERIALIZER_KWARGS = (
|
72 | 72 | 'read_only', 'write_only', 'required', 'default', 'initial', 'source',
|
73 | 73 | 'label', 'help_text', 'style', 'error_messages', 'allow_empty',
|
74 |
| - 'instance', 'data', 'partial', 'context', 'allow_null' |
| 74 | + 'instance', 'data', 'partial', 'context', 'allow_null', |
| 75 | + 'max_length', 'min_length' |
75 | 76 | )
|
76 | 77 |
|
77 | 78 | ALL_FIELDS = '__all__'
|
@@ -143,12 +144,18 @@ def many_init(cls, *args, **kwargs):
|
143 | 144 | return CustomListSerializer(*args, **kwargs)
|
144 | 145 | """
|
145 | 146 | allow_empty = kwargs.pop('allow_empty', None)
|
| 147 | + max_length = kwargs.pop('max_length', None) |
| 148 | + min_length = kwargs.pop('min_length', None) |
146 | 149 | child_serializer = cls(*args, **kwargs)
|
147 | 150 | list_kwargs = {
|
148 | 151 | 'child': child_serializer,
|
149 | 152 | }
|
150 | 153 | if allow_empty is not None:
|
151 | 154 | list_kwargs['allow_empty'] = allow_empty
|
| 155 | + if max_length is not None: |
| 156 | + list_kwargs['max_length'] = max_length |
| 157 | + if min_length is not None: |
| 158 | + list_kwargs['min_length'] = min_length |
152 | 159 | list_kwargs.update({
|
153 | 160 | key: value for key, value in kwargs.items()
|
154 | 161 | if key in LIST_SERIALIZER_KWARGS
|
@@ -568,12 +575,16 @@ class ListSerializer(BaseSerializer):
|
568 | 575 |
|
569 | 576 | default_error_messages = {
|
570 | 577 | 'not_a_list': _('Expected a list of items but got type "{input_type}".'),
|
571 |
| - 'empty': _('This list may not be empty.') |
| 578 | + 'empty': _('This list may not be empty.'), |
| 579 | + 'max_length': _('Ensure this field has no more than {max_length} elements.'), |
| 580 | + 'min_length': _('Ensure this field has at least {min_length} elements.') |
572 | 581 | }
|
573 | 582 |
|
574 | 583 | def __init__(self, *args, **kwargs):
|
575 | 584 | self.child = kwargs.pop('child', copy.deepcopy(self.child))
|
576 | 585 | self.allow_empty = kwargs.pop('allow_empty', True)
|
| 586 | + self.max_length = kwargs.pop('max_length', None) |
| 587 | + self.min_length = kwargs.pop('min_length', None) |
577 | 588 | assert self.child is not None, '`child` is a required argument.'
|
578 | 589 | assert not inspect.isclass(self.child), '`child` has not been instantiated.'
|
579 | 590 | super().__init__(*args, **kwargs)
|
@@ -635,6 +646,18 @@ def to_internal_value(self, data):
|
635 | 646 | api_settings.NON_FIELD_ERRORS_KEY: [message]
|
636 | 647 | }, code='empty')
|
637 | 648 |
|
| 649 | + if self.max_length is not None and len(data) > self.max_length: |
| 650 | + message = self.error_messages['max_length'].format(max_length=self.max_length) |
| 651 | + raise ValidationError({ |
| 652 | + api_settings.NON_FIELD_ERRORS_KEY: [message] |
| 653 | + }, code='max_length') |
| 654 | + |
| 655 | + if self.min_length is not None and len(data) < self.min_length: |
| 656 | + message = self.error_messages['min_length'].format(min_length=self.min_length) |
| 657 | + raise ValidationError({ |
| 658 | + api_settings.NON_FIELD_ERRORS_KEY: [message] |
| 659 | + }, code='min_length') |
| 660 | + |
638 | 661 | ret = []
|
639 | 662 | errors = []
|
640 | 663 |
|
|
0 commit comments