Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
*.pyc
*.pyo
*.egg-info
*.code-workspace
.idea
dist
build/
doc/_build/
venv/
.vscode/
debug.py
46 changes: 25 additions & 21 deletions odata/navproperty.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,25 @@ def __init__(self, name, entitycls, collection=False, foreign_key=None):
def __repr__(self):
return u'<NavigationProperty to {0}>'.format(self.entitycls)

def instances_from_data(self, raw_data):
def instances_from_data(self, raw_data, connection):
if self.is_collection:
return [self.entitycls.__new__(self.entitycls, from_data=d) for d in raw_data]
return [self.instance_from_data(d, connection) for d in raw_data['value']] if raw_data['value'] else []
else:
return self.entitycls.__new__(self.entitycls, from_data=raw_data)

return self.instance_from_data(raw_data, connection) if raw_data else None

def instance_from_data(self, raw_data, connection): # mwa: this needs to be seperated form navproperty
entitycls = self._getClass_by_response_type(self.entitycls, raw_data.get('@odata.type'))
e = entitycls.__new__(entitycls, from_data=raw_data)
es = e.__odata__
es.connection = connection
return e

def _getClass_by_response_type(self, matched_class, odata_type):
if not odata_type: return matched_class
for subclass in matched_class.__subclasses__():
if subclass.__odata_type__ == odata_type[1:]: return self._getClass_by_response_type(subclass, odata_type)
return matched_class

def _get_parent_cache(self, instance):
es = instance.__odata__
ic = es.nav_cache
Expand Down Expand Up @@ -102,20 +115,11 @@ def __get__(self, instance, owner):

parent_url += '/'
url = urljoin(parent_url, self.name)

if self.is_collection:
if 'collection' not in cache:
raw_data = connection.execute_get(url)
if raw_data:
cache['collection'] = self.instances_from_data(raw_data['value'])
else:
cache['collection'] = []
return cache['collection']
else:
if 'single' not in cache:
raw_data = connection.execute_get(url)
if raw_data:
cache['single'] = self.instances_from_data(raw_data)
else:
cache['single'] = None
return cache['single']
cache_type = 'collection' if self.is_collection else 'single'

try:
return cache[cache_type]
except KeyError:
raw_data = connection.execute_get(url)
cache[cache_type] = self.instances_from_data(raw_data, connection)
return cache[cache_type]
2 changes: 1 addition & 1 deletion odata/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def __iter__(self):
for row in value:
yield self._create_model(row)

if '@odata.nextLink' in data:
if '@odata.nextLink' in data and not '$top' in options.keys(): #do not load next page on userpaging
url = urljoin(self.entity.__odata_url_base__, data['@odata.nextLink'])
options = {} # we get all options in the nextLink url
else:
Expand Down