Django Restframework POST объект с массивом объектов в таблицы "один-ко-многим
Я новичок в django и пытаюсь найти решение, как разместить объект с массивом объектов в моей базе данных.
Вот мой пример модели.
class Fruit(models.Model):
name = models.CharField(max_length=100)
class FruitReviews(models.Model):
reviews = models.CharField(max_length=100)
fruit = models.ForeignKey(Fruit, on_delete=models.CASCADE)
Вот мой сериализатор.
class FruitSerializer(serializers.ModelSerializer):
class Meta:
model = Fruit
fields = '__all__'
class FruitReviewSerializer(serializers.ModelSerializer):
class Meta:
model = FruitReview
fields = '__all__'
А вот мой набор представлений, который я пробую, но, к сожалению, он не работает.
@api_view('POST'])
def createFruit(request):
serializer = FruitSerializer(data=request.data)
serializer2 = FruitReviewSerializer(data=request.data.fruitReviews, many = True)
if serializer.is_valid() and serializer2.is_valid():
serializer.save()
serializer2.save()
return Response(status=status.HTTP_200_OK)
В принципе, например, со стороны клиента я хочу разместить что-то вроде этого
{
"name": "Apple",
"fruitReviews": [{
"reviews": "Very yummy"
},
{
"reviews": "Healthy"
},
{
"reviews": "Fresh"
}]
}
Я хочу, чтобы он был размещен в таблице fruit и fruit reviews должным образом с их отношениями один-ко-многим. Помогите пожалуйста?
Сначала вам нужно изменить ваш сериализатор для FruitReviewSerializer
как:
class FruitReviewSerializer(serializers.ModelSerializer):
class Meta:
model = FruitReviews
fields = ['reviews']
Тогда в views.py
:
@api_view(['POST'])
def createFruit(request):
serializer = FruitSerializer(data=request.data)
serializer2 = FruitReviewSerializer(data=request.data['fruitReviews'], many = True)
if serializer.is_valid() and serializer2.is_valid():
fruit = Fruit.objects.filter(name = request.data['name']).exists()
if not fruit:
serializer.save()
fruit = Fruit.objects.get(name = request.data['name'])
for i in request.data['fruitReviews']:
review = FruitReviews(
fruit = fruit,
reviews = i['reviews']
)
review.save()
return Response(status=status.HTTP_200_OK)
else:
return Response(status=400)
Надеюсь, это сработает!
По умолчанию вложенные сериализаторы доступны только для чтения. Если вы хотите поддерживать операции записи во вложенное поле сериализатора, вам нужно будет создать методы create() и/или update(), чтобы явно указать, как должны сохраняться дочерние отношения:
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ['order', 'title', 'duration']
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
def create(self, validated_data):
tracks_data = validated_data.pop('tracks')
album = Album.objects.create(**validated_data)
for track_data in tracks_data:
Track.objects.create(album=album, **track_data)
return album
и данные должны быть такими:
data = {
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
],
}
ссылка: https://www.django-rest-framework.org/api-guide/relations/
Надеюсь, это будет работать без изменения ваших сериализаторов.
@api_view(['POST'])
@transaction.atomic
def create_fruit(request):
fruit_reviews_data = request.data['fruitReviews']
if 'fruitReviews' in request.data.keys():
request.data.pop('fruitReviews')
fruit_serializer = FruitSerializer(data=request.data)
fruit_obj = None
if fruit_serializer.is_valid(raise_exception=True):
fruit_obj = Fruit.objects.create(**request.data)
for fruit_review_data in fruit_reviews_data:
fruit_review_data['fruit_id'] = fruit_obj.id
fruit_review_serializer =FruitReviewSerializer(data=fruit_review_data)
if fruit_review_serializer.is_valid(raise_exception=True):
fruit_review_serializer.save()
return Response(status=status.HTTP_200_OK)