'RelatedManager'对象在DRF Serializer中没有属性'pk'

Chr*_*son 4 django django-rest-framework

这是我的(简化)models.py:

class MyList(models.Model):
    title = models.CharField(max_length=40)
    participants = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        through='ParticipantsInList',
        related_name='participants',
    )

class ParticipantsInList(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='user')
    list_parent = models.ForeignKey(MyList, related_name='list_parent')
    moderator = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)

和我的serializers.py:

class ParticipantsInListSerializer(serializers.ModelSerializer):

    class Meta:
        model = ParticipantsInList
        exclude = ('id',)
Run Code Online (Sandbox Code Playgroud)

和我的views.py:

class ParticipantsInListView(generics.ListCreateAPIView):
serializer_class = ParticipantsInListSerializer

def get_queryset(self):
    list_id = self.kwargs['list_pk']
    # This works:
    # return ParticipantsInList.objects.filter(list_parent=list_id)
    # While this doesn't:
    return MyList.objects.get(pk=list_id).participants.all()
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么在views.py中使用它:ParticipantsInList.objects.filter(list_id = list_id)工作,而使用List.objects.get(pk = list_id).participants.all()引发异常'RelatedManager'对象没有属性'pk'.

我想使用后者,因为我觉得它更好看,也因为我相信它应该工作..

Chr*_*son 6

问题是我试图序列化直通模型,如果查询是在直通模型本身上运行的话(如使用过滤器的情况那样).但是当在MyList中使用ManyToManyField进行查询时,只返回实际的用户对象.因此,在引用ManyToManyField时,解决方案是使用可以序列化用户对象的序列化程序,而不是通过模型.

在shell中运行查询可以证明这一点:

> ParticipantsInList.objects.filter(list_parent=1)
[<ParticipantsInList: ParticipantsInList object>, <ParticipantsInList: ParticipantsInList object>]
Run Code Online (Sandbox Code Playgroud)

运行其他查询时返回:

> MyList.objects.get(pk=1).participants.all()
[<MyUser: user1>, <MyUser: user2>]
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,非常有帮助 - 不确定它是否适用于这种情况,但我的嵌套序列化器需要用`many = True调用 (3认同)