src/protocols/models/managers.py
author ymh <ymh.work@gmail.com>
Fri, 30 Nov 2018 10:53:15 +0100
changeset 183 f8f3af9e5c83
parent 142 56850f5c73f6
permissions -rw-r--r--
Change the settings to avoid using Session authentication for rest framework as it raise exceptions in case client and backend are on the same domain On the filter, adapt to take into account new version of django_filters
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
142
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
import logging
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
import uuid
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
from django.apps import apps
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
from django.core.exceptions import ValidationError
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
from django.db import models, transaction
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
logger = logging.getLogger(__name__)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
class ProtocolManager(models.Manager):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
    #TODO: check id must be the same
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
    #TODO: check owner must be the same
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
    @transaction.atomic
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
    def create_new_revision(self, protocol_id, revision_def, app):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
        # lock the protocol
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
        owner = revision_def.get('owner', None)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
        if not owner:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
            raise ValidationError("Must have an owner")
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
        last_revision_modified = False
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
        if protocol_id is None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
            protocol = self.model(app=app, owner=owner)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
            protocol.save()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
            protocol_revision_model = apps.get_model(app_label='protocols', model_name='ProtocolRevision')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
            last_revision = protocol_revision_model(protocol=protocol)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
            last_revision_modified = True
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        else:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
            protocol = self.select_for_update().get(ext_id=protocol_id, app=app)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
            revision_nb = revision_def.get('version')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
            last_revision = protocol.last_revision()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
            if last_revision is not None and (revision_nb is None or revision_nb != last_revision.version):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
                raise ValidationError("Bad protocol revision number when creating new revision")
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        # create new protocol revision update protocol revision title and description
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
        title = revision_def.get('title', None)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
        description = revision_def.get('description', None)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
        last_revision_modified = last_revision_modified or \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
            (title != last_revision.title or description != last_revision.description)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
        metacategory_model = apps.get_model(app_label='protocols', model_name='Metacategory')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
        new_metacategories = [metacategory_model.objects.get_or_create_revision(app, **metacategory_def) for metacategory_def in revision_def.get('metacategories', [])]
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        if not last_revision_modified:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
            new_metacategories_ids = { mc.ext_id for mc in new_metacategories }
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
            old_metacategories_ids = { mc.ext_id for mc in last_revision.metacategories.all() }
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
            last_revision_modified = (new_metacategories_ids != old_metacategories_ids )
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
            if last_revision_modified:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
                logger.debug("metacategaories modified %r, %r", new_metacategories_ids, old_metacategories_ids)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
        if last_revision_modified:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
            last_revision.pk = None
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
            last_revision.ext_id = uuid.uuid4()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
            if title is not None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
                last_revision.title = title
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
            if description is not None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
                last_revision.description = description
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
            last_revision.save()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
            last_revision.metacategories.add(*new_metacategories)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
        return last_revision
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
    @transaction.atomic
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
    def create_from_default(self, title, description, owner, app):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        metacategory_model = apps.get_model(app_label='protocols', model_name='Metacategory')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        default_metacategories = metacategory_model.objects.filter(is_default=True, app=app)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        protocol = self.create(app=app, owner=owner)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        protocol_revision_model = apps.get_model(app_label='protocols', model_name='ProtocolRevision')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
        protocol_revision = protocol_revision_model.objects.create(protocol=protocol, title=title, description=description)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
        protocol_revision.metacategories.set([mc.revisions.all().last() for mc in default_metacategories])
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
        protocol_revision.save()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
        return protocol
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
class MetacategoryManager(models.Manager):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
    @transaction.atomic
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
    def create_with_revision(self, *args, **kwargs):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
        instance = self.create(*args, **kwargs)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
        metacategory_revision_model = apps.get_model(app_label='protocols', model_name='MetacategoryRevision')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        revision = metacategory_revision_model.objects.create(base=instance, **{k : kwargs.get(k) for k in ['title', 'label', 'description', 'color', 'has_comment']})
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        return instance
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
    @transaction.atomic
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
    def get_or_create_revision(self, app, **kwargs):
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
        # cases :
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
        # id: none, base: none
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
        #   -> create metacategory + revision
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        # id: <>, base: none
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        #   -> error
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
        # id: <>, base: <>
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
        #   -> compare filed values
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
        #   -> if same : return current instance, if not same : create new revision
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
        # id: none, base: <>
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
        #   -> compare to last revision. if different, create new revision else return revision
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
        id = kwargs.get('id')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
        base = kwargs.get('base')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
        if id is not None and base is None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
            raise ValidationError("Id is not empty and base is empty")
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
        metacategory = None
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
        metacategory_created = False
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
        if base is None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
            metacategory_created = True
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
            metacategory = self.model(
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
                app=app,
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
                title=kwargs.get('title'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
                label=kwargs.get('label'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
                description=kwargs.get('description'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
                color=kwargs.get('color'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
                has_comment=kwargs.get('has_comment', False),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
                is_default=False
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
            )
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
            metacategory.save()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
        else:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
            metacategory = self.get(ext_id=base, app=app)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
        revision = None
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
        metacategory_revision_model = apps.get_model(app_label='protocols', model_name='MetacategoryRevision')
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
        if id is None and not metacategory_created:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
            revision = metacategory.last_revision()
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
        elif not metacategory_created:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
            revision = metacategory_revision_model.objects.get(ext_id=id)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
        must_create_revision = (revision is None)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
        if revision is not None:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
            must_create_revision = \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
                (revision.title != kwargs.get('title')) or \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
                (revision.label != kwargs.get('label')) or \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
                (revision.description != kwargs.get('description')) or \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
                (revision.color != kwargs.get('color')) or \
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
                (revision.has_comment != kwargs.get('has_comment', False))
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
        if must_create_revision:
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
            revision = metacategory_revision_model.objects.create(
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
                base=metacategory,
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
                title=kwargs.get('title'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
                label=kwargs.get('label'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
                description=kwargs.get('description'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
                color=kwargs.get('color'),
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
                has_comment=kwargs.get('has_comment', False)
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
            )
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
56850f5c73f6 - upgrade libraries
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
        return revision