需求:需要真多多对多的插入插入数据操作,这个问题卡了很久。
1.Model定义
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=255, unique=True)
class Book(models.Model):
title = models.CharField(max_length=200)
#定义多对多的关系
author = models.ManyToManyField(Author, related_name="author_related")
2.Serializer序列化定义
from rest_framework import serializers
from .models import Author, Book
class AuthorModelSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ("id","name")
def create(self, validated_data):
"""
根据提供的验证过的数据创建并返回一个新的`Author`实例。
"""
return Author.objects.create(**validated_data)
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ("id","title","author")
#重点重点!!!
def create(self, validated_data):
"""
根据提供的验证过的数据创建并返回一个新的`Author`实例。
"""
#将authors 多对多关系的数据从前端传过来的数据中取出,放在authors 中
authors = validated_data.pop('author')
#将正常的book的数据进行保存,创建Book实例,并通过book 接收
book = Book.objects.create(** validated_data)
#重点中的重点:循环读取authors对象的数据
for author in authors:
#实例化author对象
author = Author.objects.filter(id=author.id).first()
#将多对多的关系添加到book中
book.author.add(author)
#保存book的多对多关系
book.save()
return book
自己疑惑的点:
1.如果需要depth =1,需要展示成多层的嵌套的数据的样式,,多层嵌套目前我还没有找到添加的数据的方式。我能想到的思路是建两个序列化的类,一个用于插入和更新的序列化类,一个专门用于查新的序列化类。合并在一起哪位知道也可以告知一下。
2.以及需要自己定制显示多对多的关系的字段,比如设置下面的样式,都会添加报错。以及增加read_only =True也会报错。
author = AuthorModelSerializer(many=True)
author = serializers.PrimaryKeyRelatedField(many=True)
author = serializers.SlugRelatedField(
many=True,
read_only=True,
slug_field='author_related'
)
3.View的编写:使用APIView
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from books.models import Book,Author
from books.serializers import BookModelSerializer,AuthorModelSerializer
from rest_framework import viewsets
class BookList(APIView):
def get(self, request):
books = Book.objects.all()
serializer = BookModelSerializer(books, many=True)
return Response(serializer.data)
def post(self, request, *args, **kwargs):
data = request.data
serializer = BookModelSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class AuthorList(APIView):
def get(self, request):
authors = Author.objects.all()
serializer = AuthorModelSerializer(authors, many=True)
return Response(serializer.data)
def post(self, request):
data = request.data
print(data)
serializer = AuthorModelSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
4.URL配置
from django.contrib import admin
from django.urls import path,re_path,include
from books import views
urlpatterns = [
re_path(r'^booklist/$', views.BookList.as_view()),
re_path(r'^authorlist/$', views.AuthorList.as_view()),
]