# -*- coding: utf-8 -*- # from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from .base import AssetUserQuerySet from .db import AuthBookBackend from .system_user import SystemUserBackend from .admin_user import AdminUserBackend class NotSupportError(Exception): pass class AssetUserManager: """ 资产用户管理器 """ ObjectDoesNotExist = ObjectDoesNotExist MultipleObjectsReturned = MultipleObjectsReturned NotSupportError = NotSupportError MSG_NOT_EXIST = '{} Object matching query does not exist' MSG_MULTIPLE = '{} get() returned more than one object ' \ '-- it returned {}!' backends = ( ('db', AuthBookBackend), ('system_user', SystemUserBackend), ('admin_user', AdminUserBackend), ) _prefer = "system_user" _using = None def filter(self, username=None, assets=None, latest=True): if assets is not None and not assets: return AssetUserQuerySet([]) if self._using: backend = dict(self.backends).get(self._using) if not backend: return self.none() instances = backend.filter(username=username, assets=assets, latest=latest) return AssetUserQuerySet(instances) instances_map = {} instances = [] for name, backend in self.backends: _instances = backend.filter( username=username, assets=assets, latest=latest ) instances_map[name] = _instances # 如果不是获取最新版本,就不再merge if not latest: for _instances in instances_map.values(): instances.extend(_instances) return AssetUserQuerySet(instances) # merge的顺序 ordering = ["db"] if self._prefer == "system_user": ordering.extend(["system_user", "admin_user"]) else: ordering.extend(["admin_user", "system_user"]) # 根据prefer决定优先使用系统用户或管理用户谁的 ordering_instances = [instances_map.get(i) for i in ordering] instances = self._merge_instances(*ordering_instances) return AssetUserQuerySet(instances) def get(self, username, asset): instances = self.filter(username, assets=[asset]) if len(instances) == 1: return instances[0] elif len(instances) == 0: self.raise_does_not_exist(self.__name__) else: self.raise_multiple_return(self.__name__, len(instances)) def raise_does_not_exist(self, name): raise self.ObjectDoesNotExist(self.MSG_NOT_EXIST.format(name)) def raise_multiple_return(self, name, length): raise self.MultipleObjectsReturned(self.MSG_MULTIPLE.format(name, length)) @staticmethod def create(**kwargs): instance = AuthBookBackend.create(**kwargs) return instance def all(self): return self.filter() def prefer(self, s): self._prefer = s return self def using(self, s): self._using = s return self @staticmethod def none(): return AssetUserQuerySet() @staticmethod def _merge_instances(*args): instances = list(args[0]) keywords = [obj.keyword for obj in instances] for _instances in args[1:]: need_merge_instances = [obj for obj in _instances if obj.keyword not in keywords] need_merge_keywords = [obj.keyword for obj in need_merge_instances] instances.extend(need_merge_instances) keywords.extend(need_merge_keywords) return instances