Skip to content

Instantly share code, notes, and snippets.

@mtford90
Created March 29, 2014 13:02
Show Gist options
  • Save mtford90/9854075 to your computer and use it in GitHub Desktop.
Save mtford90/9854075 to your computer and use it in GitHub Desktop.
proposed bug fix for django-positions #26
from positions import PositionField
class BugFixedPositionField(PositionField):
def pre_save(self, model_instance, add):
#NOTE: check if the node has been moved to another collection; if it has, delete it from the old collection.
previous_instance = None
collection_changed = False
if not add and self.collection is not None:
# Start bug fix
try:
previous_instance = type(model_instance)._default_manager.get(pk=model_instance.pk)
for field_name in self.collection:
field = model_instance._meta.get_field(field_name)
current_field_value = getattr(model_instance, field.attname)
previous_field_value = getattr(previous_instance, field.attname)
if previous_field_value != current_field_value:
collection_changed = True
break
except model_instance.DoesNotExist:
pass
# End bug fix
if not collection_changed:
previous_instance = None
self._collection_changed = collection_changed
if collection_changed:
self.remove_from_collection(previous_instance)
cache_name = self.get_cache_name()
current, updated = getattr(model_instance, cache_name)
if collection_changed:
current = None
if add:
if updated is None:
updated = current
current = None
elif updated is None:
updated = -1
# existing instance, position not modified; no cleanup required
if current is not None and updated is None:
return current
collection_count = self.get_collection(model_instance).count()
if current is None:
max_position = collection_count
else:
max_position = collection_count - 1
min_position = 0
# new instance; appended; no cleanup required on post_save
if add and (updated == -1 or updated >= max_position):
setattr(model_instance, cache_name, (max_position, None))
return max_position
if max_position >= updated >= min_position:
# positive position; valid index
position = updated
elif updated > max_position:
# positive position; invalid index
position = max_position
elif abs(updated) <= (max_position + 1):
# negative position; valid index
# Add 1 to max_position to make this behave like a negative list index.
# -1 means the last position, not the last position minus 1
position = max_position + 1 + updated
else:
# negative position; invalid index
position = min_position
# instance inserted; cleanup required on post_save
setattr(model_instance, cache_name, (current, position))
return position
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment