【问题标题】:Django nested Serializer filter to only one field, not all fieldsDjango 将 Serializer 过滤器嵌套到仅一个字段,而不是所有字段
【发布时间】:2018-09-01 17:05:40
【问题描述】:

我有两个如下所示的序列化程序。以下 sn-p 的输出是 Workers 以及与所有字段相关的 Ticket Counter 详细信息 (ticket_counter,ticket_counter_name,worker)。但我只需要一个字段ticket_counter_name

class WorkerSerializer(serializers.ModelSerializer):

    ticket_counter = WorkerToCounterSerializer(many=True, read_only=True)

    class Meta:
        model = User
        fields = (
                  'username',
                  'ticket_counter',
                  )

class WorkerToCounterSerializer(serializers.ModelSerializer):
    ticket_counter = SerializerMethodField()
    ticket_counter_name = serializers.CharField(source='ticket_counter.ticket_counter_name')

    class Meta:
        model = WorkerToTicketCounter
        list_serializer_class = FilteredListSerializer
        fields = (
            'ticket_counter',
            'ticket_counter_name',
            'worker',
        )

    def get_ticket_counter(self, obj):
        return obj.ticket_counter.pk

class FilteredListSerializer(ListSerializer):
    def to_representation(self, data):
        data = data.filter(worker_to_ticket_counter_is_deleted=False)[:1]
        return super(FilteredListSerializer, self).to_representation(data)

sn-p 上面的输出

{
        "username": "xxxxxxxxxxx",
        "ticket_counter": [
            {
                "ticket_counter": 7,
                "ticket_counter_name": "Entrance Counter",
                "worker": 4,

            }
        ]
 }

但我想要的是

 {
        "username": "xxxxxxxxxxx",
        "ticket_counter": "Entrance Counter"
 }

我只需要ticket_counter_name 的名称。就我而言,一个工人不能有两个ticket_counters。显然,它只给出了一个ticket_counter。可能吗?

编辑:使用字符串StringRelatedField

{
    "username": "xxxxxxxxxxx",
    "ticket_counter": [
          "Entrance Counter",
          "xxxxxxxxxxxxxxxx",
          "xxxxxxxxxxxxxxxx",
          "xxxxxxxxxxxxxxxx"
    ]
}

编辑:WorkerToTicketCounter 模型

class WorkerToTicketCounter(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    ticket_counter = models.ForeignKey(TicketCounter, related_name="workers")
    worker = models.ForeignKey(User, related_name='ticket_counter')
    worker_to_ticket_counter_is_deleted = models.BooleanField(default=False)

【问题讨论】:

  • 可以加WorkerToTicketCounter型号吗?
  • 您可以添加您在下面的答案中提到的 filter 的想法吗?
  • 我在谈论 FilteredListSerializer 过滤 worker_to_ticket_counter_is_deleted = False 。我已经添加了
  • 这意味着您需要显示具有worker_to_ticket_counter_is_deleted=FalseWorkerToTicketCounter 实例...对吗?
  • 是的。只有一个WorkerToTicketCounter 实例会在那里。与worker_to_ticket_counter_is_deleted=False。我能够做到。我已经在问题中提到了它。但我只需要 ticket_counter_name 。不是全部

标签: django django-models django-rest-framework django-serializer


【解决方案1】:

如果我理解正确,您只需要一个 SerializerMethodField 来执行 过滤字符串表示

class WorkerSerializer(serializers.ModelSerializer):
    ticket_counter = serializers.SerializerMethodField(read_only=True)

    def get_ticket_counter(self, user):
        qs = user.ticket_counter.filter(worker_to_ticket_counter_is_deleted=False)
        if qs.exists() and hasattr(qs.first().ticket_counter, 'ticket_counter_name'):
            return qs.first().ticket_counter.ticket_counter_name
        return None

    class Meta:
        model = User
        fields = ('username', 'ticket_counter',)

【讨论】:

【解决方案2】:

你可以使用StringRelatedField:

class WorkerSerializer(serializers.ModelSerializer):

    ticket_counter = StringRelatedField(many=True, read_only=True)

    class Meta:
        model = User
        fields = (
                  'username',
                  'ticket_counter',
                  )

注意要使用StringRelatedField,您应该将__str__ 方法添加到您的WorkerToTicketCounter 模型中:

class WorkerToTicketCounter:
    ...
    def __str__(self):
        return self.ticket_counter.ticket_counter_name

【讨论】:

  • __unicode__ 还是 __str__ ?但是,它是数组中每个 WorkerToTicketCounter 实例的结果字符串。我已经编辑了结果。
  • 我使用WorkerToCounterSerializer 的原因是我可以将FilteredListSerializer 中的它们过滤到一个实例中。但我只需要一个字段。
猜你喜欢
  • 1970-01-01
  • 2015-06-18
  • 2021-11-06
  • 2020-03-19
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多