Dav*_* R. 6 django django-rest-framework
假设给出以下模型和序列化器。
class Human(models.Model):
name = models.TextField(unique=True)
class HumanSer(serializers.ModelSerializer):
class Meta:
model = Human
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
我想验证一下,当给出一个名称列表时,该列表中的名称不会重复,而无需访问数据库(更多内容见下文)。
data = [{'name': 'John}, {'name': 'John'}]
ser = HumanSer(data=data, many=True)
Run Code Online (Sandbox Code Playgroud)
在完美的世界中,我会添加validate_name方法,访问所有先前验证的条目,并引发“ValidationError”。
目前这似乎不可能,所以我找到的选项是:
.initial_data并进行比较。这似乎不太可靠,因为我必须小心,因为我正在处理未经验证的原始数据;注意数据是否是列表等。.is_valid()返回True,但.save()抛出异常。在这种情况下,REST 调用整体失败,我无法指出名称重复的用户。如果您只关心输入列表中的唯一项目,请查看ListSerializer
class HumanListSerializer(serializers.ListSerializer):
def validate(self, data):
validation_set = set()
for item in data:
if item["name"] in validation_set:
raise serializers.ValidationError(f"duplicated item: {item['name']}")
else:
validation_set.add(item["name"])
return data
class HumanSerializer(serializers.Serializer):
name = serializers.CharField()
class Meta:
list_serializer_class = HumanListSerializer
if __name__ == '__main__':
data = [{'name': 'John', "xxx": "xz"}, {'name': 'John'}]
ser = HumanSerializer(data=data, many=True)
print(f"is valid: {ser.is_valid()}")
print(f"errors: {ser.errors}")
# >>> is valid: False
# >>> errors: {'non_field_errors': [ErrorDetail(string='duplicated item: John', code='invalid')]}
Run Code Online (Sandbox Code Playgroud)
但是如果你想验证整个数据库的唯一性,请看一下UniqueValidator
from rest_framework.validators import UniqueValidator
class HumanSer(serializers.ModelSerializer):
name = serializers.CharField(
validators=[UniqueValidator(queryset=Human.objects.all())]
)
class Meta:
model = Human
fields = '__all__'
Run Code Online (Sandbox Code Playgroud)
(我不确定这种方法的性能)
更新:正如 Iain Shelvington 指出的那样,存在一个悬而未决的问题,其中可能需要结合 ListSerializer 和 UniqueValidator 解决方案。
| 归档时间: |
|
| 查看次数: |
2526 次 |
| 最近记录: |