django-rest-framework how to make model serializer fields required
Question:
I have a model that I’m filling out step by step, it means I’m making a form wizard.
Because of that most fields in this model are required but have null=True, blank=True
to avoid raising not null errors when submitting part of the data.
I’m working with Angular.js and django-rest-framework and what I need is to tell the api that x and y fields should be required and it needs to return a validation error if they’re empty.
Answers:
You need to override the field specifically and add your own validator. You can read here for more detail http://www.django-rest-framework.org/api-guide/serializers/#specifying-fields-explicitly. This is the example code.
def required(value):
if value is None:
raise serializers.ValidationError('This field is required')
class GameRecord(serializers.ModelSerializer):
score = IntegerField(validators=[required])
class Meta:
model = Game
This is my way for multiple fields. It based on rewriting UniqueTogetherValidator.
from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.utils.representation import smart_repr
from rest_framework.compat import unicode_to_repr
class RequiredValidator(object):
missing_message = _('This field is required')
def __init__(self, fields):
self.fields = fields
def enforce_required_fields(self, attrs):
missing = dict([
(field_name, self.missing_message)
for field_name in self.fields
if field_name not in attrs
])
if missing:
raise ValidationError(missing)
def __call__(self, attrs):
self.enforce_required_fields(attrs)
def __repr__(self):
return unicode_to_repr('<%s(fields=%s)>' % (
self.__class__.__name__,
smart_repr(self.fields)
))
Usage:
class MyUserRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ( 'email', 'first_name', 'password' )
validators = [
RequiredValidator(
fields=('email', 'first_name', 'password')
)
]
The best option according to docs here is to use extra_kwargs in class Meta, For example you have UserProfile model that stores phone number and is required
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('phone_number',)
extra_kwargs = {'phone_number': {'required': True}}
For this to work ensure that your models have been set as blank false null false as below.
some_field = models.CharField(blank=False, null=False, default='Anonymous')
Another option is to use required
and trim_whitespace
if you’re using a CharField:
class CustomObjectSerializer(serializers.Serializer):
name = serializers.CharField(required=True, trim_whitespace=True)
required
doc: http://www.django-rest-framework.org/api-guide/fields/#required
trim_whitespace
doc: http://www.django-rest-framework.org/api-guide/fields/#charfield
According to link1 and link2, and due to the intended field is null=True, blank=True
(like email
field of django.contrib.auth.models.User
in my example) this will work:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', 'password')
extra_kwargs = {'email': {'required': True,
'allow_blank': False}}
This works very well on my backend app.
class SignupSerializer(serializers.ModelSerializer):
""" Serializer User Signup """
class Meta:
model = User
fields = ['username', 'password', 'password', 'first_name', 'last_name', 'email']
extra_kwargs = {'first_name': {'required': True, 'allow_blank': False}}
extra_kwargs = {'last_name': {'required': True,'allow_blank': False}}
extra_kwargs = {'email': {'required': True,'allow_blank': False}}
I have a model that I’m filling out step by step, it means I’m making a form wizard.
Because of that most fields in this model are required but have null=True, blank=True
to avoid raising not null errors when submitting part of the data.
I’m working with Angular.js and django-rest-framework and what I need is to tell the api that x and y fields should be required and it needs to return a validation error if they’re empty.
You need to override the field specifically and add your own validator. You can read here for more detail http://www.django-rest-framework.org/api-guide/serializers/#specifying-fields-explicitly. This is the example code.
def required(value):
if value is None:
raise serializers.ValidationError('This field is required')
class GameRecord(serializers.ModelSerializer):
score = IntegerField(validators=[required])
class Meta:
model = Game
This is my way for multiple fields. It based on rewriting UniqueTogetherValidator.
from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.utils.representation import smart_repr
from rest_framework.compat import unicode_to_repr
class RequiredValidator(object):
missing_message = _('This field is required')
def __init__(self, fields):
self.fields = fields
def enforce_required_fields(self, attrs):
missing = dict([
(field_name, self.missing_message)
for field_name in self.fields
if field_name not in attrs
])
if missing:
raise ValidationError(missing)
def __call__(self, attrs):
self.enforce_required_fields(attrs)
def __repr__(self):
return unicode_to_repr('<%s(fields=%s)>' % (
self.__class__.__name__,
smart_repr(self.fields)
))
Usage:
class MyUserRegistrationSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ( 'email', 'first_name', 'password' )
validators = [
RequiredValidator(
fields=('email', 'first_name', 'password')
)
]
The best option according to docs here is to use extra_kwargs in class Meta, For example you have UserProfile model that stores phone number and is required
class UserProfileSerializer(serializers.ModelSerializer):
class Meta:
model = UserProfile
fields = ('phone_number',)
extra_kwargs = {'phone_number': {'required': True}}
For this to work ensure that your models have been set as blank false null false as below.
some_field = models.CharField(blank=False, null=False, default='Anonymous')
Another option is to use required
and trim_whitespace
if you’re using a CharField:
class CustomObjectSerializer(serializers.Serializer):
name = serializers.CharField(required=True, trim_whitespace=True)
required
doc: http://www.django-rest-framework.org/api-guide/fields/#required
trim_whitespace
doc: http://www.django-rest-framework.org/api-guide/fields/#charfield
According to link1 and link2, and due to the intended field is null=True, blank=True
(like email
field of django.contrib.auth.models.User
in my example) this will work:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('username', 'email', 'password')
extra_kwargs = {'email': {'required': True,
'allow_blank': False}}
This works very well on my backend app.
class SignupSerializer(serializers.ModelSerializer):
""" Serializer User Signup """
class Meta:
model = User
fields = ['username', 'password', 'password', 'first_name', 'last_name', 'email']
extra_kwargs = {'first_name': {'required': True, 'allow_blank': False}}
extra_kwargs = {'last_name': {'required': True,'allow_blank': False}}
extra_kwargs = {'email': {'required': True,'allow_blank': False}}