'xml attributes instead child elements
Using djangorestframework-xml, can someone please help me how to render child elements as attributes?
Following the example below
<CreateCustomerAndMortgage>
<Identifier>
<UniqueID>182419002</UniqueID>
<Type>BrokerAssigned</Type>
</Identifier>
</CreateCustomerAndMortgage>
it should become
<CreateCustomerAndMortgage>
<Identifier UniqueID="182419002" Type="BrokerAssigned"/>
</CreateCustomerAndMortgage>
I was hoping I could setup something on the serializers instead overriding the XMLRenderer. Note: I know that attributes is not industry standards, but I have received the xsd already and unfortunately I'm not in power to change it.
This is my serializer
class Identifier(serializers.Serializer):
unique_id = serializers.CharField()
type = serializers.CharField()
Solution 1:[1]
You can achieve this using a custom renderer class overrides _to_xml
method of XMLRenderer
class, like this:
# 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={})
and use the custom renderer in the settings.py
:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework_xml.parsers.XMLParser',
),
'DEFAULT_RENDERER_CLASSES': (
'example_app.renderers.XmlAttributesRenderer',
),
}
or in you view class:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
renderer_classes = (XmlAttributesRenderer,)
sample responses:
/api/users
<root>
<list-item email="[email protected]" is_staff="True" url="http://127.0.0.1:8000/api/users/1/" username="admin"/>
</root>
/api/users/1
<root>
<data email="[email protected]" is_staff="True" url="http://127.0.0.1:8000/api/users/1/" username="admin"/>
</root>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |