Django RestFramework组由

ePa*_*oal 11 xml django json django-rest-framework

我的问题与Django RestFramework有关,关于如何对元素进行分组.

这是我的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')
Run Code Online (Sandbox Code Playgroud)

以下json是实际结果:

{"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"
            }
        ]}
Run Code Online (Sandbox Code Playgroud)

你可以注意到"kwdGroup"是一个重复的元素,我要分组.

我想按kwdGroup分组

{"A":[
       {
        "id": 5,
        "term_word": "word1",
        "meaning": "Text1"
        },
        {
        "id": 6,
        "term_word": "word2",
        "meaning": "Text2"
        },
        {
        "id": 7,
        "term_word": "word3",
        "meaning": "Text3"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找关于api指南的http://www.django-rest-framework.org/的答案,但我很难找到一种方法来引导它.你有同样的问题吗?你有什么建议我怎么办?你有任何使用Django RestFramework处理元素分组的例子吗?

提前致谢.

Cry*_*tal 6

让我们假设该kwdGroup字段是与名为 的模型的关系字段KeyWordGroup

默认ListSerializer使用该to_representation方法来呈现序列化对象的列表rest_framework

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
        ]
Run Code Online (Sandbox Code Playgroud)

我们可以修改ListSerializer以对结果进行分组,例如:

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()
        }
Run Code Online (Sandbox Code Playgroud)

然后我们可以使用修改VocabListSerializer后的VocabSerializer.

class VocabSerializer(serializers.Serializer):
...
    class Meta:
        list_serializer_class = VocabListSerializer
Run Code Online (Sandbox Code Playgroud)


Rex*_*ury 3

实现此目的的一种方法是使用SerializerMethodField。下面的内容可能与您的用例略有不同,但您可以相应地采用。还有其他方法可以实现此目的,包括覆盖to_representation方法,但它们更多地依赖于扰乱 DRF 的内部工作方式,而不是此处相关的。

模型.py

class Dictionary(Model):
    id = PrimaryKey


class Word(Model):
    dictionary = ForeignKey(Dictionary, related_name='words')
    word = Charfield()
    group = Charfield()
Run Code Online (Sandbox Code Playgroud)

序列化器.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')
Run Code Online (Sandbox Code Playgroud)

一个例子

>>> 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'
    },
}
Run Code Online (Sandbox Code Playgroud)

  • 你能在动态数量的不同群体中完成这项工作吗? (11认同)