use order by NULLS LAST and remove extra rows in db

This commit is contained in:
j 2011-01-25 04:16:16 +05:30
parent 0a6c88402d
commit 590c0c96c2
3 changed files with 36 additions and 83 deletions

View file

@ -6,7 +6,7 @@ from django.db.models import Q, Manager
from itemlist.models import List from itemlist.models import List
import models import models
from ox.django.query import QuerySet
def parseCondition(condition): def parseCondition(condition):
''' '''
@ -193,7 +193,8 @@ def parseConditions(conditions, operator):
class ItemManager(Manager): class ItemManager(Manager):
def get_query_set(self): def get_query_set(self):
return super(ItemManager, self).get_query_set() #return super(ItemManager, self).get_query_set()
return QuerySet(self.model)
def filter_list(self, qs, l, user): def filter_list(self, qs, l, user):
if l != "all": if l != "all":

View file

@ -357,11 +357,7 @@ class Item(models.Model):
value = self.get(key) value = self.get(key)
#also get values from sort table, i.e. numberof values #also get values from sort table, i.e. numberof values
if not value and self.sort and hasattr(self.sort, key): if not value and self.sort and hasattr(self.sort, key):
if hasattr(self.sort, '%s_desc'%key): value = getattr(self.sort, key)
if getattr(self.sort, key) == getattr(self.sort, '%s_desc'%key):
value = getattr(self.sort, key)
else:
value = getattr(self.sort, key)
if value: if value:
i[key] = value i[key] = value
@ -388,7 +384,7 @@ class Item(models.Model):
def save(key, value): def save(key, value):
f, created = ItemFind.objects.get_or_create(item=self, key=key) f, created = ItemFind.objects.get_or_create(item=self, key=key)
if value not in (''): if value not in ('', ):
if isinstance(value, basestring): if isinstance(value, basestring):
value = value.strip() value = value.strip()
f.value = value f.value = value
@ -460,6 +456,11 @@ class Item(models.Model):
) )
max_int = 9223372036854775807L max_int = 9223372036854775807L
def set_value(s, name, value):
if not value:
value = None
setattr(s, name, value)
for key in filter(lambda k: 'sort' in k, config['itemKeys']): for key in filter(lambda k: 'sort' in k, config['itemKeys']):
name = key['id'] name = key['id']
source = name source = name
@ -472,84 +473,43 @@ class Item(models.Model):
if sort_type == 'title': if sort_type == 'title':
value = utils.sort_title(canonicalTitle(self.get(source))) value = utils.sort_title(canonicalTitle(self.get(source)))
value = utils.sort_string(value) value = utils.sort_string(value)
setattr(s, '%s_desc'%name, value) set_value(s, name, value)
if not value:
value = 'zzzzzzzzzzzzzzzzzzzzzzzzz'
setattr(s, name, value)
elif sort_type == 'person': elif sort_type == 'person':
value = sortNames(self.get(source, [])) value = sortNames(self.get(source, []))
value = utils.sort_string(value)[:955] value = utils.sort_string(value)[:955]
setattr(s, '%s_desc'%name, value) set_value(s, name, value)
if not value:
value = 'zzzzzzzzzzzzzzzzzzzzzzzzz'
setattr(s, name, value)
elif sort_type == 'string': elif sort_type == 'string':
value = self.get(source, u'') value = self.get(source, u'')
if isinstance(value, list): if isinstance(value, list):
value = u','.join(value) value = u','.join(value)
value = utils.sort_string(value)[:955] value = utils.sort_string(value)[:955]
setattr(s, '%s_desc'%name, value) set_value(s, name, value)
if not value: elif sort_type in ('length', 'integer', 'float'):
value = 'zzzzzzzzzzzzzzzzzzzzzzzzz'
setattr(s, name, value)
elif sort_type == 'length':
#can be length of strings or length of arrays, i.e. keywords #can be length of strings or length of arrays, i.e. keywords
value = self.get(source, None) value = self.get(source, None)
if not value:
value = -max_int
else:
value = len(value)
setattr(s, '%s_desc'%name, value)
if value == -max_int:
value = max_int
setattr(s, name, value)
elif sort_type == 'integer':
value = self.get(source, -max_int)
if isinstance(value, list): if isinstance(value, list):
value = len(value) value = len(value)
setattr(s, '%s_desc'%name, value) set_value(s, name, value)
if value == -max_int:
value = max_int
setattr(s, name, value)
elif sort_type == 'float':
max_float = 9223372036854775807L
value = self.get(source, -max_float)
if isinstance(value, list):
value = sum(value)
setattr(s, name, value)
if value == -max_float:
value = max_float
setattr(s, '%s_desc'%name, value)
elif sort_type == 'words': elif sort_type == 'words':
value = self.get(source, '') value = self.get(source, None)
if isinstance(value, list): if isinstance(value, list):
value = '\n'.join(value) value = '\n'.join(value)
if value: if value:
value = len(value.split(' ')) value = len(value.split(' '))
else: set_value(s, name, value)
value = 0
setattr(s, name, value)
elif sort_type == 'year': elif sort_type == 'year':
value = self.get(source, '') value = self.get(source, None)
setattr(s, '%s_desc'%name, value) set_value(s, name, value)
if not value:
value = '9999'
setattr(s, name, value)
elif sort_type == 'date': elif sort_type == 'date':
value = self.get(source, None) value = self.get(source, None)
if isinstance(value, basestring): if isinstance(value, basestring):
value = datetime.strptime(value, '%Y-%m-%d') value = datetime.strptime(value, '%Y-%m-%d')
setattr(s, name, value) set_value(s, name, value)
if not value:
value = datetime.strptime('9999-12-12', '%Y-%m-%d')
setattr(s, '%s_desc'%name, value)
#sort keys based on database, these will always be available #sort keys based on database, these will always be available
s.itemId = self.itemId.replace('0x', 'xx') s.itemId = self.itemId.replace('0x', 'xx')
s.modified = self.modified s.modified = self.modified
s.modified_desc = self.modified
s.published = self.published s.published = self.published
s.published_desc = self.published
# sort values based on data from videos # sort values based on data from videos
s.words = 0 #FIXME: get words from all layers or something s.words = 0 #FIXME: get words from all layers or something
@ -566,30 +526,29 @@ class Item(models.Model):
s.bitrate = videos[0].info['bitrate'] s.bitrate = videos[0].info['bitrate']
s.pixels = sum([v.pixels for v in videos]) s.pixels = sum([v.pixels for v in videos])
s.filename = ' '.join([v.name for v in videos])[:955] s.filename = ' '.join([v.name for v in videos])[:955]
s.filename_desc = ' '.join([v.name for v in videos])[:955]
s.files = self.files.all().count() s.files = self.files.all().count()
s.size = sum([v.size for v in videos]) #FIXME: only size of movies? s.size = sum([v.size for v in videos]) #FIXME: only size of movies?
s.volume = 0 s.volume = 0
else: else:
s.duration = 0 s.duration = None
s.resolution = 0 s.resolution = None
s.aspectratio = 0 s.aspectratio = None
s.bitrate = 0 s.bitrate = None
s.pixels = 0 s.pixels = None
s.filename = 0 s.filename = None
s.files = 0 s.files = None
s.size = 0 s.size = None
s.volume = 0 s.volume = None
s.color = int(sum(self.data.get('color', []))) s.color = int(sum(self.data.get('color', [])))
s.saturation = 0 #FIXME s.saturation = None #FIXME
s.brightness = 0 #FIXME s.brightness = None #FIXME
s.cuts = len(self.data.get('cuts', [])) s.cuts = len(self.data.get('cuts', []))
if s.duration: if s.duration:
s.cutsperminute = s.cuts / (s.duration/60) s.cutsperminute = s.cuts / (s.duration/60)
else: else:
s.cutsperminute = 0 s.cutsperminute = None
s.save() s.save()
@ -883,13 +842,9 @@ for key in filter(lambda k: 'sort' in k, config['itemKeys']):
'date': 'date', 'date': 'date',
}.get(sort_type, sort_type)] }.get(sort_type, sort_type)]
attrs[name] = model[0](**model[1]) attrs[name] = model[0](**model[1])
attrs['%s_desc'%name] = model[0](**model[1])
ItemSort = type('ItemSort', (models.Model,), attrs) ItemSort = type('ItemSort', (models.Model,), attrs)
ItemSort.fields = filter(lambda x: not x.endswith('_desc'), ItemSort.fields = [f.name for f in ItemSort._meta.fields]
[f.name for f in ItemSort._meta.fields])
ItemSort.descending_fields = filter(lambda x: x.endswith('_desc'),
[f.name for f in ItemSort._meta.fields])
class Access(models.Model): class Access(models.Model):

