Skip to content

Commit 5f84e15

Browse files
author
Mike Hearing
committed
Fixing endless recursion on RestQueryset
1 parent 7253a9f commit 5f84e15

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

pyrestorm/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,17 @@ def request(self, method, url, *args, **kwargs):
5353
self.status_code = self._response.status_code
5454

5555
# Handle exceptions
56-
self.raise_exception(self._response.status_code)
56+
self.raise_exception(self._response)
5757

5858
# No exceptions means we should return the response
5959
return self.parse_response(self._response)
6060

6161
# Codes which should not show up in a response for a valid request
62-
def raise_exception(self, status_code):
62+
def raise_exception(self, response):
63+
status_code = response.status_code
64+
content = response.content
65+
66+
# Process the different exceptions that could happen
6367
if status_code == StatusCodes.HTTP_SERVER_ERROR:
6468
raise ServerErrorException
6569
elif status_code == StatusCodes.HTTP_METHOD_NOT_ALLOWED:

pyrestorm/models.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from pyrestorm.client import RestClient
55
from pyrestorm.fields import Field, RelatedField
66
from pyrestorm.exceptions import orm as orm_exceptions
7+
from pyrestorm.query import RestQueryset
78
from pyrestorm.manager import RestOrmManager
89

910
primitives = [int, str, unicode, bool, type(None)]
@@ -178,36 +179,39 @@ def _serialize_data(self, obj, ref):
178179
if key.startswith('_') or self._get_reference_data(ref, key) == value:
179180
continue
180181

182+
# Check if the value can be cleaned
183+
cleaned_value = value
184+
185+
# Serializing of a `RestQueryset` is currently unsuppored since there
186+
# is no public way to create one without querying, which means the data
187+
# already exists on the server.
188+
if isinstance(value, RestQueryset):
189+
return local_diff
190+
181191
# Determine what type the current `value` is to process one of the three cases
182192
value_type = type(value)
183193

184194
# 1. Primitives
185195
if value_type in primitives:
186-
cleaned_value = value
187-
# Checks if we need to prepare the data
188-
if key in getattr(getattr(value, '_meta', None), 'fields', {}):
189-
cleaned_value = value._meta.fields[key].clean(value)
190-
191196
# If the value of the field is not what we've seen before, add it to the diff
192-
if ref != value:
197+
if ref != cleaned_value:
193198
local_diff[key] = cleaned_value
194-
195199
# 2/3. Objects
196200
else:
197201
# 2. Lists
198202
if value_type == list:
199203
# Process each idex of the `list`
200204
local_diff[key] = []
201-
for idx, inner_value in enumerate(value):
205+
for idx, inner_value in enumerate(cleaned_value):
202206
if type(inner_value) in primitives:
203207
local_diff[key].append(inner_value)
204208
else:
205209
local_diff[key].append(self._serialize_data(inner_value, self._get_reference_data(ref, idx)))
206210
# 3. Object/Dictionary
207211
else:
208212
new_ref = self._get_reference_data(ref, key)
209-
_data = self._serialize_data(value, new_ref)
210-
if not _data and type(value) not in (primitives + non_object_types):
213+
_data = self._serialize_data(cleaned_value, new_ref)
214+
if not _data and value_type not in (primitives + non_object_types):
211215
continue
212216
local_diff[key] = _data
213217

0 commit comments

Comments
 (0)