fix some issues with unsaved changesets

This commit is contained in:
Laura Klünder 2017-06-27 18:54:12 +02:00
parent fec524731d
commit 3e73da779b
3 changed files with 20 additions and 12 deletions

View file

@ -145,7 +145,10 @@ class ChangedObject(models.Model):
obj = self.changeset.get_created_object(field.related_model, value) obj = self.changeset.get_created_object(field.related_model, value)
setattr(instance, field.get_cache_name(), obj) setattr(instance, field.get_cache_name(), obj)
else: else:
delattr(instance, field.get_cache_name()) try:
delattr(instance, field.get_cache_name())
except AttributeError:
pass
setattr(instance, field.attname, value) setattr(instance, field.attname, value)
else: else:
raise NotImplementedError raise NotImplementedError

View file

@ -92,11 +92,12 @@ class ChangeSet(models.Model):
new_changeset = cls() new_changeset = cls()
new_changeset.request = request new_changeset.request = request
if request.session.session_key is None:
request.session.save()
if request.user.is_authenticated: if request.user.is_authenticated:
changeset = qs.filter(Q(author=request.user)).order_by('-created').first() changeset = qs.filter(Q(author=request.user)).order_by('-created').first()
if changeset is not None: if changeset is not None:
if request.session.session_key is None:
request.session.save()
changeset.session_id = request.session.session_key changeset.session_id = request.session.session_key
changeset.save() changeset.save()
return changeset return changeset

View file

@ -208,7 +208,7 @@ class ModelInstanceWrapper(BaseWrapper):
except FieldDoesNotExist: except FieldDoesNotExist:
pass pass
else: else:
if field.many_to_one and value is not None: if field.many_to_one and name != field.attname and value is not None:
if isinstance(value, models.Model): if isinstance(value, models.Model):
value = self._wrap_instance(value) value = self._wrap_instance(value)
if not isinstance(value, ModelInstanceWrapper): if not isinstance(value, ModelInstanceWrapper):
@ -221,10 +221,10 @@ class ModelInstanceWrapper(BaseWrapper):
def __repr__(self): def __repr__(self):
cls_name = self._obj.__class__.__name__ cls_name = self._obj.__class__.__name__
if self.pk is None: if self.pk is None:
return '<%s (unsaved) with Changeset #%d>' % (cls_name, self._changeset.pk) return '<%s (unsaved) with Changeset #%s>' % (cls_name, self._changeset.pk)
elif is_created_pk(self.pk): elif is_created_pk(self.pk):
return '<%s #%s (created) from Changeset #%d>' % (cls_name, self.pk, self._changeset.pk) return '<%s #%s (created) from Changeset #%s>' % (cls_name, self.pk, self._changeset.pk)
return '<%s #%d (existing) with Changeset #%d>' % (cls_name, self.pk, self._changeset.pk) return '<%s #%d (existing) with Changeset #%s>' % (cls_name, self.pk, self._changeset.pk)
def _get_unique_checks(self, exclude=None): def _get_unique_checks(self, exclude=None):
unique_checks, date_checks = self._obj.__class__._get_unique_checks(self, exclude=exclude) unique_checks, date_checks = self._obj.__class__._get_unique_checks(self, exclude=exclude)
@ -422,6 +422,8 @@ class BaseQueryWrapper(BaseWrapper):
# check if we are filtering by a foreign key field # check if we are filtering by a foreign key field
if field.many_to_one: if field.many_to_one:
rel_model = field.related_model
if not segments: if not segments:
# turn 'foreign_obj' into 'foreign_obj__pk' for later # turn 'foreign_obj' into 'foreign_obj__pk' for later
filter_name = field_name + '__pk' filter_name = field_name + '__pk'
@ -445,9 +447,10 @@ class BaseQueryWrapper(BaseWrapper):
if filter_type == 'pk' and segments == ['in']: if filter_type == 'pk' and segments == ['in']:
# foreign_obj__pk__in # foreign_obj__pk__in
filter_value = (pk for pk in filter_value if pk is not None)
filter_value = tuple(pk for pk in filter_value filter_value = tuple(pk for pk in filter_value
if is_created_pk(pk) or if is_created_pk(pk) or
int(pk) not in self._changeset.deleted_existing.get(field.related_model, ())) int(pk) not in self._changeset.deleted_existing.get(rel_model, ()))
existing_pks = tuple(pk for pk in filter_value if not is_created_pk(pk)) existing_pks = tuple(pk for pk in filter_value if not is_created_pk(pk))
q = Q(**{field_name+'__pk__in': existing_pks}) q = Q(**{field_name+'__pk__in': existing_pks})
filter_value = tuple(str(pk) for pk in filter_value) filter_value = tuple(str(pk) for pk in filter_value)
@ -459,10 +462,10 @@ class BaseQueryWrapper(BaseWrapper):
if filter_type == 'pk': if filter_type == 'pk':
# foreign_obj__pk # foreign_obj__pk
if is_created_pk(filter_value): if filter_value is None or int(filter_value) in self._changeset.deleted_existing.get(rel_model, ()):
q = Q(pk__in=())
elif int(filter_value) in self._changeset.deleted_existing.get(field.related_model, ()):
return Q(pk__in=()), set() return Q(pk__in=()), set()
elif is_created_pk(filter_value):
q = Q(pk__in=())
filter_value = str(filter_value) filter_value = str(filter_value)
return self._filter_values(q, field_name, lambda val: str(val) == filter_value) return self._filter_values(q, field_name, lambda val: str(val) == filter_value)
@ -509,6 +512,7 @@ class BaseQueryWrapper(BaseWrapper):
filter_value_existing = set(pk for pk in filter_value if not is_created_pk(pk)) filter_value_existing = set(pk for pk in filter_value if not is_created_pk(pk))
# lets removeall spaces that have been deleted # lets removeall spaces that have been deleted
filter_value = (pk for pk in filter_value if pk is not None)
filter_value = tuple(pk for pk in filter_value filter_value = tuple(pk for pk in filter_value
if is_created_pk(pk) or if is_created_pk(pk) or
int(pk) not in self._changeset.deleted_existing.get(rel_model, ())) int(pk) not in self._changeset.deleted_existing.get(rel_model, ()))
@ -557,7 +561,7 @@ class BaseQueryWrapper(BaseWrapper):
return (Q(pk__in=(pk for pk in pks if not is_created_pk(pk))), return (Q(pk__in=(pk for pk in pks if not is_created_pk(pk))),
set(pk for pk in pks if is_created_pk(pk))) set(pk for pk in pks if is_created_pk(pk)))
if int(filter_value) in self._changeset.deleted_existing.get(rel_model, ()): if filter_value is None or int(filter_value) in self._changeset.deleted_existing.get(rel_model, ()):
return Q(pk__in=()), set() return Q(pk__in=()), set()
return (((q & ~Q(pk__in=(pk for pk in remove_pks if not is_created_pk(pk)))) | return (((q & ~Q(pk__in=(pk for pk in remove_pks if not is_created_pk(pk)))) |