Django Rest Framework中的中间模型访问字段

时间:2017-05-22 14:19:55

标签: django django-rest-framework

很难尝试从DRF中的中间模型访问字段。

让我们看看相关的模型:

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)返回QuerySet时从StaffOrder读取订单字段。以下是Serializers:

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返回的是Manager,而不是与此User相关的StaffOrder模型中的order字段。

员工的JSON预期响应将是这样的:

[
  {
    "username": "Denise",
    "email": "deniseburton@maximind.com",
    "order": 9
  },
  {
    "username": "Ina",
    "email": "inaburton@maximind.com",
    "order": 4
  }
]

我希望能够从序列化器中写出这个值,但是我可以在Viewset中做到这一点,但我真的需要在Serializer中读取这个值...任何想法我都缺少这里吗?

1 个答案:

答案 0 :(得分: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。