DRFで実装したAPIで、ManyToManyなフィールドに、同時にオブジェクトをCreate出来るようにしたい。

公式ドキュメントのやり方は少々煩雑なのでライブラリを使う

drf-writable-nested

https://github.com/beda-software/drf-writable-nested

以下の使い方はドキュメントからの抜粋

Model

# models.py
from django.db import models


class Site(models.Model):
    url = models.CharField(max_length=100)


class User(models.Model):
    username = models.CharField(max_length=100)


class AccessKey(models.Model):
    key = models.CharField(max_length=100)


class Profile(models.Model):
    sites = models.ManyToManyField(Site)
    user = models.OneToOneField(User)
    access_key = models.ForeignKey(AccessKey, null=True)


class Avatar(models.Model):
    image = models.CharField(max_length=100)
    profile = models.ForeignKey(Profile, related_name='avatars')

Serializer

Serializerはこう書く。ManyToManyを定義してあるModelのSerializerでWritableNestedModelSerializerを継承する。OneToOneなフィールドにも対応している。

# serializers.py
from rest_framework import serializers
from drf_writable_nested.serializers import WritableNestedModelSerializer

class AvatarSerializer(serializers.ModelSerializer):
    image = serializers.CharField()

    class Meta:
        model = Avatar
        fields = ('pk', 'image',)

class SiteSerializer(serializers.ModelSerializer):
    url = serializers.CharField()

    class Meta:
        model = Site
        fields = ('pk', 'url',)

class AccessKeySerializer(serializers.ModelSerializer):

    class Meta:
        model = AccessKey
        fields = ('pk', 'key',)


class ProfileSerializer(WritableNestedModelSerializer):
    # Direct ManyToMany relation
    sites = SiteSerializer(many=True)

    # Reverse FK relation
    avatars = AvatarSerializer(many=True)

    # Direct FK relation
    access_key = AccessKeySerializer(allow_null=True)

    class Meta:
        model = Profile
        fields = ('pk', 'sites', 'avatars', 'access_key',)


class UserSerializer(WritableNestedModelSerializer):
    # Reverse OneToOne relation
    profile = ProfileSerializer()

    class Meta:
        model = User
        fields = ('pk', 'profile', 'username',)

登録処理

data = {
    'username': 'test',
    'profile': {
        'access_key': {
            'key': 'key',
        },
        'sites': [
            {
                'url': 'http://google.com',
            },
            {
                'url': 'http://yahoo.com',
            },
        ],
        'avatars': [
            {
                'image': 'image-1.png',
            },
            {
                'image': 'image-2.png',
            },
        ],
    },
}

user_serializer = UserSerializer(data=data)
user_serializer.is_valid(raise_exception=True)
user = user_serializer.save()

# 確認してみる
user_serializer = UserSerializer(instance=user)
print(user_serializer.data)

#>> 結果
{
    'pk': 1,
    'username': 'test',
    'profile': {
        'pk': 1,
        'access_key': {
            'pk': 1,
            'key': 'key'
        },
        'sites': [
            {
                'pk': 1,
                'url': 'http://google.com',
            },
            {
                'pk': 2,
                'url': 'http://yahoo.com',
            },
        ],
        'avatars': [
            {
                'pk': 1,
                'image': 'image-1.png',
            },
            {
                'pk': 2,
                'image': 'image-2.png',
            },
        ],
    },
}

注意点

既知の問題として、Updateの際、ユニーク制約のある属性のValidationに問題がある模様。
https://github.com/beda-software/drf-writable-nested#known-problems-with-solutions

Udemy 独学でのアプリ開発に限界を感じたら

プログラミング初学者の皆さんに、 Udemy を強くお勧めしたいと思います。 Udemy は世界中のトップレベルのプログラミング講師が提供するオンライン講座を取り揃えています。以下は、 Udemy で学ぶことのメリットについての詳細です。

1. Udemy の豊富なコースの選択肢

Udemyには、数千ものコースがあります。初心者から上級者まで、プログラミングのあらゆるレベルを網羅しています。また、様々なプログラミング言語やツールに関するコースも多数あり、希望に合わせたコースを選ぶことができます。

2. 実践的な学習方法

Udemyのコースは、理論だけでなく実践的な学習も行えます。多くのコースには、プログラムの作成や実際のプロジェクトに取り組む演習が含まれています。これにより、理論だけでなく実践的なスキルも身につけることができます。

3. Udemy には質の高い講師陣

Udemyの講師陣には、世界中のトップレベルのプログラマーが多数在籍しています。彼らは、実務での経験を活かして、分かりやすい講義を行っています。

4. 初学者が始めるのにとても手頃な価格

Udemyのコースは、他のオンライン講座と比べて手頃な価格で提供されています。また、一度購入すると、終身アクセスが得られるので、自分のペースで学習することができます。

以上の理由から、プログラミング初学者の方には、Udemyが最適な学習プラットフォームであると考えられます。ぜひ一度、Udemyのコースを体験してみてください。


ウェブ開発の人気オンラインコース


ITとソフトウェアの人気オンラインコース


デザインの人気オンラインコース