src/iconolab/models.py
changeset 521 63a7f61554fe
parent 519 fb295acc6c3c
child 523 74bed3682231
equal deleted inserted replaced
520:d1e231a045ac 521:63a7f61554fe
     7 import requests
     7 import requests
     8 from django.conf import settings
     8 from django.conf import settings
     9 from django.contrib.auth.models import User
     9 from django.contrib.auth.models import User
    10 from django.contrib.contenttypes.fields import GenericRelation
    10 from django.contrib.contenttypes.fields import GenericRelation
    11 from django.contrib.contenttypes.models import ContentType
    11 from django.contrib.contenttypes.models import ContentType
    12 from django.db import models, transaction
    12 from django.db import models, transaction, connection
    13 from django.utils.text import slugify
    13 from django.utils.text import slugify
    14 from django_comments_xtd.models import XtdComment
    14 from django_comments_xtd.models import XtdComment
    15 
    15 
    16 import iconolab.signals.handlers as iconolab_signals
    16 import iconolab.signals.handlers as iconolab_signals
    17 
    17 
    18 logger = logging.getLogger(__name__)
    18 logger = logging.getLogger(__name__)
    19 
    19 
       
    20 # https://docs.djangoproject.com/fr/1.11/topics/db/sql/#executing-custom-sql-directly
       
    21 def dictfetchall(cursor):
       
    22     "Return all rows from a cursor as a dict"
       
    23     columns = [col[0] for col in cursor.description]
       
    24     return [
       
    25         dict(zip(columns, row))
       
    26         for row in cursor.fetchall()
       
    27     ]
    20 
    28 
    21 class Collection(models.Model):
    29 class Collection(models.Model):
    22     """
    30     """
    23         Collection objects are the thematic item repositories in Iconolab
    31         Collection objects are the thematic item repositories in Iconolab
    24 
    32 
    40     image = models.ImageField(
    48     image = models.ImageField(
    41         upload_to='uploads/', height_field='height', width_field='width', null=True, blank=True)
    49         upload_to='uploads/', height_field='height', width_field='width', null=True, blank=True)
    42     height = models.IntegerField(null=True, blank=True)
    50     height = models.IntegerField(null=True, blank=True)
    43     width = models.IntegerField(null=True, blank=True)
    51     width = models.IntegerField(null=True, blank=True)
    44     show_image_on_home = models.BooleanField(default=False)
    52     show_image_on_home = models.BooleanField(default=False)
       
    53     completed_percent_calculated = None
       
    54 
       
    55     def completed_percent(self):
       
    56 
       
    57         if self.completed_percent_calculated is None:
       
    58 
       
    59             sql = '''SELECT i.id AS item, COUNT(a.id) AS annotations
       
    60     FROM iconolab_collection c
       
    61     JOIN iconolab_item i ON i.collection_id = c.id
       
    62     JOIN iconolab_image img ON img.item_id = i.id
       
    63     LEFT JOIN iconolab_annotation a ON a.image_id = img.id
       
    64     WHERE c.id = %s
       
    65     GROUP BY c.name, i.id'''
       
    66 
       
    67             with connection.cursor() as cursor:
       
    68                 cursor.execute(sql, [self.id])
       
    69                 results = dictfetchall(cursor)
       
    70                 total_items = len(results)
       
    71                 items_with_annotation = 0
       
    72 
       
    73                 for result in results:
       
    74                     if result['annotations'] > 0:
       
    75                         items_with_annotation += 1
       
    76 
       
    77                 self.completed_percent_calculated = int(round((items_with_annotation * 100) / total_items))
       
    78 
       
    79         return self.completed_percent_calculated
    45 
    80 
    46     def __str__(self):
    81     def __str__(self):
    47         return self.name
    82         return self.name
    48 
    83 
    49 class Folder(models.Model):
    84 class Folder(models.Model):