【问题标题】:How to change the root element and list-item elements name? (django-rest-framework)如何更改根元素和列表项元素名称? (django-rest-framework)
【发布时间】:2014-04-28 16:54:57
【问题描述】:

我是 django-rest-framework 的新手,我有类似的工作示例

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

我需要的是

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

【问题讨论】:

  • 您的问题是什么?你试过什么?显示一些代码。
  • 此时我只知道我需要的输出,我需要帮助来指出我实现该输出的正确方向。这是删除 标记并替换为我的自定义,还删除默认 并使用 我的自定义。谢谢

标签: python django django-rest-framework


【解决方案1】:

本着对搜索此内容的任何其他人有所帮助的精神...以下是如何将 XMLRenderer 子类化并覆盖根标记(以前是“根”)和项目标记(以前是“列表项”)以随心所欲。

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))

【讨论】:

  • 什么是 smart_text?
【解决方案2】:

如果您希望一般地执行此操作,则不需要覆盖太多的类:

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

    root_tag_name = 'file'
    item_tag_name = 'instance'

【讨论】:

  • 谢谢,很好的回答。
【解决方案3】:

我认为您不需要创建一个完整的子类,我可以通过在创建实例之后和运行渲染之前覆盖实例变量来做到这一点,见下文:

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

希望对遇到的人有所帮助

【讨论】:

    【解决方案4】:

    这些是硬编码的值,因此您唯一的机会是通过覆盖 XMLRenderer(实际上几乎是整个类)来创建自定义渲染器,并在您的视图中使用该自定义渲染器。

    【讨论】:

      【解决方案5】:

      对于任何想要编辑实际包的人,您可以转到您的 Python 文件夹、站点包、rest_framework_xml 并编辑 renderers.py

      到达那里后,您可以编辑: item_tag_name = 'list-item' 并将其更改为 item_tag_name = 'item'

      注意: 通过执行此方法,您将覆盖实际的类。对于我的项目,没关系,但是如果你打算将 xml 库用于另一个 Django 项目,请记住这一点。

      【讨论】:

        猜你喜欢
        • 2018-05-06
        • 1970-01-01
        • 1970-01-01
        • 2013-09-17
        • 2017-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        相关资源
        最近更新 更多