Combine {Item,Clip,edit.Clip}.get_layers()

This has several benefits:

    • Clip.get_layers() (used by smart edits) and Item.get_layers() pick up
    the select_related('user') optimization added for static edits in
    r5007.

    • Static edits and items pick up the optimization from r4941 to select
    annotations once, not once per layer.

Fetching an item with ~1000 annotations took ~1s without this patch,
~0.34s with this patch. Another item with ~6000 annotations took ~11.6s
before, ~8.6s after.

Because this block is moved out to the top:

if user and user.is_anonymous():
user = None

then, for anonymous users,

"editable": false,

is no longer included in the annotations. The old behaviour ended up
including this key in all layers listed before the first private layer
in the config, and leaving it out from later ones. So this new behaviour
is more consistent.
This commit is contained in:
Will Thompson 2015-09-14 14:06:43 +02:00 committed by j
parent 861be871d5
commit eebb0b5681
3 changed files with 36 additions and 53 deletions

View File

@ -11,6 +11,36 @@ from archive import extract
import managers
def get_layers(item, interval=None, user=None):
from annotation.models import Annotation
if user and user.is_anonymous():
user = None
layers = {}
private = []
for l in settings.CONFIG['layers']:
name = l['id']
layers[name] = []
if l.get('private'):
private.append(name)
qs = Annotation.objects.filter(item=item).exclude(value='')
qs = qs.order_by('start', 'end', 'sortvalue')
if interval:
start, end = interval
qs = qs.filter(start__lt=end, end__gt=start)
for a in qs.order_by('start').select_related('user'):
if a.layer in private:
if a.user == user:
layers[a.layer].append(a.json(user=user))
else:
layers[a.layer].append(a.json(user=user))
return layers
class MetaClip:
def update_calculated_values(self):
start = self.start
@ -113,27 +143,7 @@ class MetaClip:
return data
def get_layers(self, user=None):
from annotation.models import Annotation
start = self.start
end = self.end
item = self.item
layers = {}
private = []
for l in settings.CONFIG['layers']:
name = l['id']
layers[name] = []
if l.get('private'):
private.append(name)
qs = Annotation.objects.filter(item=item).exclude(value='')
qs = qs.order_by('start', 'end', 'sortvalue')
qs = qs.filter(start__lt=end, end__gt=start)
for a in qs.order_by('start'):
if a.layer in private:
if a.user == user:
layers[a.layer].append(a.json(user=user))
else:
layers[a.layer].append(a.json(user=user))
return layers
return get_layers(item=self.item, interval=(self.start, self.end), user=user)
@classmethod
def get_or_create(cls, item, start, end):

View File

@ -511,22 +511,8 @@ class Clip(models.Model):
start = self.start
end = self.end
item = self.item
layers = {}
for l in settings.CONFIG['layers']:
name = l['id']
ll = layers.setdefault(name, [])
qs = Annotation.objects.filter(layer=name, item=item).order_by(
'start', 'end', 'sortvalue')
if name == 'subtitles':
qs = qs.exclude(value='')
qs = qs.filter(start__lt=end, end__gt=start)
if l.get('private'):
if user and user.is_anonymous():
user = None
qs = qs.filter(user=user)
for a in qs.order_by('start').select_related('user'):
ll.append(a.json(user=user))
return layers
return clip.models.get_layers(item=item, interval=(start, end), user=user)
class Position(models.Model):

View File

@ -34,7 +34,7 @@ from data_api import external_data
from annotation.models import Annotation
from archive import extract
from clip.models import Clip
from clip.models import Clip, get_layers
from person.models import get_name_sort
from sequence.tasks import get_sequences
from title.models import get_title_sort
@ -547,21 +547,8 @@ class Item(models.Model):
return s.json()
def get_layers(self, user=None):
layers = {}
for l in settings.CONFIG['layers']:
name = l['id']
ll = layers.setdefault(name, [])
qs = Annotation.objects.filter(layer=name, item=self).order_by(
'start', 'end', 'sortvalue')
qs = qs.exclude(value='')
if l.get('private'):
if user and user.is_anonymous():
user = None
qs = qs.filter(user=user)
for a in qs.order_by('start'):
ll.append(a.json(user=user))
return layers
return get_layers(item=self, user=user)
def get_documents(self, user=None):
qs = self.documents.all()
documents = [d.json(item=self) for d in qs]