Djangorestframework序列化器实现多张表数据添加和修改

在本文中,我们将了解Django rest框架嵌套序列化器以及如何创建DRF可写嵌套序列化器。本教程分为两部分。在第一部分中,我们将讨论如何创建模型、序列化器和视图。在第二部分中,我们将讨论如何使用嵌套序列化器以及如何创建和更新嵌套序列化器。

PART 1:

将下面的代码复制到您的Django应用程序的 models.py 文件中。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.


class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

    def __unicode__(self):
        return self.first_name


class Album(models.Model):
    artist = models.ForeignKey(Musician, on_delete=models.CASCADE, related_name='album_musician', null=True, blank=True)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

这里我们有两个model,'Musician'和'Album,'Album'有外键对'Musician'.

上述两个模型的序列化器可以像下面的代码片段那样编写。创建一个名为serializers.py 的文件,并将以下代码复制到其中

在使用djangorestframework,之前,请确保安装了它。您可以通过简单地运行以下命令来安装它

 
  
pip install djangorestframework

然后在settings.py文件中添加'rest_framework'到settings.py 中。

from .models import *
from rest_framework import serializers, fields


class AlbumSerializer(serializers.ModelSerializer):

    class Meta:
        model = Album
        fields = ('id', 'artist', 'name', 'release_date', 'num_stars')


class MusicianSerializer(serializers.ModelSerializer):

    class Meta:
        model = Musician
        fields = ('id', 'first_name', 'last_name', 'instrument')

现在在 views.py文件中,复制下面的代码并保存它。

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from .models import *
from .serializers import *
from rest_framework import generics
# Create your views here.


class MusicianListView(generics.ListCreateAPIView):
    queryset = Musician.objects.all()
    serializer_class = MusicianSerializer


class MusicianView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = MusicianSerializer
    queryset = Musician.objects.all()


class AlbumListView(generics.ListCreateAPIView):
    queryset = Album.objects.all()
    serializer_class = AlbumSerializer


class AlbumView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = AlbumSerializer
    queryset = Album.objects.all()

视图就绪后,将url添加到项目文件夹中的url .py文件。它将与settings.py文件位于相同的目录中。

url(r'^api/musicians/$', MusicianListView.as_view()),
url(r'^api/musicians/(?P\d+)/$', MusicianView.as_view()),
url(r'^api/albums/$', AlbumListView.as_view()),
url(r'^api/albums/(?P\d+)/$', AlbumView.as_view()),

MusicianListView的输出如下所示。

[
    {
        "id": 1,
        "first_name": "ganesh",
        "last_name": "xeno",
        "instrument": "Guitar"
    }
]

我也添加了一些 albums 这是示例输出。

[
    {
        "id": 1,
        "artist": 1,
        "name": "NEO",
        "release_date": "2017-07-07",
        "num_stars": 4
    },
    {
        "id": 2,
        "artist": 1,
        "name": "NEO 2",
        "release_date": "2017-07-22",
        "num_stars": 4
    }
]

如果我们想要在em>MusicianListView中显示“Albums”的详细信息,需要修改MusicianSerializer ,如下所示.

from .models import *
from rest_framework import serializers, fields


class AlbumSerializer(serializers.ModelSerializer):

    class Meta:
        model = Album
        fields = ('id', 'artist', 'name', 'release_date', 'num_stars')


class MusicianSerializer(serializers.ModelSerializer):
    album_musician = AlbumSerializer(read_only=True, many=True)

    class Meta:
        model = Musician
        fields = ('id', 'first_name', 'last_name', 'instrument', 'album_musician')

MusicianListView 的输出将类似于下面的代码片段

[
    {
        "id": 1,
        "first_name": "ganesh",
        "last_name": "xeno",
        "instrument": "Guitar",
        "album_musician": [
            {
                "id": 1,
                "artist": 1,
                "name": "NEO",
                "release_date": "2017-07-07",
                "num_stars": 4
            },
            {
                "id": 2,
                "artist": 1,
                "name": "NEO 2",
                "release_date": "2017-07-22",
                "num_stars": 4
            }
        ]
    }
]

正如我们现在看到的,Albums 被显示为列表。但这里我们只能读取数据。

PART 2:

现在让我们进入这篇文章的真正主题。也就是将数据写入这个嵌套的序列化程序。让我们继续修改下面所示的序列化器代码。

from .models import *
from rest_framework import serializers, fields


class AlbumSerializer(serializers.ModelSerializer):

    class Meta:
        model = Album
        fields = ('id', 'artist', 'name', 'release_date', 'num_stars')


class MusicianSerializer(serializers.ModelSerializer):
    album_musician = AlbumSerializer(many=True)

    class Meta:
        model = Musician
        fields = ('id', 'first_name', 'last_name', 'instrument', 'album_musician')

    def create(self, validated_data):
        albums_data = validated_data.pop('album_musician')
        musician = Musician.objects.create(**validated_data)
        for album_data in albums_data:
            Album.objects.create(artist=musician, **album_data)
        return musician

    def update(self, instance, validated_data):
        albums_data = validated_data.pop('album_musician')
        albums = (instance.album_musician).all()
        albums = list(albums)
        instance.first_name = validated_data.get('first_name', instance.first_name)
        instance.last_name = validated_data.get('last_name', instance.last_name)
        instance.instrument = validated_data.get('instrument', instance.instrument)
        instance.save()

        for album_data in albums_data:
            album = albums.pop(0)
            album.name = album_data.get('name', album.name)
            album.release_date = album_data.get('release_date', album.release_date)
            album.num_stars = album_data.get('num_stars', album.num_stars)
            album.save()
        return instance

下面给出了用于创建和更新MusicianSerializer的示例数据

# Post data to the MusicianListView to create.
{
    "first_name": "ganesh",
    "last_name": "xeno",
    "instrument": "Guitar",
    "album_musician": [
        {
            "name": "NEO",
            "release_date": "2017-07-07",
            "num_stars": 5
        },
        {
            "name": "NEO 2",
            "release_date": "2017-07-22",
            "num_stars": 4
        }
    ]
}

# PUT data to the MusicianListView to update data.
{
    "id": 1,
    "first_name": "ganesh",
    "last_name": "xeno",
    "instrument": "Guitar",
    "album_musician": [
        {
            "id": 1,
            "artist": 1,
            "name": "NEO",
            "release_date": "2017-07-07",
            "num_stars": 5
        },
        {
            "id": 2,
            "artist": 1,
            "name": "NEO 2",
            "release_date": "2017-07-22",
            "num_stars": 4
        }
    ]
}

你可能感兴趣的:(Django,DRF,ModelViewset,序列化器serializers)