def test_get_field_kwargs_for_nullable_field(self): field = self.TestModel._meta.get_field('phone') kwargs = get_field_kwargs('phone', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 30) self.assertFalse(kwargs['required']) self.assertTrue(kwargs['allow_null'])
def test_get_field_kwargs_for_blank_field(self): field = self.TestModel._meta.get_field('additional_info') kwargs = get_field_kwargs('additional_info', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 30) self.assertFalse(kwargs['required']) self.assertTrue(kwargs['allow_blank'])
def test_get_field_kwargs_for_decimal_field_with_validator(self): field = self.TestModel._meta.get_field('rate') kwargs = get_field_kwargs('rate', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if not isinstance(validator, DecimalValidator) ] )
def test_get_field_kwargs_for_url_field_with_validator(self): field = self.TestModel._meta.get_field('url') kwargs = get_field_kwargs('url', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if not isinstance(validator, (URLValidator, MaxLengthValidator)) # NOQA ] )
def test_get_field_kwargs_for_char_field_with_max_length_validator(self): field = self.TestModel._meta.get_field('about') kwargs = get_field_kwargs('about', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 255) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if not isinstance(validator, MaxLengthValidator) ] )
def test_get_field_kwargs_for_char_field_with_min_value_validator(self): field = self.TestModel._meta.get_field('min_rate') kwargs = get_field_kwargs('min_rate', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['min_value'], 0) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if not isinstance(validator, (MinValueValidator, MaxValueValidator)) # NOQA ] )
def test_get_field_kwargs_for_ip_address_field_with_validator(self): field = self.TestModel._meta.get_field('ip_address') kwargs = get_field_kwargs('ip_address', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if validator is not validate_ipv46_address and not isinstance(validator, MaxLengthValidator) ] )
def test_get_field_kwargs_for_char_field_with_min_length_validator(self): field = self.TestModel._meta.get_field('cover_letter') kwargs = get_field_kwargs('cover_letter', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 255) self.assertEqual(kwargs['min_length'], 100) self.assertEqual( kwargs['validators'], [ validator for validator in list(field.validators) if not isinstance(validator, (MinLengthValidator, MaxLengthValidator)) # NOQA ] )
def build_standard_field(self, *args, **kwargs): """ Create regular model fields. """ field_name, model_field = args field_mapping = ClassLookupDict(self.serializer_field_mapping) field_class = field_mapping[model_field] field_kwargs = get_field_kwargs(field_name, model_field) if 'choices' in field_kwargs: # Fields with choices get coerced into `ChoiceField` # instead of using their regular typed field field_class = self.serializer_choice_field # Some model fields may introduce kwargs that would not be valid # for the choice field. We need to strip these out valid_kwargs = { 'read_only', 'write_only', 'required', 'default', 'initial', 'source', 'label', 'help_text', 'style', 'error_messages', 'validators', 'allow_null', 'allow_blank', 'choices' } for key in list(field_kwargs.keys()): if key not in valid_kwargs: field_kwargs.pop(key) if not issubclass(field_class, ModelField): # `model_field` is only valid for the fallback case of # `ModelField`, which is used when no other typed field # matched to the model field field_kwargs.pop('model_field', None) if not issubclass(field_class, CharField) and not issubclass(field_class, ChoiceField): # NOQA # `allow_blank` is only valid for textual fields field_kwargs.pop('allow_blank', None) if postgres_fields and isinstance(model_field, postgres_fields.ArrayField): # NOQA # Populate the `child` argument on `ListField` instances generated # for the PostgreSQL specific `ArrayField` child_model_field = model_field.base_field child_field_class, child_field_kwargs = self.build_standard_field( 'child', child_model_field ) field_kwargs['child'] = child_field_class(**child_field_kwargs) return field_class, field_kwargs
def build_standard_field(self, *args, **kwargs): """ Create regular model fields. """ field_name, model_field = args field_mapping = ClassLookupDict(self.serializer_field_mapping) field_class = field_mapping[model_field] field_kwargs = get_field_kwargs(field_name, model_field) if 'choices' in field_kwargs: # Fields with choices get coerced into `ChoiceField` # instead of using their regular typed field field_class = self.serializer_choice_field # Some model fields may introduce kwargs that would not be valid # for the choice field. We need to strip these out valid_kwargs = { 'read_only', 'write_only', 'required', 'default', 'initial', 'source', 'label', 'help_text', 'style', 'error_messages', 'validators', 'allow_null', 'allow_blank', 'choices' } for key in list(field_kwargs.keys()): if key not in valid_kwargs: field_kwargs.pop(key) if not issubclass(field_class, ModelField): # `model_field` is only valid for the fallback case of # `ModelField`, which is used when no other typed field # matched to the model field field_kwargs.pop('model_field', None) if not issubclass(field_class, CharField) and not issubclass( field_class, ChoiceField): # NOQA # `allow_blank` is only valid for textual fields field_kwargs.pop('allow_blank', None) if postgres_fields and isinstance(model_field, postgres_fields.ArrayField): # NOQA # Populate the `child` argument on `ListField` instances generated # for the PostgreSQL specific `ArrayField` child_model_field = model_field.base_field child_field_class, child_field_kwargs = self.build_standard_field( 'child', child_model_field) field_kwargs['child'] = child_field_class(**child_field_kwargs) return field_class, field_kwargs
def test_get_field_kwargs_for_filepath_field(self): field = self.TestModel._meta.get_field('photos') kwargs = get_field_kwargs('photos', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['path'], '/home/images')
def test_get_field_kwargs_for_char_field_with_verbose_name(self): field = self.TestModel._meta.get_field('middle_name') kwargs = get_field_kwargs('middle_name', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 30) self.assertEqual(kwargs['label'], 'Middle_name')
def test_get_field_kwargs_for_char_field(self): field = self.TestModel._meta.get_field('first_name') kwargs = get_field_kwargs('first_name', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 30)
def test_get_field_kwargs_for_decimal_field_with_max_digits(self): field = self.TestModel._meta.get_field('salary') kwargs = get_field_kwargs('salary', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_digits'], 5)
def test_get_field_kwargs_for_char_field_with_help_text(self): field = self.TestModel._meta.get_field('last_name') kwargs = get_field_kwargs('last_name', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['max_length'], 30) self.assertEqual(kwargs['help_text'], 'last_name help text')
def test_get_field_kwargs_for_field_with_choices(self): field = self.TestModel._meta.get_field('position') kwargs = get_field_kwargs('position', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['choices'], self.TestModel.POSITION)
def test_get_field_kwargs_for_decimal_field_with_decimal_places(self): field = self.TestModel._meta.get_field('bonus_salary') kwargs = get_field_kwargs('bonus_salary', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['decimal_places'], 2)
def test_get_field_kwargs_for_filepath_field_with_allow_folders(self): field = self.TestModel._meta.get_field('photos_with_allow_folders') kwargs = get_field_kwargs('photos_with_allow_folders', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['path'], '/home/images') self.assertTrue(kwargs['allow_folders'])
def test_get_field_kwargs_for_filepath_field_with_recursive(self): field = self.TestModel._meta.get_field('photos_with_recursive') kwargs = get_field_kwargs('photos_with_recursive', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['path'], '/home/images') self.assertTrue(kwargs['recursive'])
def test_get_field_kwargs_for_filepath_field_with_match(self): field = self.TestModel._meta.get_field('photos_with_match') kwargs = get_field_kwargs('photos_with_match', field) self.assertEqual(kwargs['model_field'], field) self.assertEqual(kwargs['path'], '/home/images') self.assertEqual(kwargs['match'], 'img.*\.txt$')
def test_get_field_kwargs_for_auto_field_as_readonly(self): field = self.TestModel._meta.get_field('id') kwargs = get_field_kwargs('id', field) self.assertEqual(kwargs['model_field'], field) self.assertTrue(kwargs['read_only'])
def test_get_field_kwargs_for_nullable_boolean_field(self): field = self.TestModel._meta.get_field('has_car') kwargs = get_field_kwargs('has_car', field) self.assertEqual(kwargs['model_field'], field) self.assertFalse(kwargs['required'])