View file

@ -49,12 +49,10 @@ def _order_query(qs, sort, prefix='sort__'):
if operator != '-': if operator != '-':
operator = '' operator = ''
key = {'id': 'itemId'}.get(e['key'], e['key']) key = {'id': 'itemId'}.get(e['key'], e['key'])
if operator=='-' and '%s_desc'%key in models.ItemSort.descending_fields:
key = '%s_desc' % key
order = '%s%s%s' % (operator, prefix, key) order = '%s%s%s' % (operator, prefix, key)
order_by.append(order) order_by.append(order)
if order_by: if order_by:
qs = qs.order_by(*order_by) qs = qs.order_by(*order_by, nulls_last=True)
return qs return qs
def _order_by_group(query): def _order_by_group(query):
@ -213,8 +211,7 @@ Positions
response['data']['files'] = files.count() response['data']['files'] = files.count()
response['data']['items'] = items.count() response['data']['items'] = items.count()
response['data']['pixels'] = r['pixels__sum'] response['data']['pixels'] = r['pixels__sum']
response['data']['runtime'] = items.filter(sort__runtime_desc__gt=0).aggregate( response['data']['runtime'] = items.aggregate(Sum('sort__runtime'))['sort__runtime__sum']
Sum('sort__runtime_desc'))['sort__runtime_desc__sum']
response['data']['size'] = r['size__sum'] response['data']['size'] = r['size__sum']
for key in ('runtime', 'duration', 'pixels', 'size'): for key in ('runtime', 'duration', 'pixels', 'size'):
if response['data'][key] == None: if response['data'][key] == None:
@ -241,7 +238,7 @@ def autocomplete(request):
key = site_config['keys'][data['key']] key = site_config['keys'][data['key']]
order_by = key.get('find', {}).get('autocompleteSortKey', False) order_by = key.get('find', {}).get('autocompleteSortKey', False)
if order_by: if order_by:
order_by = '-sort__%s_desc' % order_by order_by = '-sort__%s' % order_by
else: else:
order_by = '-items' order_by = '-items'
sort_type = key.get('sort', {}).get('type', 'string') sort_type = key.get('sort', {}).get('type', 'string')