Пользовательский запрос к сериализатору или из него в djang rest framework

#django #django-rest-framework

#django #django-rest-framework

Вопрос:

Учитывая, что у меня есть это перечисление в моей модели:

 MEDIA_TYPES = (
        ('A', 'Acrylic'),
        ('W', 'Watercolor'),
        ('MM', 'Multimedia'),
        ('G', 'Gouache'),
        ('O', 'Oil'),
        ('P', 'Pencil'),
        ('C', 'Charcoal'),
        ('PS', 'Pastel'),
        ('CO', 'Conte Crayon'),
    )
 

Они могут быть выбраны для объектов оформления в моем администраторе. Я хочу создать сериализованный json только для тех, которые используются. Допустим, у меня есть несколько объектов, но они используют только акварель, масло и уголь, а не другие материалы. Как мне вернуть объект, который выглядит следующим образом:

 [
  {
    "W": "Watercolor"
  },
  {
    "O": "Oil"
  },
  {
    "C": "Charcoal"
  }
]
 

Мой сериализатор:

 class MediaTypeSerializer (serializers.ModelSerializer):

    media_display = serializers.CharField(source='get_media_display')

    class Meta:
        model = Artwork
        fields = ['media', 'media_display']
 

Мое мнение:

 class ArtworkMediaTypes(generics.ListAPIView):
    serializer_class = MediaTypeSerializer

    def get_queryset(self):
        """
        Get unique media types from objects
        """
        # queryset = Artwork.objects.all()
        queryset = Artwork.objects.all()
        return queryset
```
What I am getting:

 

[
{
«media»: «MM»,
«media_display»: «Мультимедиа»
},
{
«media»: «MM»,
«media_display»: «Мультимедиа»
},
{
«медиа»: «ММ»,
«media_display»: «Мультимедиа»
},
{
«media»: «MM»,
«media_display»: «Мультимедиа»
},
{
«media»: «C»,
«media_display»: «Древесный уголь»
}
]

 
I want to have it only list the unique, not multiple. I won't know from what site each will select, so I am trying to build a menu in the nextjs front end from what was put in in the backend.
 

Комментарии:

1. Будет лучше, если вы опубликуете свой сериализатор. Чтобы отфильтровать, вы можете сделать [x for x in MEDIA_TYPES if x[0] in ['W', 'O', 'C']]

2. Я обновил. Я не буду знать, какие значения будут выбраны, поэтому я не знаю, выбраны ли «W» или «O», это всего лишь примеры. Это сайт django для ввода иллюстраций, и с иллюстрациями связан тип носителя. Итак, во внешнем интерфейсе я хочу перебирать значения, которые были введены для меню фильтра.

3. Вы можете определить свойство в своих моделях. py, который вернет только W, O, C варианты выбора и передаст его в media_display ‘s source .

Ответ №1:

Метод сериализатора rest Framework to_representation позволяет форматировать json.

 class MediaTypeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Artwork
        fields = ['media']

    def to_representation(self, value):
        return {value.media: value.get_media_display()}
 

выводит:

 [
    {
        "C": "Charcoal"
    },
    {
        "G": "Gouache"
    },
    {
        "MM": "Multimedia"
    }
]
 

Чтобы удалить дубликаты, метод distinct('media') on эффективно выполняет это на уровне БД. * ОБРАТИТЕ внимание, что эта функциональность недоступна в sqlite.

 class ArtworkMediaTypes(generics.ListAPIView):
    serializer_class = MediaTypeSerializer

    def get_queryset(self):
        """
        Get unique media types from objects
        """
        queryset = Artwork.objects.all().order_by('media').distinct('media')

        return queryset
 

Комментарии:

1. Спасибо. Я использую postgres и получаю эту ошибку при использовании distinct: ВЫБОР DISTINCT В выражениях должен соответствовать первоначальному порядку выражений СТРОКА 1: ВЫБЕРИТЕ DISTINCT В («artwork_artwork».»media») «artwork_artw…

2. Я обновил пример, чтобы включить предложение order_by.

3. Спасибо. Это было так.