Reputation: 895
I have the next serializers:
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = Address
class ClientSerializer(serializers.ModelSerializer):
address = AddressSerializer()
class Meta:
model = Client
fields = ('id', 'email', 'address')
The models:
class Address(models.Model):
street = models.CharField(max_length=50, default='')
zip = models.CharField(max_length=5, default='')
state = models.CharField(max_length=50, choices=STATES ,default='')
suburb = models.CharField(max_length=50, default='')
num = models.CharField(max_length=7, blank=True, default='')
country = models.CharField(max_length=50, default='')
ref = models.CharField(max_length=120, blank=True)
class Client(models.Model):
address = models.OneToOneField(Address, null=True)
email = models.EmailField(unique=True, default='')
The expected behaviour is to have all the AddressSerializer fields as required, but that's not the case
When I check the options in the Client list api view I get the address as this:
"address": {
"type": "field",
"required": true,
"read_only": false,
"label": "Address"
}
But then when I check the Address list api view all my fields are optional:
"street": {
"type": "string",
"required": false,
"read_only": false,
"label": "Street",
"max_length": 50
},
"state": {
"type": "string",
"required": false,
"read_only": false,
"label": "State",
"max_length": 50
},
"zip": {
"type": "string",
"required": false,
"read_only": false,
"label": "ZIP",
"max_length": 5
},
Why the fields that are supposed to be required are not?
How can I set all fields to be required preferably without using the extra_kwargs
argument?
Upvotes: 2
Views: 3286
Reputation: 3
If you need to do it on certain fields this worked for me:
some_field = serializers.PrimaryKeyRelatedField(
queryset=YourModel.objects.all(),
allow_null=False,
allow_empty=False,
required=True
)
def validate_some_field(self, value):
if value is None:
raise serializers.ValidationError("Required.")
return value
Upvotes: 0
Reputation: 1797
There's another approach that might be considered cleaner than overriding get_fields
:
I solved a similar problem (marking optional fields as required) by supplying extra_kwargs. Alternatively, if you want something more dynamic, you can override the get_extra_kwargs
method on your serializer.
Upvotes: 0
Reputation: 2249
Field with default value is not required. You need to mark them as required explicitly:
class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = Address
def get_fields(self):
fields = super(AddressSerializer, self).get_fields()
for field in fields.values():
field.required = True
return fields
Upvotes: 2
Reputation: 17077
if model_field.has_default() or model_field.blank or model_field.null:
kwargs['required'] = False
The above is an excerpt from the DRF 3.1.2 source showing how the required
attribute of auto-generated serializer field of ModelSerializer
is determined.
What you have observed is by design. If you want an auto-generated serializer field to have required = True
attribute, its corresponding model field must neither have a default value nor accept blank nor accept null.
Upvotes: 3