fix manytomany queries
This commit is contained in:
parent
66d91e071f
commit
0b38921b94
2 changed files with 26 additions and 24 deletions
|
@ -35,8 +35,8 @@ class ChangeSet(models.Model):
|
||||||
self.created_objects = {}
|
self.created_objects = {}
|
||||||
self.updated_existing = {}
|
self.updated_existing = {}
|
||||||
self.deleted_existing = {}
|
self.deleted_existing = {}
|
||||||
self.m2m_add_existing = {}
|
self.m2m_added = {}
|
||||||
self.m2m_remove_existing = {}
|
self.m2m_removed = {}
|
||||||
self._last_change_pk = 0
|
self._last_change_pk = 0
|
||||||
|
|
||||||
def parse_changes(self):
|
def parse_changes(self):
|
||||||
|
@ -63,8 +63,23 @@ class ChangeSet(models.Model):
|
||||||
self.created_objects[model].pop(change.created_object_id)
|
self.created_objects[model].pop(change.created_object_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
pk = change.obj_pk
|
||||||
name = change.field_name
|
name = change.field_name
|
||||||
value = json.loads(change.field_value)
|
value = json.loads(change.field_value)
|
||||||
|
|
||||||
|
if change.action == 'm2m_add':
|
||||||
|
m2m_removed = self.m2m_removed.get(model, {}).get(pk, {}).get(name, ())
|
||||||
|
if value in m2m_removed:
|
||||||
|
m2m_removed.remove(value)
|
||||||
|
else:
|
||||||
|
self.m2m_added.setdefault(model, {}).setdefault(pk, {}).setdefault(name, set()).add(value)
|
||||||
|
elif change.action == 'm2m_remove':
|
||||||
|
m2m_added = self.m2m_added.get(model, {}).get(pk, {}).get(name, ())
|
||||||
|
if value in m2m_added:
|
||||||
|
m2m_added.remove(value)
|
||||||
|
else:
|
||||||
|
self.m2m_removed.setdefault(model, {}).setdefault(pk, {}).setdefault(name, set()).add(value)
|
||||||
|
|
||||||
if change.existing_object_pk is None:
|
if change.existing_object_pk is None:
|
||||||
if change.action == 'update':
|
if change.action == 'update':
|
||||||
self.created_objects[model][change.created_object_id][name] = value
|
self.created_objects[model][change.created_object_id][name] = value
|
||||||
|
@ -74,21 +89,8 @@ class ChangeSet(models.Model):
|
||||||
self.created_objects[model][change.created_object_id][name].remove(value)
|
self.created_objects[model][change.created_object_id][name].remove(value)
|
||||||
return
|
return
|
||||||
|
|
||||||
pk = change.existing_object_pk
|
|
||||||
if change.action == 'update':
|
if change.action == 'update':
|
||||||
self.updated_existing.setdefault(model, {}).setdefault(pk, {})[name] = value
|
self.updated_existing.setdefault(model, {}).setdefault(pk, {})[name] = value
|
||||||
elif change.action == 'm2m_add':
|
|
||||||
m2m_remove_existing = self.m2m_remove_existing.get(model, {}).get(pk, {}).get(name, ())
|
|
||||||
if value in m2m_remove_existing:
|
|
||||||
m2m_remove_existing.remove(value)
|
|
||||||
else:
|
|
||||||
self.m2m_add_existing.setdefault(model, {}).setdefault(pk, {}).setdefault(name, set()).add(value)
|
|
||||||
elif change.action == 'm2m_remove':
|
|
||||||
m2m_add_existing = self.m2m_add_existing.get(model, {}).get(pk, {}).get(name, ())
|
|
||||||
if value in m2m_add_existing:
|
|
||||||
m2m_add_existing.remove(value)
|
|
||||||
else:
|
|
||||||
self.m2m_remove_existing.setdefault(model, {}).setdefault(pk, {}).setdefault(name, set()).add(value)
|
|
||||||
|
|
||||||
def get_changed_values(self, model, name):
|
def get_changed_values(self, model, name):
|
||||||
r = tuple((pk, values[name]) for pk, values in self.updated_existing.get(model, {}).items() if name in values)
|
r = tuple((pk, values[name]) for pk, values in self.updated_existing.get(model, {}).items() if name in values)
|
||||||
|
@ -302,8 +304,8 @@ class Change(models.Model):
|
||||||
return self._set_object.pk
|
return self._set_object.pk
|
||||||
if self.existing_object_pk is not None:
|
if self.existing_object_pk is not None:
|
||||||
return self.existing_object_pk
|
return self.existing_object_pk
|
||||||
if self.created_object is not None:
|
if self.created_object_id is not None:
|
||||||
return 'c'+str(self.created_object.changeset_id)
|
return 'c'+str(self.created_object_id)
|
||||||
raise TypeError('existing_model_pk or created_object have to be set.')
|
raise TypeError('existing_model_pk or created_object have to be set.')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -385,17 +385,17 @@ class BaseQueryWrapper(BaseWrapper):
|
||||||
if class_value.reverse:
|
if class_value.reverse:
|
||||||
model = class_value.field.model
|
model = class_value.field.model
|
||||||
|
|
||||||
|
def get_changeset_m2m(items):
|
||||||
|
return items.get(model, {}).get(filter_value, {}).get(class_value.field.name, ())
|
||||||
|
|
||||||
|
remove_pks = get_changeset_m2m(self._changeset.m2m_removed)
|
||||||
|
add_pks = get_changeset_m2m(self._changeset.m2m_added)
|
||||||
|
|
||||||
if self.is_created_pk(filter_value):
|
if self.is_created_pk(filter_value):
|
||||||
filter_value = int(filter_value[1:])
|
pks = add_pks
|
||||||
pks = tuple(self._changeset.created_objects[model][filter_value].get(field_name, ()))
|
|
||||||
return (Q(pk__in=(pk for pk in pks if not self.is_created_pk(pk))),
|
return (Q(pk__in=(pk for pk in pks if not self.is_created_pk(pk))),
|
||||||
set(int(pk[1:]) for pk in pks if self.is_created_pk(pk)))
|
set(int(pk[1:]) for pk in pks if self.is_created_pk(pk)))
|
||||||
|
|
||||||
def get_changeset_m2m(items):
|
|
||||||
return items.get(model, {}).get(filter_value, {}).get(field_name, ())
|
|
||||||
|
|
||||||
remove_pks = get_changeset_m2m(self._changeset.m2m_remove_existing)
|
|
||||||
add_pks = get_changeset_m2m(self._changeset.m2m_add_existing)
|
|
||||||
return (((q & ~Q(pk__in=(pk for pk in remove_pks if not self.is_created_pk(pk)))) |
|
return (((q & ~Q(pk__in=(pk for pk in remove_pks if not self.is_created_pk(pk)))) |
|
||||||
Q(pk__in=(pk for pk in remove_pks if not self.is_created_pk(pk)))),
|
Q(pk__in=(pk for pk in remove_pks if not self.is_created_pk(pk)))),
|
||||||
set(int(pk[1:]) for pk in add_pks if self.is_created_pk(pk)))
|
set(int(pk[1:]) for pk in add_pks if self.is_created_pk(pk)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue