例如
class People(models.Model):
name = models.CharField(max_length=20)
class Blog(models.Model):
author = models.ForeignKeyField(People)
content = models.TextField()
然后,
class CreateBlogSerializer(serializers.Serializer):
#author id
author = serializers.IntegerField()
content = serializers.TextField()
在视图中,我需要获取author_id,检查id是否存在并获取作者实例,这样做很麻烦。
serializer = CreateBlogSerializer(data=request.DATA)
if serializer.is_valid():
try:
author = Author.objects.get(pk=serializer.data["author"])
except Author.DoesNotExist:
return Response(data={"author does not exist"})
blog = Blog.objects.create(author=author, content=serializer.data["content"])
是否有一个ForeignKeyField来反序列化和验证primarykey数据,然后返回一个实例。
class CreateBlogSerializer(serializers.Serializer):
author = serializers.ForeignKeyField(Author)
content = serializers.TextField()
serializer = CreateBlogSerializer(data=request.DATA)
if serializer.is_valid():
#after deserialization , the author id becomes author model instance
blog = Blog.objects.create(author=serializer.data["author"], content=serializer.data["content"])
else:
#the author id does not exist will cause serializer.is_valid=Flase
PS
我在ModelSerializer中知道PrimaryKeyRelatedField,但我不能在这里使用ModelSerializer,模型结构很复杂,上面只是示例。
我的第一个想法是写一个客户领域。
答案 0 :(得分:1)
class ForeignKeyField(WritableField):
def __init__(self, model_name, *args, **kwargs):
super(ForeignKeyField, self).__init__(*args, **kwargs)
self.model_name = model_name
self.model_instance = None
def from_native(self, pk):
if not isinstance(pk, int):
raise ValidationError("pk must be int")
try:
self.model_instance = self.model_name.objects.get(pk=pk)
return self.model_instance
except self.model_name.DoesNotExist:
raise ValidationError('object does not exist')
def to_native(self, obj):
return self.model_instance
我入侵了它,但我不知道它为什么会起作用。
<强>用法:强> 有一点差异
class t_serializer(serializers.Serializer):
author = ForeignKeyField(Author)
@api_view(["POST"])
def func(request):
serializer = t_serializer(data=request.DATA)
if serializer.is_valid():
print isinstance(serializer.data["author"], Author)
#print True
else:
print serializer.errors
答案 1 :(得分:0)
看来你想要的是自定义验证码。
对于此特定实例,您可以编写以下内容。
class CreateBlogSerializer(serializers.Serializer):
author = serializers.ForeignKeyField(Author)
content = serializers.TextField()
def validate_author(self, attrs, source):
"""
Verify that the author exists.
"""
author = attrs[source]
if Author.objects.filter(pk=author).exists():
return attrs
raise serializers.ValidationError("Specified Author does not exist!")
现在,当您致电serializer.is_valid()
时,将会进行此项检查。
因此,您可以在代码中的其他位置执行此操作,
if serializer.is_valid():
blog = Blog.objects.create(author=serializer.data["author"], content=serializer.data["content"])
请确保如果创建了给定的blog
,则数据库中已存在相应的Author
。
因此,Django Rest Framework提供了一种向序列化程序添加自定义验证的方法。这可以通过在序列化程序类validate_<field name>
中提供以下格式的方法来完成。这些方法会将source
值设置为给定字段的名称,在我们的示例author
中,然后可以与attrs
变量一起使用以获取字段的当前值({ {1}}包含传递给序列化程序的所有值。
调用这些验证方法,然后调用attrs
方法。如果给定的测试通过,他们应该返回serializer.is_valid()
,否则提出attrs
。
它们可能会有些复杂,所以如果你在这里阅读完整的文档可能是最好的,http://www.django-rest-framework.org/api-guide/serializers#validation