Как сделать поле 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
}
Вернуться на верх