Как сделать поле ModelSerializer необязательным в Django rest framework
У меня есть модель Reaction с полями code и comment. В файле models.py у меня оба поля null=True, blank=True. Я хочу, чтобы одно из них было заполнено, а другое - пусто, для этого я создал метод clean в models и метод validate в serializers. Но когда я пытаюсь создать реакцию без кода/комментария, он говорит, что код/комментарий необходим.
models.py
class Reaction(models.Model):
code = models.ForeignKey(Code, null=True, blank=True, related_name="code_reactions", on_delete=models.CASCADE)
comment = models.ForeignKey(Comment, null=True, blank=True, related_name="comment_reactions", on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name="reations", on_delete=models.CASCADE)
REACTION_CHOICES = [
("like", "Like"),
("dislike", "Dislike"),
("wow", "Wow"),
("love", "Love"),
("sad", "Sad"),
("haha", "Haha"),
("rocket", "Rocket"),
("angry", "Angry"),
]
name = models.CharField(choices=REACTION_CHOICES, max_length=10)
class Meta:
unique_together = [["code", "user"], ["comment", "user"]]
def clean(self):
if self.code and self.comment:
raise ValidationError(_('One reaction cannot be assigned to a code and a comment'))
if not self.code and not self.comment:
raise ValidationError(_("Please enter a code or a comment"))
serializers.py
class ReactionCreateSerializer(serializers.ModelSerializer):
code = serializers.IntegerField(required=False)
comment = serializers.IntegerField(required=False)
class Meta:
model = Reaction
fields = ["id", "user", "code", "comment", "name"]
def validate(self, data):
if data["code"] and data["comment"]:
raise serializers.ValidationError(_('One reaction cannot be assigned to a code and a comment'))
if not data["code"] and not data["comment"]:
raise serializers.ValidationError(_("Please enter a code or a comment"))
return data
Я также пробовал
class Meta:
extra_kwargs = {'code': {'required': False},
'comment': {'required': False,}
}
example request
{
"code": 1,
"name": "love",
"user": 1
}
returned response
{"comment":["This field is required."]}
Required=False позволяет вам отправлять значения None/Blank в этом поле. Это не означает, что вы можете вообще не отправлять это поле в параметрах запроса. Другими словами, не следует путать 'required' с 'exclude' полями.
Для справки:
Если поле имеет required=False и вы передаете clean() пустое значение, то clean() вернет нормализованное пустое значение, а не выдаст ошибку ValidationError. Для поля CharField это вернет значение empty_value, которое по умолчанию пустая строка. Для других классов Field это может быть None. (Это зависит от конкретного поля.)
.
документация : https://docs.djangoproject.com/en/4.0/ref/forms/fields/#required
То, что вы делаете в своем сериализаторе, правильно. Просто убедитесь, что вы установили None для поля, которое вы не отправляете:
{
"code": 1,
"name": "love",
"user": 1,
"comment": None
}
или
{
"code": None,
"name": "love",
"user": 1,
"comment": 2
}