【问题标题】:Filter on nested serializer in django rest framework在 django rest 框架中过滤嵌套的序列化程序
【发布时间】:2015-05-11 13:20:42
【问题描述】:

我正在使用 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=,但正如预期的那样抛出了一个错误,所以很明显之前帖子中的“工作”代码实际上并没有按所写的那样运行。

【问题讨论】:

  • 从您的示例看来,似乎没有嵌套用于序列化的模型。你能解释一下你想要过滤和序列化的相关模型吗?
  • 我已经编辑了 OP 以包含模型和整个序列化器链。
  • 我刚才也遇到了同样的问题。最初,当我编写序列化程序时,抽象警告不存在,但今天它存在。我不知道它是如何修复的,但我在 pycharm 上运行了无效缓存并重新启动,警告消失了..

标签: django django-rest-framework


【解决方案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

注意这假定如果未分配事件的状态,您正试图将事件排除在序列化之外。

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

【讨论】:

  • 遗憾的是,我仍然看到状态不是已分配的事件。我认为你理解这个问题。我可以看到你的代码打算做什么,这就是我想要的。
  • 再看一遍,我意识到我错过了您提出的更改之一。放入导致如下: 异常类型:AssertionError 异常值:在序列化器'UserConnectionSerializer'中的SerializerMethodField'event'上指定'get_event'是多余的,因为它与默认方法名称相同。删除“method_name”参数。
  • 我编辑了答案以删除“method_name”参数,这些更改是否有效?
  • 它运行正常,但它仍然显示所有未分配但所有字段为空的事件。我取出了 else 子句,用 None 调用序列化程序,如果未分配事件,则返回 None 那些事件仍然显示,但事件为 None 而不是一个充满空值的对象。这并不理想,但它是一种改进。现在,如果我能按开始时间对它们进行排序...
猜你喜欢
  • 2016-05-14
  • 2020-03-21
  • 2019-12-23
  • 2021-06-23
  • 2018-12-13
  • 2015-08-14
  • 2015-03-25
  • 1970-01-01
  • 2015-07-20
相关资源
最近更新 更多