如何在Django rest框架中使ModelSerializer字段可选



我有这个带有代码和注释字段的模型Reaction。在我的models.py文件中,它们都为null=True,blank=True。我希望其中一个是填充的,另一个是空的,为此我在模型中创建了clean方法,并在序列化程序中验证了方法。但当我尝试创建一个没有代码/注释的反应时,它会说需要代码/注释。

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类,它可能是没有一个(这因场而异。(

文档: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
}

最新更新