Fields¶
Even if we tried to keep most of the native Django fields, we had to override some of them to be more fit for RESTful applications. Also, we introduced new ones, to cover extra functionality like nested requests. In this section, we will explain our intentions and describe their usage.
To sum up:
- You can use Django Form Fields:
- CharField
- ChoiceField
- TypedChoiceField
- DateField
- DateTimeField
- DecimalField
- DurationField
- EmailField
- FilePathField
- FloatField
- IntegerField
- GenericIPAddressField
- MultipleChoiceField
- TypedMultipleChoiceField
- RegexField
- SlugField
- TimeField
- URLField
- UUIDField
- ModelChoiceField
- ModelMultipleChoiceField
- You can use Django Validators.
Fields that are not in the list above were not been tested or been replaced with our customized implementation (or it just doesn't make sense to use them in RESTful APIs).
BooleanField¶
- Normalizes to: A Python True or False value (or None if it's not required)
Django BooleanField
checks only for False (false
, 0
)
values and everything else is suppose to be True.
In my point of view this kind of behaviour it's little bit weird, so we decided to check explicitly for True and False values. If field is required ValidationError is raised or value is normalized as None.
Checked values:
- True:
True
'True'
'true'
1
'1'
- False:
False
'False'
'false'
0
'0'
Note: We would like to change this behaviour to support only boolean values and rely on deserializers.
FieldList¶
This field is used to parse list of primitive values (like strings or numbers). If you want to parse list of object,
check FormFieldList
.
- Normalizes to: A Python list
- Error message keys:
not_field
,not_list
,min_length
,max_length
- Required arguments:
field
: Instance of a form field representing children- Optional arguments:
min_length
: Minimum length of field size as integermax_length
: Maximum length of field size as integer
JSON example
Python representation
from django_api_forms import Form, FieldList
from django.forms import fields
class FibonacciForm(Form):
numbers = FieldList(field=fields.IntegerField())
FormField¶
Field used for embedded objects represented as another API form.
- Normalizes to: A Python dictionary
- Required arguments:
form
: Type of a nested form
JSON example
{
"title": "Unknown Pleasures",
"year": 1979,
"artist": {
"name": "Joy Division",
"genres": [
"rock",
"punk"
],
"members": 4
}
}
Python representation
from django_api_forms import Form, FormField, FieldList
from django.forms import fields
class ArtistForm(Form):
name = fields.CharField(required=True, max_length=100)
genres = FieldList(field=fields.CharField(max_length=30))
members = fields.IntegerField()
class AlbumForm(Form):
title = fields.CharField(max_length=100)
year = fields.IntegerField()
artist = FormField(form=ArtistForm)
FormFieldList¶
Field used for embedded objects represented as another API form.
- Normalizes to: A Python list of dictionaries
- Error message keys:
not_list
,min_length
,max_length
- Required arguments:
form
: Type of a nested form- Optional arguments:
min_length
: Minimum length of field size as integermax_length
: Maximum length of field size as integer
JSON example
{
"title": "Rock For People",
"artists": [
{
"name": "Joy Division",
"genres": [
"rock",
"punk"
],
"members": 4
}
]
}
Python representation
from django_api_forms import Form, FormFieldList, FieldList
from django.forms import fields
class ArtistForm(Form):
name = fields.CharField(required=True, max_length=100)
genres = FieldList(field=fields.CharField(max_length=30))
members = fields.IntegerField()
class FestivalForm(Form):
title = fields.CharField(max_length=100)
year = fields.IntegerField()
artists = FormFieldList(form=ArtistForm)
EnumField¶
Tip: Django has pretty cool implementation of the enumeration types.
- Normalizes to: A Python
Enum
object - Error message keys:
not_enum
,invalid
- Required arguments:
enum
: Enum class
JSON example
Python representation
from django_api_forms import Form, EnumField
from django.forms import fields
from django.db.models import TextChoices
class AlbumType(TextChoices):
CD = 'cd', 'CD'
VINYL = 'vinyl', 'Vinyl'
class AlbumForm(Form):
title = fields.CharField(required=True, max_length=100)
type = EnumField(enum=AlbumType)
DictionaryField¶
Field created for containing typed value pairs.
Due to inverted key, value parameters in __init__
method, value_field
is forced keyword arguments.
- Normalizes to: A Python dictionary
- Error message keys:
not_dict
,not_field
- Required arguments:
value_field
: Type of a nested form- Optional arguments:
key_field
: Type of a nested form
JSON example
{
"my_dict": {
"b061bb03-1eaa-47d0-948f-3ce1f15bf3bb": 2.718,
"0a8912f0-6c10-4505-bc27-bbb099d2e395": 42
}
}
Python representation
from django_api_forms import Form, DictionaryField
from django.forms import fields
class DictionaryForm(Form):
my_typed_dict = DictionaryField(value_field=fields.DecimalField(), key_field=fields.UUIDField())
AnyField¶
Field without default validators.
- Normalizes to: Type according to the chosen request payload parser
JSON example
Python representation
from django_api_forms import Form, DictionaryField, AnyField
class BandForm(Form):
singer = DictionaryField(value_field=AnyField())
FileField¶
This field contains BASE64 encoded file.
- Normalizes to: A Django File object
- Error message keys:
max_length
,invalid_uri
,invalid_mime
- Arguments:
max_length
: Maximum files size in bytes (optional)mime
: Tuple of allowed mime types (optional - if present, value must be in form of Data URI)- Extra normalised attributes:
file_field.clean(payload).content_type
: Mime type (str
- e.g.audio/mpeg
) of containing file (None
if unable to detect - if payload is not in DATA URI format)
JSON example
Python representation
from django_api_forms import Form, FileField
from django.conf import settings
from django.forms import fields
class SongForm(Form):
title = fields.CharField(required=True, max_length=100)
audio = FileField(max_length=settings.DATA_UPLOAD_MAX_MEMORY_SIZE, mime=('audio/mpeg',))
ImageField¶
This field contains BASE64 encoded image. Depends on
Pillow because normalized value contains Image
object. Pillow is also used for
image validation Image.verify()
is called.
- Normalizes to: A Django File object
- Error message keys:
max_length
,invalid_uri
,invalid_mime
,invalid_image
(if Image.verify() failed) - Arguments:
max_length
: Maximum files size in bytes (optional)mime
: Tuple of allowed mime types (optional, value must be in Data URI)- Extra normalised attributes:
image_field.clean(payload).content_type
: Mime type (str
- e.g.audio/mpeg
) of containing file (None
if unable to detect - if payload is not in DATA URI format). Value is filled using PillowImage.MIME.get(image.format)
)image_field.clean(payload).image
: A Pillow Image object instance
JSON example
Python representation
from django_api_forms import Form, ImageField
from django.conf import settings
from django.forms import fields
class AlbumForm(Form):
title = fields.CharField(required=True, max_length=100)
cover = ImageField(max_length=settings.DATA_UPLOAD_MAX_MEMORY_SIZE, mime=('image/png',))
RRule Field¶
This field contains RRule object.
- Normalizes to a Dateutil RRule object.
- Error message keys:
not_rrule
Python representation
from django_api_forms import Form, RRuleField
class VacationForm(Form):
rrule = RRuleField(required=True)
GeoJSON Field¶
This field contains GEOSGeometry django GEOS object. Translates GeoJSON format into geodjango fields. Depends on gdal because of spatial reference system (SRS) which is specified in this library.
- Error message keys:
not_dict
,not_geojson
,not_int
,transform_error
- Arguments:
srid
: spatial reference identifier (optional - default 4326)transform
: transform to different spatial reference identifier (optional)
GeoJSON example
Python representation