0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【RestFramework】関連するモデル一覧を出力する

Last updated at Posted at 2021-04-21

関連するモデルを出力することを学んだのでメモする

前提

各、都道府県と市区町村が関連するmodelを用意

  1. Prefは都道府県
  2. Cityは市区町村を指す
class Pref(models.Model):
    pref_name = models.CharField(max_length=255, blank=True)
    pref_code = models.CharField(max_length=255, blank=True)

    def __str__(self):
        return self.pref_name


class City( models.Model ):
    city_name = models.CharField( max_length=255, blank=True )
    city_code = models.CharField( max_length=255, blank=True )
    pref = models.ForeignKey(Pref, on_delete=models.CASCADE, blank=True)

    def __str__(self):
        return self.city_name

データの登録

1.管理画面で適当にモデルにデータを登録する。

今回はテストなのでこんな感じで登録した。

都道府県

スクリーンショット 2021-04-21 18.29.26.png

市区町村

スクリーンショット 2021-04-21 18.30.54.png

  1. 木更津、富津市は千葉県へ紐付ける
  2. 十和田市は青森県へ紐付ける
  3. 札幌市中央区は北海道へ紐付ける

Serializerの登録

Serializerの細かい作成方法は割愛します。
今回はPrefに紐付いているCity一覧を取得することを大目的にします。

from rest_framework import serializers
from .models import Pref, City, Plan


class CitySerializer(serializers.ModelSerializer):

    class Meta:
        model = City
        fields = ['id', 'city_name', 'city_code']


class PrefSerializer(serializers.ModelSerializer):

    city = serializers.SerializerMethodField()

    class Meta:
        model = Pref
        fields = ['id', 'pref_name', 'pref_code', 'city']

    def get_city(self, obj):
        try:
            city_child = CitySerializer(City.objects.all().filter(pref=Pref.objects.get(id=obj.id)),many=True).data
            return city_child
        except:
            city_child = None
            return city_child


ポイント

  1. PrefSerializerにcity = serializers.SerializerMethodField()を追加すること
  2. 子要素のcityオブジェクトを def get_cityとして取得することです。

以下コードはCitySerializerからcityオブジェクト一覧を取得し、フィルターで関連するPrefオブジェクトを取得しています。
最後に,.data をつけないとエラーになります。

city_child = CitySerializer(City.objects.all().filter(pref=Pref.objects.get(id=obj.id)),many=True).data

View

今回はAPIViewを継承して一覧を取得しました。

from django_filters import rest_framework as filters
from rest_framework import status, views
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError

from .models import Pref, City
from .serializer import PrefSerializer, PlanSerializer, CitySerializer

class PrefFilter(filters.FilterSet):

    class Meta:
        model = Pref
        fields = '__all__'


class PrefListApiView(views.APIView):

    def get(self, request, *args, **kwargs):
        #Prefオブジェクトを取得
        filter_set = PrefFilter(request.query_params, queryset=Pref.objects.all()) 
        #バリデーション
        if not filter_set.is_valid():
            raise ValidationError(filter_set.errors)

     #serializerインスタンスの作成
        serializer = PrefSerializer(instance=filter_set.qs, many=True)
        # serializerをレスポンス
        return Response(serializer.data, status.HTTP_200_OK)

結果はこんな感じ

スクリーンショット 2021-04-21 18.44.38.png

city_code入れるの忘れた...

ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?