Как изменить root и имя списка элементов в XML API в представлении django - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь изменить root и имя элементов списка в соответствии с требованиями API. Я не хочу изменять класс XMLRenderer в renderer.py, потому что я мог бы использовать его снова, я просто хочу использовать представление для настройки.

Ниже приведены классы сериализатора, класс представления и выходные данные

класс сериализатора

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = TypeCategory
        fields = '__all__'


class ZoneSerializer(serializers.ModelSerializer):
    type = CategorySerializer(many=True, read_only=True)

    class Meta:
        model = Type
        fields = ('TypeDesc', 'type')

в представлении

class ZoneLists(APIView):
    renderer_classes = (JSONRenderer, XMLRenderer)

    def get(self, request):
        zone1 = Type.objects.all()

        serializer = ZoneSerializer(zone1, many=True)
        return Response(serializer.data)

Вывод

<root>
 <list-item>
  <TypeDesc>NORMAL</TypeDesc>
  <type>
   <list-item>
    <id>5</id>
    <Category>Normal</Category>
    <Type>1</Type>
   </list-item>
  </type>
 </list-item>
 <list-item>
  <TypeDesc>ZONES</TypeDesc>
  <type>
   <list-item>
    <id>9</id>
    <Category>Zone manager</Category>
    <Type>4</Type>
   </list-item>
   <list-item>
    <id>10</id>
    <Category>zone officials</Category>
    <Type>4</Type>
   </list-item>
  </type>
 </list-item>
</root>

1 Ответ

0 голосов
/ 30 апреля 2020

Расширьте XMLRenderer в файле renderer.py в вашем проекте и перезапишите root_tag_name и item_tag_name следующим образом:

from rest_framework_xml.renderers import XMLRenderer


class MyXMLRenderer(XMLRenderer):
    """Custom root renderer which serializes to XML"""
    root_tag_name = "my-custom-root"
    item_tag_name = "my-item-tag"

    def _to_xml(self, xml, data):
        """
        Print list inside dict with tag name = key associated to the list
        e.g. 
            my_list = ['a','b','c']
            my_dict = {'my_element': my_list}
        will be rendered as:
            <my_element>a</my_element>
            <my_element>b</my_element>
            <my_element>c</my_element>
        """
        if isinstance(data, dict):
            for key, value in data.items():
                if isinstance(value, (list, tuple)):
                    for item in value:
                        xml.startElement(key, {})
                        self._to_xml(xml, item)
                        xml.endElement(key)
                else:
                    xml.startElement(key, {})
                    self._to_xml(xml, value)
                    xml.endElement(key)
        else:
            super()._to_xml(xml, data)

Не стесняйтесь добавлять или удалять части производного класса.

...