How to change the root element and list-item eleme

2019-08-02 23:43发布

I am new to django-rest-framework i have working sample like

<root>
    <list-item>worrier1</list-item>
    <list-item>worrier2</list-item>
<root>

What i need is

<Hero>
    <worrier1>worrier1</worrier1>
    <worrier2>worrier2</worrier2>
<Hero>

5条回答
啃猪蹄的小仙女
2楼-- · 2019-08-03 00:13

If you wish to do this generically you don't need to override too much of the class:

class MyXMLRenderer(XMLRenderer):
    """Override XML tag names."""

    root_tag_name = 'file'
    item_tag_name = 'instance'
查看更多
Animai°情兽
3楼-- · 2019-08-03 00:14

Those are hardcoded values, so the only chance you get, is to create custom renderer by overriding the XMLRenderer (which in effect would be pretty much the whole class) and use that custom renderer in your view.

查看更多
萌系小妹纸
4楼-- · 2019-08-03 00:25

I don't think you need to go so far as to create a whole subclass, I was able to do it by overriding the instance variables after creating the instance and before running render, see below:

renderer = XMLRenderer()
renderer.item_tag_name = 'warrior'
renderer.root_tag_name = 'Hero'
content = renderer.render(serializer.data)

Hope that helps anyone else who stumbles by

查看更多
看我几分像从前
5楼-- · 2019-08-03 00:26

In the spirit of being helpful to anyone else who searches for this... Below is how you can subclass the XMLRenderer and override the root tag (previously "root") and item tags (previously "list-item") to whatever you like.

from django.utils.six.moves import StringIO
from django.utils.xmlutils import SimplerXMLGenerator
from rest_framework_xml.renderers import XMLRenderer

class ModifiedXMLRenderer(XMLRenderer):
    item_tag_name = "item"
    root_tag_name = "channel"

    def render(self, data, accepted_media_type=None, renderer_context=None):
        """
        Renders `data` into serialized XML.
        """
        if data is None:
            return ''

        stream = StringIO()

        xml = SimplerXMLGenerator(stream, self.charset)
        xml.startDocument()
        xml.startElement(self.root_tag_name, {})

        self._to_xml(xml, data)

        xml.endElement(self.root_tag_name)
        xml.endDocument()
        return stream.getvalue()

    def _to_xml(self, xml, data):
        if isinstance(data, (list, tuple)):
            for item in data:
                xml.startElement(self.item_tag_name, {})
                self._to_xml(xml, item)
                xml.endElement(self.item_tag_name)

        elif isinstance(data, dict):
            for key, value in six.iteritems(data):
                xml.startElement(key, {})
                self._to_xml(xml, value)
                xml.endElement(key)

        elif data is None:
            # Don't output any value
            pass

        else:
            xml.characters(smart_text(data))
查看更多
Ridiculous、
6楼-- · 2019-08-03 00:28

For anyone who wants to edit the actual package, you can go to your Python folder, site-packages, rest_framework_xml, and edit renderers.py

When you get there, you can edit: item_tag_name = 'list-item' and change this to item_tag_name = 'item'

Note: By doing this method, you are overriding the actual class. For my project, it does not matter, but if you intend to use the xml library for another Django project, just keep this in mind.

查看更多
登录 后发表回答