我有一个带有以下代码的django rest API:
models.py:
from django.db import models
class Actor(models.Model):
id = models.CharField(max_length = 50, primary_key = True)
login = models.CharField(max_length = 50, unique = True, blank = False)
avatar_url = models.CharField(max_length = 100, blank = False)
def __str__(self):
return self.login
class Repo(models.Model):
id = models.CharField(max_length = 50, primary_key=True)
name = models.CharField(max_length =50, blank=False)
url = models.CharField(max_length=100, blank=False, unique = True)
def __str__(self):
return self.name
class Event(models.Model):
id = models.CharField(max_length = 50, primary_key = True)
type = models.CharField(max_length = 50)
actor = models.ForeignKey(Actor, on_delete = models.PROTECT)
repo = models.ForeignKey(Repo, on_delete=models.CASCADE)
created_at = models.DateField()
def __str__(self):
return self.name
serializers.py:
from models import Actor, Repo, Event
class ActorSerializer(serializers.ModelSerializer):
class Meta:
model = Actor
fields = ('id', 'login', 'avatar_url')
class RepoSerializer(serializers.ModelSerializer):
class Meta:
model = Repo
fields = ('id', 'name', 'url')
class EventSerializer(serializers.ModelSerializer):
actor = ActorSerializer()
repo = RepoSerializer()
class Meta:
model = Event
fields = ('id', 'type', 'actor', 'repo', 'created_at')
views.py:
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from models import Actor, Repo, Event
from serializers import ActorSerializer, RepoSerializer, EventSerializer
class EventView(ModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
事件模型具有Actor和Repo模型的外键。因此,它具有嵌套的序列化器。无论何时发送POST请求,都会将一个事件添加到事件模型中。但是在添加事件之前,还将添加Actor和Repo行。
如果我添加另一个事件,并且具有与之前相同的Actor和Repo信息,则会收到错误消息,提示那些Actor和Repo已经存在。
如何确保如果Actor和Repo条目已经存在,则事件添加仍应成功?我希望仅当Actor和Repo不存在时才创建它们。
答案 0 :(得分:0)
我将您的序列化器更改为
class ActorSerializer(serializers.ModelSerializer):
class Meta:
model = Actor
fields = ('id', 'login', 'avatar_url')
extra_kwargs = {
"id": {"validators": []},
"login": {"validators": []}
}
class RepoSerializer(serializers.ModelSerializer):
class Meta:
model = Repo
fields = ('id', 'name', 'url')
extra_kwargs = {
"id": {"validators": []},
"url": {"validators": []}
}
class EventSerializer(serializers.ModelSerializer):
actor = ActorSerializer()
repo = RepoSerializer()
def create(self, validated_data):
repo, created = Repo.objects.get_or_create(**validated_data.pop('repo'))
actor, created = Actor.objects.get_or_create(**validated_data.pop('actor'))
return Event.objects.create(**validated_data, repo=repo, actor=actor)
class Meta:
model = Event
fields = ('id', 'type', 'actor', 'repo', 'created_at')
我做了什么?
您在模型中将某些字段定义为unique
,因此在序列化程序中它已成为Validator
。我通过在Metaclass中添加extra_kwargs
覆盖了两个序列化器的验证
要创建Writable Nested Serializers
,我们必须覆盖create()
EventSerializer
方法