From 3dd44e52e2b9214fb44e38449e34684fc3c156f1 Mon Sep 17 00:00:00 2001 From: Robert Moggach Date: Tue, 29 Oct 2013 21:41:51 -0500 Subject: [PATCH] added additional admin functionality --- .gitignore | 3 ++ positions/__init__.py | 1 + positions/admin.py | 45 ++++++++++++++++ positions/fields.py | 48 ++++++++++++++++-- positions/static/positions/img/arrow-down.gif | Bin 0 -> 80 bytes positions/static/positions/img/arrow-up.gif | Bin 0 -> 838 bytes 6 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 positions/admin.py create mode 100644 positions/static/positions/img/arrow-down.gif create mode 100644 positions/static/positions/img/arrow-up.gif diff --git a/.gitignore b/.gitignore index ec828ad..e47f13e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ *.un~ /build /dist +.DS_Store +._* +.svn diff --git a/positions/__init__.py b/positions/__init__.py index 4de1f3e..3df263f 100644 --- a/positions/__init__.py +++ b/positions/__init__.py @@ -1,2 +1,3 @@ from positions.fields import PositionField from positions.managers import PositionManager +from positions.admin import PositionAdmin \ No newline at end of file diff --git a/positions/admin.py b/positions/admin.py new file mode 100644 index 0000000..30e12e7 --- /dev/null +++ b/positions/admin.py @@ -0,0 +1,45 @@ +from django.conf import settings +from django.contrib import admin +from django.shortcuts import get_object_or_404 +from django.utils.functional import update_wrapper +from django.conf.urls.defaults import patterns, url +from django.contrib.admin.util import unquote +from django.http import HttpResponseRedirect + + +class PositionAdmin(admin.ModelAdmin): + def get_urls(self): + def wrap(view): + def wrapper(*args, **kwargs): + return self.admin_site.admin_view(view)(*args, **kwargs) + return update_wrapper(wrapper, view) + + info = self.model._meta.app_label, self.model._meta.module_name + return patterns('', + url(r'^(.+)/position-(up)/$', wrap(self.position_view), name='%s_%s_position_up' % info), + url(r'^(.+)/position-(down)/$', wrap(self.position_view), name='%s_%s_position_down' % info), + ) + super(PositionAdmin, self).get_urls() + + def position_view(self, request, object_id, direction): + obj = get_object_or_404(self.model, pk=unquote(object_id)) + if direction == 'up': + obj.position_up() + else: + obj.position_down() + return HttpResponseRedirect('../../') + + def position_up_down_links(self, obj): + return ''' + Position Up + Position Down''' % { + 'app_label': self.model._meta.app_label, + 'module_name': self.model._meta.module_name, + 'object_id': obj.id, + 'STATIC_URL': settings.STATIC_URL, + } + + position_up_down_links.allow_tags = True + + position_up_down_links.short_description = 'Position' + + diff --git a/positions/fields.py b/positions/fields.py index 3d6fa52..777120b 100644 --- a/positions/fields.py +++ b/positions/fields.py @@ -1,5 +1,6 @@ import datetime import warnings +import types from django.db import models from django.db.models.signals import post_delete, post_save, pre_delete @@ -39,8 +40,8 @@ def __init__(self, verbose_name=None, name=None, default=-1, collection=None, pa self.collection = collection self.parent_link = parent_link self._collection_changed = None - - def contribute_to_class(self, cls, name): + + def contribute_to_class(self, cls, name ): super(PositionField, self).contribute_to_class(cls, name) for constraint in cls._meta.unique_together: if self.name in constraint: @@ -50,6 +51,34 @@ def contribute_to_class(self, cls, name): if getattr(field, 'auto_now', False): self.auto_now_fields.append(field) setattr(cls, self.name, self) + + def _position_move(instance, up): + collection = self.get_collection(instance) + cache_name = self.get_cache_name() + position = getattr(instance, cache_name)[0] + if up: + collection = collection.filter(**{'%s__gt' % self.name: position}) + else: + collection = collection.order_by('-%s' % self.name).filter(**{'%s__lt' % self.name: position}) + try: + replacement = collection[0] + except IndexError: + return + current, updated = getattr(instance, cache_name), getattr(replacement, cache_name) + setattr(instance, cache_name, updated) + setattr(replacement, cache_name, current) + instance.save() + replacement.save() + + def position_down(self): + return _position_move(self, up=False) + + def position_up(self): + return _position_move(self, up=True) + + setattr(cls, 'position_down', position_down ) + setattr(cls, 'position_up', position_up ) + pre_delete.connect(self.prepare_delete, sender=cls) post_delete.connect(self.update_on_delete, sender=cls) post_save.connect(self.update_on_save, sender=cls) @@ -167,8 +196,19 @@ def get_next_sibling(self, instance): Returns the next sibling of this instance. """ try: - return self.get_collection(instance).filter(**{'%s__gt' % self.name: getattr(instance, self.get_cache_name())[0]})[0] - except: + position = getattr(instance, self.get_cache_name())[0] + return self.get_collection(instance).filter(**{'%s__gt' % self.name: position}).order_by('%s' % self.name)[0] + except IndexError: + return None + + def get_previous_sibling(self, instance): + """ + Returns the previous sibling of this instance. + """ + try: + position = getattr(instance, self.get_cache_name())[0] + return self.get_collection(instance).filter(**{'%s__lt' % self.name: position}).order_by('-%s' % self.name)[0] + except IndexError: return None def remove_from_collection(self, instance): diff --git a/positions/static/positions/img/arrow-down.gif b/positions/static/positions/img/arrow-down.gif new file mode 100644 index 0000000000000000000000000000000000000000..a967b9fd5563a0fc2f5fde8ec0f7de3fc8fbc5a9 GIT binary patch literal 80 zcmZ?wbhEHb3wfn>L+1d2-{%jW1rjm^pLi|Ns9P7#I|PvM@3LmFNK3 i3?Q`(%%TyyyiA!oB04G)Te5yh$2@OMO7G-kum%ACMICAY literal 0 HcmV?d00001 diff --git a/positions/static/positions/img/arrow-up.gif b/positions/static/positions/img/arrow-up.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fe4851399a37337891ccf5452ee5d59bbedeec7 GIT binary patch literal 838 zcmZ?wbhEHb3wfn>L+1d2-{%jW1rjm^pJM!zdUHfe{k|ia%Kx8GuSOX;Q=NFCLWFl0*@NH#f6pb?3n1_z+epkX4f1j literal 0 HcmV?d00001