Skip to content
Merged
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
14 changes: 7 additions & 7 deletions odata/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def delete(self, entity):
entity.__odata__.persisted = False
self.log.info(u'Success')

def save(self, entity, force_refresh=True, extra_headers=None):
def save(self, entity, force_refresh=True, extra_headers=None, omit_null_props=[]):
"""
Creates a POST or PATCH call to the service. If the entity already has
a primary key, an update is called. Otherwise the entity is inserted
Expand All @@ -63,14 +63,14 @@ def save(self, entity, force_refresh=True, extra_headers=None):
"""

if self.is_entity_saved(entity):
self._update_existing(entity, force_refresh=force_refresh, extra_headers=extra_headers)
self._update_existing(entity, force_refresh=force_refresh, extra_headers=extra_headers, omit_null_props=omit_null_props)
else:
self._insert_new(entity)
self._insert_new(entity, omit_null_props=omit_null_props)

def is_entity_saved(self, entity):
return entity.__odata__.persisted

def _insert_new(self, entity):
def _insert_new(self, entity, omit_null_props=[]):
"""
Creates a POST call to the service, sending the complete new entity

Expand All @@ -84,7 +84,7 @@ def _insert_new(self, entity):
self.log.info(u'Saving new entity')

es = entity.__odata__
insert_data = es.data_for_insert()
insert_data = es.data_for_insert(omit_null_props)
saved_data = self.connection.execute_post(url, insert_data)
es.reset()
es.connection = self.connection
Expand All @@ -95,7 +95,7 @@ def _insert_new(self, entity):

self.log.info(u'Success')

def _update_existing(self, entity, force_refresh=True, extra_headers=None):
def _update_existing(self, entity, force_refresh=True, extra_headers=None, omit_null_props=[]):
"""
Creates a PATCH call to the service, sending only the modified values

Expand All @@ -106,7 +106,7 @@ def _update_existing(self, entity, force_refresh=True, extra_headers=None):
msg = 'Cannot update Entity that does not belong to EntitySet: {0}'.format(entity)
raise ODataError(msg)

patch_data = es.data_for_update()
patch_data = es.data_for_update(omit_null_props)

if len([i for i in patch_data if not i.startswith('@')]) == 0:
self.log.debug(u'Nothing to update: {0}'.format(entity))
Expand Down
4 changes: 2 additions & 2 deletions odata/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def delete(self, entity):
"""
return self.default_context.delete(entity)

def save(self, entity, force_refresh=True):
def save(self, entity, force_refresh=True, omit_null_props=[]):
"""
Creates a POST or PATCH call to the service. If the entity already has
a primary key, an update is called. Otherwise the entity is inserted
Expand All @@ -254,4 +254,4 @@ def save(self, entity, force_refresh=True):
:param force_refresh: Read full entity data again from service after PATCH call
:raises ODataConnectionError: Invalid data or serverside error. Server returned an HTTP error code
"""
return self.default_context.save(entity, force_refresh=force_refresh)
return self.default_context.save(entity, force_refresh=force_refresh, omit_null_props=omit_null_props)
33 changes: 26 additions & 7 deletions odata/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@ def set_property_dirty(self, prop):
if prop.name not in self.dirty:
self.dirty.append(prop.name)

def data_for_insert(self):
return self._clean_new_entity(self.entity)
def data_for_insert(self, omit_null_props=[]):
return self._clean_new_entity(self.entity, omit_null_props)

def data_for_update(self):
def data_for_update(self, omit_null_props=[]):
update_data = OrderedDict()
update_data['@odata.type'] = self.entity.__odata_type__

Expand All @@ -211,9 +211,19 @@ def data_for_update(self):
update_data[key] = [i.__odata__.id for i in value]
else:
update_data[key] = value.__odata__.id
return update_data

def _clean_new_entity(self, entity):

update_data_filtered = {}
for prop_name, prop in update_data.items():
if omit_null_props is True or prop_name in omit_null_props:
# Should omit unless not None
if prop is None:
# Omit from request
continue
update_data_filtered[prop_name] = prop

return update_data_filtered

def _clean_new_entity(self, entity, omit_null_props=[]):
""":type entity: odata.entity.EntityBase """
insert_data = OrderedDict()
insert_data['@odata.type'] = entity.__odata_type__
Expand Down Expand Up @@ -262,4 +272,13 @@ def _clean_new_entity(self, entity):
else:
insert_data[prop.name] = self._clean_new_entity(value)

return insert_data
insert_data_filtered = {}
for prop_name, prop in insert_data.items():
if omit_null_props is True or prop_name in omit_null_props:
# Should omit unless not None
if prop is None:
# Omit from request
continue
insert_data_filtered[prop_name] = prop

return insert_data_filtered