Mikhail Korobov avatar Mikhail Korobov committed 3b61335

new method: get_order_in_album

Comments (0)

Files changed (1)

generic_images/models.py

 
 class AbstractAttachedImage(ReplaceOldImageModel, GenericModelBase):
     '''
-        Abstract Image model that can be attached to any other Django model using
-        generic relations.
+        Abstract Image model that can be attached to any other Django model
+        using generic relations.
 
         .. attribute:: is_main
 
     '''
 
 
-    user = models.ForeignKey(User, blank=True, null=True, verbose_name=_('User'))
-    'A ForeignKey to associated user, for example user who uploaded image. Can be empty.'
+    user = models.ForeignKey(User, blank=True, null=True,
+                             verbose_name=_('User'))
+    '''A ForeignKey to associated user, for example user who uploaded image.
+    Can be empty.'''
 
     caption = models.TextField(_('Caption'), null=True, blank=True)
     'TextField caption for image'
     order = models.IntegerField(_('Order'), default=0)
 
     objects = AttachedImageManager()
-    'Default manager of :class:`~generic_images.managers.AttachedImageManager` type.'
+    '''Default manager of :class:`~generic_images.managers.AttachedImageManager`
+    type.'''
 
     def next(self):
-        ''' Returns next image for same content_object and None if image is the last. '''
+        ''' Returns next image for same content_object and None if image is
+        the last. '''
         try:
-            return self.__class__.objects.for_model(self.content_object).filter(order__lt=self.order).order_by('-order')[0]
+            return self.__class__.objects.for_model(self.content_object,
+                                                    self.content_type).\
+                            filter(order__lt=self.order).order_by('-order')[0]
         except IndexError:
             return None
 
     def previous(self):
-        ''' Returns previous image for same content_object and None if image is the first. '''
+        ''' Returns previous image for same content_object and None if image
+        is the first. '''
         try:
-            return self.__class__.objects.for_model(self.content_object).filter(order__gt=self.order).order_by('order')[0]
+            return self.__class__.objects.for_model(self.content_object,
+                                                    self.content_type).\
+                            filter(order__gt=self.order).order_by('order')[0]
         except IndexError:
             return None
 
+    def get_order_in_album(self, reversed_ordering=True):
+        ''' Returns image order number. It is calculated as (number+1) of images
+        attached to the same content_object whose order is greater
+        (if 'reverse_ordering' is True) or lesser (if 'reverse_ordering' is
+        False) than image's order.
+        '''
+        lookup = 'order__gt' if reversed_ordering else 'order__lt'
+        return self.__class__.objects.\
+                        for_model(self.content_object, self.content_type).\
+                        filter(**{lookup: self.order}).count() + 1
+
 
     def _get_next_pk(self):
-        max_pk = self.__class__.objects.aggregate(max_pk=Max('pk'))['max_pk'] or 0
+        max_pk = self.__class__.objects.aggregate(m=Max('pk'))['m'] or 0
         return max_pk+1
 
 
+#    def put_as_last(self):
+#        """ Sets order to max(order)+1 for self.content_object
+#        """
+#        last = self.__class__.objects.exclude(id=self.id).\
+#                        filter(
+#                           object_id = self.object_id,
+#                           content_type = self.content_type,
+#                        ).aggregate(max_order=Max('order'))['max_order'] or 0
+#        self.order = last+1
+
+
     def get_file_name(self, filename):
         ''' Returns file name (without path and extenstion)
             for uploaded image. Default is 'max(pk)+1'.
             if you want different file names (ex: random string).
         '''
 #        alphabet = "1234567890abcdefghijklmnopqrstuvwxyz"
-#        return ''.join([random.choice(alphabet) for i in xrange(16)]) # 1e25 variants
-        return str(self._get_next_pk()) # anyway _get_next_pk is needed for setting `order` field
+#        # 1e25 variants
+#        return ''.join([random.choice(alphabet) for i in xrange(16)])
+
+        # anyway _get_next_pk is needed for setting `order` field
+        return str(self._get_next_pk())
 
 
     def get_upload_path(self, filename):
         ''' Override this in proxy subclass to customize upload path.
-            Default upload path is :file:`/media/images/<user.id>/<filename>.<ext>`
+            Default upload path is
+            :file:`/media/images/<user.id>/<filename>.<ext>`
             or :file:`/media/images/common/<filename>.<ext>` if user is not set.
 
-            filename is returned by :meth:`~generic_images.models.AbstractAttachedImage.get_file_name` method.
-            By default it is probable id of new image (it is
+            ``<filename>`` is returned by
+            :meth:`~generic_images.models.AbstractAttachedImage.get_file_name`
+            method. By default it is probable id of new image (it is
             predicted as it is unknown at this stage).
         '''
         user_folder = str(self.user.pk) if self.user else 'common'
 
         root, ext = os.path.splitext(filename)
-        return os.path.join('media', 'images', user_folder, self.get_file_name(filename) + ext)
+        return os.path.join('media', 'images', user_folder,
+                            self.get_file_name(filename) + ext)
 
 
     def save(self, *args, **kwargs):
         send_signal = getattr(self, 'send_signal', True)
         if self.is_main:
-            related_images = self.__class__.objects.filter(content_type=self.content_type,
-                                                          object_id=self.object_id)
+            related_images = self.__class__.objects.filter(
+                                                content_type=self.content_type,
+                                                object_id=self.object_id
+                                            )
             related_images.update(is_main=False)
 
         if not self.pk: # object is created
         super(AbstractAttachedImage, self).save(*args, **kwargs)
 
         if send_signal:
-            image_saved.send(sender = self.content_type.model_class(), instance = self)
+            image_saved.send(sender = self.content_type.model_class(),
+                             instance = self)
 
 
     def delete(self, *args, **kwargs):
         send_signal = getattr(self, 'send_signal', True)
         if send_signal:
-            image_deleted.send(sender = self.content_type.model_class(), instance = self)
+            image_deleted.send(sender = self.content_type.model_class(),
+                               instance = self)
         super(AbstractAttachedImage, self).delete(*args, **kwargs)
 
 
     def __unicode__(self):
         try:
             if self.user:
-                return u"AttachedImage #%d for [%s] by [%s]" % (self.pk, self.content_object, self.user)
+                return u"AttachedImage #%d for [%s] by [%s]" % (
+                         self.pk, self.content_object, self.user)
             else:
-                return u"AttachedImage #%d for [%s]" % (self.pk, self.content_object,)
+                return u"AttachedImage #%d for [%s]" % (
+                        self.pk, self.content_object,)
         except:
             try:
                 return u"AttachedImage #%d" % (self.pk)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.