在django rest框架中过滤嵌套的序列化程序

时间:2015-03-10 07:18:21

标签: django django-rest-framework

我正在使用django rest框架在django中构建一个序列化程序。我需要过滤嵌套模型的查询集。

我找到How do you filter a nested serializer in Django Rest Framework?,似乎有答案,但是当我实施它时,我的数据没有变化。我能看到的唯一区别是引用过滤列表序列化程序的序列化程序也有其他字段。

模型(为清晰起见缩写):

class GCUser(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()
    is_member = models.BooleanField(default=False)
    age = models.SmallIntegerField(blank=True, null=True)
    session_key = models.CharField(max_length=100, db_index=True, blank=True, null=True)


class Connection(models.Model):
    creation_date = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(GCUser, related_name='user_connection')
    event = models.ForeignKey(Event, related_name='event_connection')
    role = models.CharField(max_length=8, choices=constants.Roles.ROLE_CHOICES,)

class Event(Game):
    creation_date = models.DateTimeField(auto_now_add=True)
    public = models.BooleanField(default=False)
    start_time = models.DateTimeField(null=True, blank=True)
    end_time = models.DateTimeField(null=True, blank=True)
    gm_is_player = models.BooleanField(default=False,
                                       help_text='Check if GM will be playing the game',
                                       verbose_name='GM is a player')
    gm_is_designer = models.BooleanField(default=False, help_text='Check if GM designed the game')
    user_notes = models.TextField(blank=True, default='', verbose_name='Note to Scheduler')
    scheduler_notes = models.TextField(blank=True, default='')
    experience = models.CharField(max_length=3, choices=constants.ExpLevels.EXPERIENCE_CHOICES,
                                  default=constants.ExpLevels.NOVICE,)
    status = models.CharField(max_length=4, db_index=True,
                              choices=constants.Status.STATUS_CHOICES,)

这是我的代码:

class FilteredListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        data = data.filter(status=constants.Status.ASSIGNED).order_by('start_time')
        return super(FilteredListSerializer, self).to_representation(data)


class UserEventSerializer(serializers.ModelSerializer):
    class Meta:
        list_serializer_class = FilteredListSerializer
        model = models.Event
        fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time')


class UserConnectionSerializer(serializers.ModelSerializer):
    event = UserEventSerializer()

    class Meta:
        model = models.Connection
        fields = ('get_role_display', 'conflict_type', 'event')


class GCUserSerializer(serializers.ModelSerializer):
    user_connection = UserConnectionSerializer(many=True)

    class Meta:
        model = models.GCUser
        fields = ('pk', 'first_name', 'last_name', 'email',
                  'is_member', 'age', 'user_connection')

PyCharm告诉我"类FilteredListSerializer必须实现所有抽象方法"但它实际上并没有抛出错误。我在列表序列化器的第一行放了一个断点,但它没有被触发。

我使用Python 3.4和django 1.7。

提前感谢您的帮助。

编辑添加:查看序列化代码,我意识到可能是关键区别:我的电话有many=True,而上一篇文章没有。{我尝试取出model=,但正如预期的那样抛出一个错误,显然"工作"早期帖子中的代码实际上并没有按照书面形式运行。

1 个答案:

答案 0 :(得分:1)

所以我不确定如何使用您正在使用的方法,但是,如果我正确理解您的问题,我相信您可以这样做:

  class UserEventSerializer(serializers.ModelSerializer):
    class Meta:
      model = models.Event
      fields = ('id', 'event_name', 'conflict_type', 'start_time', 'end_time')

  class UserConnectionSerializer(serializers.ModelSerializer):
    event = serializers.SerializerMethodField()

    class Meta:
        model = models.Connection
        fields = ('get_role_display', 'conflict_type', 'event')

    def get_event(self, obj):
      if obj.event.status == constants.Status.ASSIGNED:
        serializer = UserEventSerializer(obj.event)
        return serializer.data
      else:
        serializer = UserEventSerializer(None)
        return serializer.data

N.B。这假设您尝试在未分配状态时排除事件序列化。

我希望这会有所帮助。如果我不明白这个问题,请告诉我。