Django вложил фильтр сериализатора только в одно поле, а не во все поля - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть два сериализатора, как показано ниже. Выходные данные для приведенного ниже фрагмента: «Рабочие» и со связанными данными счетчика билетов со всеми полями (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)

Что выше выводимых фрагментов

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

            }
        ]
 }

Но я хочу

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

Мне просто нужно имя ticket_counter_name. В моем случае не может быть двух счетчиков ticket_counter для работника. Очевидно, это дает только один 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)

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Если я правильно понял, вам нужен только SerializerMethodField для выполнения фильтрации и представления строки .

class WorkerSerializer(serializers.ModelSerializer):
    <b>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</b>

    class Meta:
        model = User
        fields = ('username', 'ticket_counter',)
0 голосов
/ 01 сентября 2018

Вы можете использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...