2017-05-22 34 views
0

DRFの中間モデルからのフィールドへのアクセスに苦労しています。Django Rest Frameworkの中間モデルからのフィールドへのアクセス

のは、関連のモデルを見てみましょう:

class School(models.Model): 

    created = models.DateTimeField(auto_now_add=True) 
    name = models.CharField(max_length=50, verbose_name=_(u'Name')) 

    staff_order = models.ManyToManyField(settings.AUTH_USER_MODEL, verbose_name=_(u'Staff ordering'), through='StaffOrder', related_name='school_staff_order') 

class User(AbstractUser): 

    phone = models.CharField(max_length=20, blank=True, null=True) 
    address = models.CharField(max_length=150, blank=True, null=True) 
    about_me = models.CharField(max_length=200, blank=True, null=True) 

    REQUIRED_FIELDS = ['email'] 

    def __unicode__(self): 
     return u'{0}'.format(self.username) 

class StaffOrder(models.Model): 
    user = models.ForeignKey(settings.AUTH_USER_MODEL) 
    school = models.ForeignKey(School) 
    order = models.PositiveSmallIntegerField(default=0, verbose_name=_(u'Staff ordering for this school')) 

    class Meta: 
     verbose_name_plural = _(u'Staff ordering') 

は今、私は期待していどのようなユーザー(StaffSerializer)のためのクエリセットを返すときにStaffOrderから順番フィールドを読み取ることができることです。ここでシリアライザされています

class StaffRoleSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = StaffOrder 
     fields = (
      'order', 
     ) 


class StaffSerializer(serializers.ModelSerializer): 

    username = serializers.CharField(max_length=75, required=True) 
    email = serializers.CharField(max_length=75, required=True) 
    order = StaffRoleSerializer(source='school_staff_order') 

    class Meta: 
     model = User 

StaffSerializerために返され、何がこのユーザーに関連StaffOrderモデルからではなく、注文フィールドで、マネージャです。私もシリアライザからこの値を書くことができるようにしてみたいが、私はビューセットでそれを行うことができますが、私

[ 
    { 
    "username": "Denise", 
    "email": "[email protected]", 
    "order": 9 
    }, 
    { 
    "username": "Ina", 
    "email": "[email protected]", 
    "order": 4 
    } 
] 

:A JSONはスタッフのための応答がこのようなものになるだろうと予想

シリアライザ自体でこの値を読む必要があります...私はここで何が欠けているのか考えていますか?

+0

あなたの名前はとても混乱しています。注文フィールドにsource = school_staff_orderがあるのはなぜですか?それは何を参照していますか? –

+0

@ zaphod100.10これは、シリアライザで中間モデルをマッピングする際の要件と思われます。これは、School.staff_order – AlejandroVK

+0

の関連する名前にマップされます。フィールド 'staff_order'は、学校モデル上で' users'または 'staff'という名前にしてはなりませんか?それはユーザーとの関係が多いからです。そして、あなたが望んでいるjsonの例を挙げることができますか? –

答えて

1

最初に、1人のユーザーが多くのスタッフの注文を受けることができることを理解する必要があります。あなたのモデルでは、そのように定義しました。

質問で指定したjson出力を取得するには、ユーザーではなくStaffOrderオブジェクトを照会する必要があります。

class StaffOrderSerializer(serializers.ModelSerializer): 
    username = serializers.CharField(source='user.username') 
    email = serializers.CharField(source='user.email') 

    class Meta: 
     model = StaffOrder 
     fields = ('order',) 

リストビューで、このシリアライザクラスを使用します。

class StaffOrderListApi(generics.ListAPIView): 
    serializer_class = StaffOrderSerializer 

    def get_queryset(self): 
     # using distinct because same user can have multiple staff orders 
     # based on your example it seems you want distinct users 
     return StaffOrder.objects.all().distinct('user') 

これはまさにあなたが望むJSONをあなたを取得します。

+0

ありがとう、しかし、これははるかに大きなアプリの一部です、私はStaffOrdersモデルを返すことはできません。そして、はい、ユーザーはN学校にいる可能性があり、各学校で異なる順序を持つ可能性があるので、ユーザーはStaffOrderモデルで複数の項目を持つことができます。ビューについては、NestedViewSetMixinとModelViewSetを継承するビューを使用しています。私がコメントしたように、これは私の現在のモデルの非常に単純なバージョンです、私は私のStaffSerializerを捨てることはできません、あなたの提案StaffOrderSerializerを使用することはできませんが、 – AlejandroVK

関連する問題