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.updated_existing = {}
|
||||
self.deleted_existing = {}
|
||||
self.m2m_add_existing = {}
|
||||
self.m2m_remove_existing = {}
|
||||
self.m2m_added = {}
|
||||
self.m2m_removed = {}
|
||||
self._last_change_pk = 0
|
||||
|
||||
def parse_changes(self):
|
||||
|
@ -63,8 +63,23 @@ class ChangeSet(models.Model):
|
|||
self.created_objects[model].pop(change.created_object_id)
|
||||
return
|
||||
|
||||
pk = change.obj_pk
|
||||
name = change.field_name
|
||||
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.action == 'update':
|
||||
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)
|
||||
return
|
||||
|
||||
pk = change.existing_object_pk
|
||||
if change.action == 'update':
|
||||
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):
|
||||
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
|
||||
if self.existing_object_pk is not None:
|
||||
return self.existing_object_pk
|
||||
if self.created_object is not None:
|
||||
return 'c'+str(self.created_object.changeset_id)
|
||||
if self.created_object_id is not None:
|
||||
return 'c'+str(self.created_object_id)
|
||||
raise TypeError('existing_model_pk or created_object have to be set.')
|
||||
|
||||
@property
|
||||
|
|
|
@ -385,17 +385,17 @@ class BaseQueryWrapper(BaseWrapper):
|
|||
if class_value.reverse:
|
||||
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):
|
||||
filter_value = int(filter_value[1:])
|
||||
pks = tuple(self._changeset.created_objects[model][filter_value].get(field_name, ()))
|
||||
pks = add_pks
|
||||
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)))
|
||||
|
||||
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)))) |
|
||||
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)))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue