Django REST Framework - Целочисленное поле не принимает пустой ответ?
Поле models.py
IntegerField настроено:
class DMCAModel(models.Model):
tick = models.CharField(max_length=20)
percent_calc = models.FloatField()
ratio = models.IntegerField(blank=True, null=True, default=None) #The problem is here
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, related_name='dmca',
on_delete=models.CASCADE, null=True)
serilaizers.py
class DMCASerializer(serializers.ModelSerializer):
class Meta:
model = DMCAModel
fields = '__all__'
# fields = ['id', 'tick', 'percent_calc', 'ratio']
# I have tried removing fields, if I remove 'ratio' then even if I send an input it is ignored.
api.py
class DmcaViewSet(viewsets.ModelViewSet):
# queryset = DMCAModel.objects.all()
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = DcaSerializer
def get_queryset(self):
return self.request.user.dmca.all()
def perform_create(self, serializer):
# print(self.request.user)
serializer.save(owner=self.request.user)
Когда я делаю следующий POST
запрос от почтальона:
Authorization: Token xxxxxx
Body JSON:
{
"tick":"XYZ",
"percent_calc":"3",
"ratio":""
}
Я получаю ошибку:
{ "соотношение": [ "Требуется действительное целое число". ] }
Я думаю, что правильно задал свойства поля Models
, если я правильно их понимаю: null=True
база данных установит пустое значение NULL
, blank=True
будет принят ввод формы, default=None
в случае, если ничего не введено. Я пытался использовать свойства по одному и посмотреть, что произойдет. Но не могу разобраться с ошибкой.
Удалите default = True
. Если blank = True
, то default = False
, согласно документации.
Но также, null = True
означает, что значение будет обязательным в формах. Поэтому удаление null = True
также является частью решения.
Попробуйте это:
class DMCAModel(models.Model):
tick = models.CharField(max_length=20)
percent_calc = models.FloatField()
ratio = models.IntegerField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, related_name='dmca', on_delete=models.CASCADE, null=True)
Вот полезный ответ о разнице между null
и blank
, также. Стоит прочитать.
Внутри вашего сериализатора вы можете использовать CharField для поля отношения, если вы хотите отправить пустую строку, а затем преобразовать ее в Int в методе валидации.
class DMCASerializer(serializers.ModelSerializer):
ratio = serializers.CharField(required=False, allow_null=True, allow_blank=True)
class Meta:
model = DMCAModel
fields = '__all__'
def validate_ratio(self, value):
if not value:
return None
try:
return int(value)
except ValueError:
raise serializers.ValidationError('Valid integer is required')
Также необходимо изменить serializer_class внутри DmcaViewSet с:
serializer_class = DcaSerializer
to
serializer_class = DMCASerializer
Когда я посылаю пустую строку:
Когда я посылаю целое число:
Попробуйте передать этот запрос
Authorization: Token xxxxxx
Body JSON:
{
"tick":"XYZ",
"percent_calc":"3",
"ratio": null
}
Если вы передаете пустую строку, то в конце она будет строкой, поэтому возникнет ValidationError, также вы используете modelserializer, поэтому по умолчанию он будет проверять тип поля модели.
blank=True
ничего не будет значить с целым числом.