0

次のモデル スケルトンがあります。

class A(models.Model):
    post_id = models.ForeignKey('D')
    user_id = models.ForeignKey('B')

class B(AbstractBaseUser):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=20, unique=True)    
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=40)
    # `resource_id`
    profile_photo = models.ForeignKey('C', null=True)

class C(models.Model):
    user_id = models.ForeignKey('B')
    name = models.CharField(max_length=60)

nameB に関連するモデル C から返される A のシリアライザーを書きたいと思います。

ここでの関係は A->B->C のようなものです A のシリアライザを使用して C からデータを取得したい

A経由でCにアクセスしたい、つまりBからprofile_photoを取得し、Cからprofile_photoの名前を取得したい

ここでDjango Rest 関係を指定して RelatedFields をスクロールしましたが、私が望むものを達成することができません。

私がそれを達成できる方法はありますか。

また、モデル スケルトンに記載されている以外の多くのフィールドがあり、それらを取得したくありません。

編集:私が必要とする最終結果は、モデルCからuser_idの特定post_idのAからのすべてですname

4

1 に答える 1

1

ModelSerializerでこれを行うことができます:

注:それ'posts.Post'がモデルであると仮定しますC

class CsSerializer(serializers.ModelSerializer):

    class Meta:
        model = C
        fields = ('name')


class AsSerializer(serializers.ModelSerializer):

    post_id = CsSerializer()

    class Meta:
        model = A
        # exclude = ('field_you_dont_want_1', 'field_you_dont_want_2')
        # fields = ('field_you_want_1', 'field_you_want_2')

この場合CsSerializer、モデルから必要なフィールドを返すことができることに注意してください。Cname

文字列だけが必要な場合は、StringRelatedFieldを使用できます

class AsSerializer(serializers.ModelSerializer):
    post_id = serializers.StringRelatedField(many=True)

    class Meta:
        model = A

これStringRelatedFieldは、C モデルが method で返すものを返します__unicode__( __str__python 3.x の場合は method )。

編集

今、あなたのコメントから、私はそれがモデルで'posts.Post'はないことを知っています. したがって、 SerializerMethodFieldCを使用できます。

class AsSerializer(serializers.ModelSerializer):
    c_name = serializers.SerializerMethodField()

    def get_c_name(self, obj):
        return obj.user_id.c_set.values('name')  # this will return a list of dicts with B's related C objects.

    class Meta:
        model = A

編集

モデルではいつでもクラス メソッドを定義できます。

class B(AbstractBaseUser):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=20, unique=True)    
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=40)
    # `resource_id`
    profile_photo = models.ForeignKey('C', null=True)

    def get_profile_photo(self):
        return self.profile_photo.name  # This will return 'C' related object's name

したがって、A のオブジェクトがある場合:

a_object.user_id.get_profile_photo()

または、B のオブジェクトがある場合:

b_object.get_profile_photo()

編集

C クラスの新しい Serializer を定義できます。

class CsSerializer(serializers.Serializer):

    class Meta:
        model = C

次に、あなたのAsSerializer

class AsSerializer(serializers.ModelSerializer):
    c_name = serializers.SerializerMethodField()

    def get_c_name(self, obj):
        qs = obj.user_id.c_set.all()
        qs_serialized = CsSerializer(qs, many=True)
        return qs_serialized.data

    class Meta:
        model = A
于 2015-10-03T15:42:00.673 に答える