CrudBuilderRegistry.extract_args()   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 16
rs 9.4285
cc 3
1
from django.db import models
2
3
from crudbuilder.exceptions import (
4
    NotModelException,
5
    AlreadyRegistered,
6
    NotRegistered
7
)
8
9
from crudbuilder import helpers
10
11
__all__ = ('CrudBuilderRegistry', 'register', 'registry')
12
13
14
class CrudBuilderRegistry(dict):
15
    """Dictionary like object representing a collection of objects."""
16
17
    @classmethod
18
    def extract_args(cls, *args):
19
        """
20
        Takes any arguments like a model and crud, or just one of
21
        those, in any order, and return a model and crud.
22
        """
23
        model = None
24
        crudbuilder = None
25
26
        for arg in args:
27
            if issubclass(arg, models.Model):
28
                model = arg
29
            else:
30
                crudbuilder = arg
31
32
        return [model, crudbuilder]
33
34
    def register(self, *args, **kwargs):
35
        """
36
        Register a crud.
37
38
        Two unordered arguments are accepted, at least one should be passed:
39
        - a model,
40
        - a crudbuilder class
41
        """
42
43
        assert len(args) <= 2, 'register takes at most 2 args'
44
        assert len(args) > 0, 'register takes at least 1 arg'
45
46
        model, crudbuilder = self.__class__.extract_args(*args)
47
48
        if not issubclass(model, models.Model):
49
            msg = "First argument should be Django Model"
50
            raise NotModelException(msg)
51
52
        key = self._model_key(model, crudbuilder)
53
54
        if key in self:
55
            msg = "Key '{key}' has already been registered.".format(
56
                key=key
57
            )
58
            raise AlreadyRegistered(msg)
59
60
        self.__setitem__(key, crudbuilder)
61
        return crudbuilder
62
63
    def _model_key(self, model, crudbuilder):
64
        app_label = model._meta.app_label
65
        model_name = model.__name__.lower()
66
        postfix_url = helpers.custom_postfix_url(crudbuilder(), model_name)
67
        return '{}-{}-{}'.format(app_label, model_name, postfix_url)
68
69
    def unregister(self, model):
70
        key = self._model_key(model)
71
        if key in self:
72
            self.__delitem__(key)
73
74
    def __getitem__(self, name):
75
        """
76
        Return the CrudBuilder class registered for this name. If none is
77
        registered, raise NotRegistered.
78
        """
79
        try:
80
            return super(CrudBuilderRegistry, self).__getitem__(name)
81
        except KeyError:
82
            raise NotRegistered(name, self)
83
84
85
registry = CrudBuilderRegistry()
86
87
88
def register(*args, **kwargs):
89
    """
90
    Proxy method :py:meth:`CrudBuilderRegistry.register` of the
91
    :py:data:`registry` module level instance.
92
    """
93
    return registry.register(*args, **kwargs)
94