Django RestFramework Group by

My problem is with Django RestFramework and describes how to group elements.

This is my serializers.py

from collaborativeAPP.models import * from rest_framework import serializers class VocabSerializer(serializers.ModelSerializer): term_word = serializers.CharField(source='term.word',read_only=True) kwdGroup = serializers.StringRelatedField() class Meta: model = Vocab fields = ('id','term_word', 'meaning','kwdGroup') class TermSerializer(serializers.ModelSerializer): word = serializers.CharField(read_only=True) class Meta: model = Term fields = ('url', 'word') 

The following json is the actual result:

 {"results":[ { "id": 5, "term_word": "word1", "meaning": "Text1" "kwdGroup": "A" }, { "id": 6, "term_word": "word2", "meaning": "Text2" "kwdGroup": "A" }, { "id": 7, "term_word": "word3", "meaning": "Text3" "kwdGroup": "A" } ]} 

As you can see, "kwdGroup" is a repeating element that I have to group.

I would like to group by kwdGroup

 {"A":[ { "id": 5, "term_word": "word1", "meaning": "Text1" }, { "id": 6, "term_word": "word2", "meaning": "Text2" }, { "id": 7, "term_word": "word3", "meaning": "Text3" } ] } 

I am looking for answers at http://www.django-rest-framework.org/ in the api manual, but I am having difficulty finding an approach to it. Do you share the same problem? Do you have any suggestion on how I can do this? Do you have an example that concerns grouping elements using Django RestFramework?

Thanks in advance.

+6
source share
3 answers

Suppose the kwdGroup field is a model relationship field called KeyWordGroup .

By default, the ListSerializer uses the to_representation method to display a list of rest_framework serialized objects:

 class ListSerializer(BaseSerializer): ... def to_representation(self, data): """ List of object instances -> List of dicts of primitive datatypes. """ # Dealing with nested relationships, data can be a Manager, # so, first get a queryset from the Manager if needed iterable = data.all() if isinstance(data, models.Manager) else data return [ self.child.to_representation(item) for item in iterable ] 

We can modify the ListSerializer to group the results, for example:

 class VocabListSerializer(serializers.ListSerializer): def to_representation(self, data): iterable = data.all() if isinstance(data, models.Manager) else data return { kwdGroup: super().to_representation(Vocab.objects.filter(kwdGroup=kwdGroup)) for kwdGroup in KeyWordGroup.objects.all() } 

Then we can use the modified VocabListSerializer with the VocabSerializer .

 class VocabSerializer(serializers.Serializer): ... class Meta: list_serializer_class = VocabListSerializer 
+2
source

One way to achieve this is to use SerializerMethodField . The following may differ from your use case, but you can accept it accordingly. There are other ways to accomplish this, including rewriting to_representation methods, but they rely on clutter with the internal operation of DRF more than it matters.

models.py

 class Dictionary(Model): id = PrimaryKey class Word(Model): dictionary = ForeignKey(Dictionary, related_name='words') word = Charfield() group = Charfield() 

serializers.py

 class WordSerializer(serializers.ModelSerializer): word = serializers.CharField(read_only=True) class Meta: model = Word fields = ('word',) class DictionarySerializer(serializers.ModelSerializer): group_a = serializers.SerializerMethodField() group_b = serializers.SerializerMethodField() def get_group_a(self, instance): return WordSerializer(instance.words.filter(group='a'), many=True).data def get_group_b(self, instance): return WordSerializer(instance.words.filter(group='b'), many=True).data class Meta: model = Dictionary fields = ('group_a', 'group_b') 

Example

 >>> my_dictionary = Dictionary.objects.create() >>> Word.objects.bulk_create( Word(word='arrow', group='a' dictionary=my_dictionary), Word(word='apple', group='a' dictionary=my_dictionary), Word(word='baby', group='b' dictionary=my_dictionary), Word(word='banana', group='b' dictionary=my_dictionary) ) >>> serializer = DictionarySerializer(my_dictionary) >>> print serializer.data { 'group_a': { 'word': 'arrow', 'word': 'apple' }, 'group_b': { 'word': 'baby', 'word': 'banana' }, } 
+1
source

You can use "serializer relationships" and especially "nested relationships." See the documentation here

0
source

Source: https://habr.com/ru/post/989802/


All Articles