XML属性代替子元素



使用djangorestframework-xml,有人能帮助我如何渲染子元素作为属性吗?

下面的例子

<CreateCustomerAndMortgage>
<Identifier>
<UniqueID>182419002</UniqueID>
<Type>BrokerAssigned</Type>
</Identifier>
</CreateCustomerAndMortgage>

应该变成

<CreateCustomerAndMortgage>
<Identifier UniqueID="182419002" Type="BrokerAssigned"/>
</CreateCustomerAndMortgage>

我希望我可以在序列化器上设置一些东西,而不是覆盖XMLRenderer。注意:我知道属性不是行业标准,但我已经收到了xsd,不幸的是我没有权力改变它。

这是我的序列化器

class Identifier(serializers.Serializer):
unique_id = serializers.CharField()
type = serializers.CharField()

您可以使用自定义渲染器类覆盖XMLRenderer类的_to_xml方法来实现这一点,如下所示:

# renderers.py in example_app 
from django.utils.encoding import force_str
from rest_framework_xml.renderers import XMLRenderer

class XmlAttributesRenderer(XMLRenderer):
"""
Renderer which serializes data to XML attributes.
"""
def _to_xml(self, xml, data):
# render the data to xml how you'd like
# ...
# use xml.addQuickElement('name_of_xml_tag', attrs={'attr1': 'value_of_attr1'})
has_xml_tag = False
if isinstance(data, (list, tuple)):
for item in data:
has_xml_tag = True
xml.addQuickElement(self.item_tag_name, attrs=self._to_xml(xml, item))
elif isinstance(data, dict):
dict_data = dict(map(lambda di: (force_str(di[0]), force_str(self._to_xml(xml, di[1]))), data.items()))
if has_xml_tag:
return dict_data
else:
has_xml_tag = True
xml.addQuickElement('data', attrs=dict_data)
elif data is None:
return ''
else:
return force_str(data)
if not has_xml_tag:
xml.addQuickElement('data', attrs={})

和使用自定义渲染器在settings.py:

REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework_xml.parsers.XMLParser',
),
'DEFAULT_RENDERER_CLASSES': (
'example_app.renderers.XmlAttributesRenderer',
),
}

或者在视图类中:

class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
renderer_classes = (XmlAttributesRenderer,)

示例响应:

/api/users

<root>
<list-item email="admin@example.com" is_staff="True" url="http://127.0.0.1:8000/api/users/1/" username="admin"/>
</root>

/api/users/1

<root>
<data email="admin@example.com" is_staff="True" url="http://127.0.0.1:8000/api/users/1/" username="admin"/>
</root>

最新更新