質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

0回答

1516閲覧

Django Serializerを使用した関連モデルのリソースをネスト形式で取ってきたい

Exacom

総合スコア4

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/09/30 05:07

Django Serializerを使用した関連モデルのリソースをネスト形式で取ってきたい

はじめまして。新米プログラマーのExaと申します。
今回、DjangoのREST_Framework・Serializerを利用し、関連先のモデル情報を含め、JSON化して
出力したいと思っております。

実装内容といたしまして、
Postモデルのauthorフィールドには、models.ForeignKeyを使用して、Userモデルを関連付けております。
実際にAPIを叩き、PostモデルからJSONを生成する際、authorフィールドには、Userモデルのuuid(PK)とJournalist_nameという2つの情報をネストした状態を付け加え、返却したいと考えております。

Postモデル

def get_delete_msg(): return User.objects.get_or_create(journalist_name='unknown')[0].pk class Post(models.Model): class Meta: db_table = "posts" id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True) title = models.CharField(_('タイトル'), max_length=255) content = models.TextField(_("コンテンツ")) author = models.ForeignKey(User, null=True, on_delete=models.SET(get_delete_msg())) post_create_day = models.DateField(_('作成日付'), default=now()) post_deadline_day = models.DateField(_('締切日付'), null=True, blank=True) evalution_count = models.FloatField(_('記事総合評価'), default=0) agree_count = models.FloatField(_('賛同評価'), default=0) opposite_count = models.FloatField(_('反論評価'), default=0) comment_count = models.IntegerField(_('コメント数'), default=0) thumbnail_img = models.ImageField(_("サムネイル画像"), upload_to='Thumbnail', null=True, blank=True) def __str__(self): return self.title

Userモデル

#関係ないフィールドは載せていません class User(AbstractBaseUser, PermissionsMixin): class Meta(AbstractBaseUser.Meta): db_table = 'wej_user' username_validator = UnicodeUsernameValidator() uuid = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True) journalist_name = models.CharField(_('journalist_name'), max_length=150, default="Jornalist")

(現在)Postモデル単体から取得した場合

[ { "id": "26c39386-0900-4f50-adac-f6318d9eb363", "title": "テスト1", "content": "test", "author": "24dee3aa-3a39-49e7-8e0f-7918250f1aab", "post_deadline_day": null, "evalution_count": 0.0, "agree_count": 0.0, "opposite_count": 0.0, "comment_count": 0, "thumbnail_img": null } ]

Postモデル+Userモデルから必要な情報を付け加え実際に出力させたい内容

[ { "id": "26c39386-0900-4f50-adac-f6318d9eb363", "title": "テスト1", "content": "test", "author": { "uuid": "24dee3aa-3a39-49e7-8e0f-7918250f1aab", "journalist_name" : "journalist" }, "post_deadline_day": null, "evalution_count": 0.0, "agree_count": 0.0, "opposite_count": 0.0, "comment_count": 0, "thumbnail_img": null } ]

実現するために行ったこと

PostSerializerクラスのauthorフィールドに、AuthorListSerializerを指定しています。

# serializers.py class AuthorSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['uuid', 'journalist_name'] class AuthorListSerializer(serializers.ListSerializer): child = AuthorSerializer() class PostSerializer(serializers.ModelSerializer): author = AuthorListSerializer() class Meta: model = Post fields = ('id', 'title', 'content', 'author', 'post_deadline_day', 'evalution_count', 'agree_count', \ 'opposite_count', 'comment_count', 'thumbnail_img')

■■すると、以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 760, in data ret = super().data File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 261, in data self._data = self.to_representation(self.instance) File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 678, in to_representation self.child.to_representation(item) for item in iterable File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 678, in <listcomp> self.child.to_representation(item) for item in iterable File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 526, in to_representation ret[field.field_name] = field.to_representation(attribute) File "/code/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 674, in to_representation self.child.to_representation(item) for item in iterable TypeError: 'User' object is not iterable

試したこと

rest_framework/serializers.pyのエラー箇所を確認すると、以下の場所で失敗していました。

def to_representation(self, data): """ List of object instances -> List of dicts of primitive datatypes. """ # Dealing with nested relationships, data can be a Manager, # so, first get a queryset from the Manager if needed # ここで失敗している様子 iterable = data.all() if isinstance(data, models.Manager) else data return [ self.child.to_representation(item) for item in iterable ]

イテレーターではない? このあたりがよくわかりません。
serializers.pyの書き方が悪いのでしょうか。
このiterable変数をコンソール出力してみると、PostモデルのQuerySetと、メールアドレスが返ってきました。

<QuerySet [<Post: テスト1>]> root@hogehoge.com

ちなみに、メールアドレスでログインさせる実装にしているので、UserモデルのUSERNAME_FIELDは以下のようにしています。

USERNAME_FIELD = 'email'

補足情報(FW/ツールのバージョンなど)

Python 3.7.4
Django==2.2.5
mysqlclient==1.4.4
djangorestframework==3.10.3

お力添えいただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問