如何在 Django 休息框架中使 ModelSerializer 字段可选
How to make ModelSerializer field optional in Django rest framework
我有这个带有代码和评论字段的模型 Reaction。我的 models.py 文件中都有它们 null=True, blank=True 。我希望其中一个被填充而另一个为空,为此我在模型中创建了 clean 方法并在序列化程序中创建了 validate 方法。但是当我尝试在没有 code/comment 的情况下创建反应时,它说 code/comment 是必需的。
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' 字段混淆。
供参考:
If a Field has required=False and you pass clean() an empty value,
then clean() will return a normalized empty value rather than raising
ValidationError. For CharField, this will return empty_value which
defaults to an empty string. For other Field classes, it might be
None. (This varies from field to 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
}
我有这个带有代码和评论字段的模型 Reaction。我的 models.py 文件中都有它们 null=True, blank=True 。我希望其中一个被填充而另一个为空,为此我在模型中创建了 clean 方法并在序列化程序中创建了 validate 方法。但是当我尝试在没有 code/comment 的情况下创建反应时,它说 code/comment 是必需的。
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' 字段混淆。
供参考:
If a Field has required=False and you pass clean() an empty value, then clean() will return a normalized empty value rather than raising ValidationError. For CharField, this will return empty_value which defaults to an empty string. For other Field classes, it might be None. (This varies from field to 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
}