aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarko Tibold2012-01-13 12:36:02 -0800
committerMarko Tibold2012-01-13 12:36:02 -0800
commitc204101563bce0997e46ad5381d6d410f570b233 (patch)
tree99e3ef2b2bd00ac6b5fbf0579f2989f868cdc6cf
parentc71b6fb090b7a225869526b1d75d7e850e85c282 (diff)
parent21776c0de2eca3d66534817b3f5a258a6fc1fc2f (diff)
downloaddjango-rest-framework-c204101563bce0997e46ad5381d6d410f570b233.tar.bz2
Merge pull request #125 from michelelazzeri-nextage/master
application/xml parser fully compatible with application/xml render
-rw-r--r--djangorestframework/parsers.py30
-rw-r--r--djangorestframework/tests/parsers.py41
-rw-r--r--djangorestframework/tests/renderers.py124
3 files changed, 96 insertions, 99 deletions
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py
index c218e5ee..b99423a0 100644
--- a/djangorestframework/parsers.py
+++ b/djangorestframework/parsers.py
@@ -187,13 +187,33 @@ class XMLParser(BaseParser):
`data` will simply be a string representing the body of the request.
`files` will always be `None`.
"""
- data = {}
tree = ET.parse(stream)
- for child in tree.getroot().getchildren():
- data[child.tag] = self._type_convert(child.text)
-
+ data = self._xml_convert(tree.getroot())
+
return (data, None)
-
+
+ def _xml_convert(self, element):
+ """
+ convert the xml `element` into the corresponding python object
+ """
+
+ children = element.getchildren()
+
+ if len(children) == 0:
+ return self._type_convert(element.text)
+ else:
+ # if the fist child tag is list-item means all children are list-item
+ if children[0].tag == "list-item":
+ data = []
+ for child in children:
+ data.append(self._xml_convert(child))
+ else:
+ data = {}
+ for child in children:
+ data[child.tag] = self._xml_convert(child)
+
+ return data
+
def _type_convert(self, value):
"""
Converts the value returned by the XMl parse into the equivalent
diff --git a/djangorestframework/tests/parsers.py b/djangorestframework/tests/parsers.py
index e4e7e09a..5bd4aad3 100644
--- a/djangorestframework/tests/parsers.py
+++ b/djangorestframework/tests/parsers.py
@@ -156,10 +156,9 @@ class TestFormParser(TestCase):
self.assertEqual(Form(data).is_valid(), True)
-
class TestXMLParser(TestCase):
def setUp(self):
- self.input = StringIO(
+ self._input = StringIO(
'<?xml version="1.0" encoding="utf-8"?>'
'<root>'
'<field_a>121.0</field_a>'
@@ -168,15 +167,45 @@ class TestXMLParser(TestCase):
'<field_d>2011-12-25 12:45:00</field_d>'
'</root>'
)
- self.data = {
+ self._data = {
'field_a': 121,
'field_b': 'dasd',
'field_c': None,
'field_d': datetime.datetime(2011, 12, 25, 12, 45, 00)
}
-
+ self._complex_data_input = StringIO(
+ '<?xml version="1.0" encoding="utf-8"?>'
+ '<root>'
+ '<creation_date>2011-12-25 12:45:00</creation_date>'
+ '<sub_data_list>'
+ '<list-item><sub_id>1</sub_id><sub_name>first</sub_name></list-item>'
+ '<list-item><sub_id>2</sub_id><sub_name>second</sub_name></list-item>'
+ '</sub_data_list>'
+ '<name>name</name>'
+ '</root>'
+ )
+ self._complex_data = {
+ "creation_date": datetime.datetime(2011, 12, 25, 12, 45, 00),
+ "name": "name",
+ "sub_data_list": [
+ {
+ "sub_id": 1,
+ "sub_name": "first"
+ },
+ {
+ "sub_id": 2,
+ "sub_name": "second"
+ }
+ ]
+ }
+
def test_parse(self):
parser = XMLParser(None)
- (data, files) = parser.parse(self.input)
- self.assertEqual(data, self.data)
+ (data, files) = parser.parse(self._input)
+ self.assertEqual(data, self._data)
+
+ def test_complex_data_parse(self):
+ parser = XMLParser(None)
+ (data, files) = parser.parse(self._complex_data_input)
+ self.assertEqual(data, self._complex_data)
diff --git a/djangorestframework/tests/renderers.py b/djangorestframework/tests/renderers.py
index e80f0f20..142791e4 100644
--- a/djangorestframework/tests/renderers.py
+++ b/djangorestframework/tests/renderers.py
@@ -6,7 +6,7 @@ from djangorestframework.views import View
from djangorestframework.compat import View as DjangoView
from djangorestframework.renderers import BaseRenderer, JSONRenderer, YAMLRenderer, \
XMLRenderer, JSONPRenderer, DocumentingHTMLRenderer
-from djangorestframework.parsers import JSONParser, YAMLParser
+from djangorestframework.parsers import JSONParser, YAMLParser, XMLParser
from djangorestframework.mixins import ResponseMixin
from djangorestframework.response import Response
@@ -283,72 +283,6 @@ if YAMLRenderer:
self.assertEquals(obj, data)
-class XMLRendererTestCase(TestCase):
- """
- Tests specific to the XML Renderer
- """
-
- def test_render_string(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 'astring'}, 'application/xml')
- self.assertXMLContains(content, '<field>astring</field>')
-
- def test_render_integer(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 111}, 'application/xml')
- self.assertXMLContains(content, '<field>111</field>')
-
- def test_render_datetime(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({
- 'field': datetime.datetime(2011, 12, 25, 12, 45, 00)
- }, 'application/xml')
- self.assertXMLContains(content, '<field>2011-12-25 12:45:00</field>')
-
- def test_render_float(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': 123.4}, 'application/xml')
- self.assertXMLContains(content, '<field>123.4</field>')
-
- def test_render_decimal(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': Decimal('111.2')}, 'application/xml')
- self.assertXMLContains(content, '<field>111.2</field>')
-
- def test_render_none(self):
- """
- Test XML rendering.
- """
- renderer = XMLRenderer(None)
- content = renderer.render({'field': None}, 'application/xml')
- self.assertXMLContains(content, '<field></field>')
-
- def assertXMLContains(self, xml, string):
- self.assertTrue(xml.startswith('<?xml version="1.0" encoding="utf-8"?>\n<root>'))
- self.assertTrue(xml.endswith('</root>'))
- self.assertTrue(string in xml, '%r not in %r' % (string, xml))
-
-class HTMLView(View):
- renderers = (DocumentingHTMLRenderer)
-
- def get(self, request, **kwargs):
- return 'text'
-
urlpatterns += patterns('',
url(r'^/html$', HTMLView.as_view()),
)
@@ -429,6 +363,21 @@ class XMLRendererTestCase(TestCase):
Tests specific to the XML Renderer
"""
+ _complex_data = {
+ "creation_date": datetime.datetime(2011, 12, 25, 12, 45, 00),
+ "name": "name",
+ "sub_data_list": [
+ {
+ "sub_id": 1,
+ "sub_name": "first"
+ },
+ {
+ "sub_id": 2,
+ "sub_name": "second"
+ }
+ ]
+ }
+
def test_render_string(self):
"""
Test XML rendering.
@@ -478,30 +427,29 @@ class XMLRendererTestCase(TestCase):
renderer = XMLRenderer(None)
content = renderer.render({'field': None}, 'application/xml')
self.assertXMLContains(content, '<field></field>')
-
- def assertXMLContains(self, xml, string):
- self.assertTrue(xml.startswith('<?xml version="1.0" encoding="utf-8"?>\n<root>'))
- self.assertTrue(xml.endswith('</root>'))
- self.assertTrue(string in xml, '%r not in %r' % (string, xml))
-
-
-
-class Issue122Tests(TestCase):
- """
- Tests that covers #122.
- """
-
- urls = 'djangorestframework.tests.renderers'
-
- def test_only_html_renderer(self):
+
+ def test_render_complex_data(self):
"""
- Test if no recursion occurs.
+ Test XML rendering.
"""
- resp = self.client.get('/html')
+ renderer = XMLRenderer(None)
+ content = renderer.render(self._complex_data, 'application/xml')
+ self.assertXMLContains(content, '<sub_name>first</sub_name>')
+ self.assertXMLContains(content, '<sub_name>second</sub_name>')
- def test_html_renderer_is_first(self):
+ def test_render_and_parse_complex_data(self):
"""
- Test if no recursion occurs.
+ Test XML rendering.
"""
- resp = self.client.get('/html1')
+ renderer = XMLRenderer(None)
+ content = StringIO(renderer.render(self._complex_data, 'application/xml'))
+
+ parser = XMLParser(None)
+ complex_data_out, dummy = parser.parse(content)
+ error_msg = "complex data differs!IN:\n %s \n\n OUT:\n %s" % (repr(self._complex_data), repr(complex_data_out))
+ self.assertDictEqual(self._complex_data, complex_data_out, error_msg)
+ def assertXMLContains(self, xml, string):
+ self.assertTrue(xml.startswith('<?xml version="1.0" encoding="utf-8"?>\n<root>'))
+ self.assertTrue(xml.endswith('</root>'))
+ self.assertTrue(string in xml, '%r not in %r' % (string, xml)) \ No newline at end of file