def data_mart(self): ''' :return: active `DataMartModel` instance from context, if `data_mart` not set, try find object by parsing request ''' value = self.data_mart_pk if value is not None: key = 'pk' # it was a string, not an int. Try find object by `slug` try: value = int(value) except ValueError: key = 'slug' return get_object_or_404(DataMartModel.objects.active(), **{key: value}) return None
def data_mart(self): ''' :return: active `DataMartModel` instance from `self.data_mart_id` ''' value = self.data_mart_id if value is not None: key = 'pk' # it was a string, not an int. Try find object by `slug` try: value = int(value) except ValueError: key = 'slug' return get_object_or_404(DataMartModel.objects.active(), **{key: value}) return None
def tree(self, request, data_mart_pk=None, *args, **kwargs): if data_mart_pk is not None: request.GET.setdefault('parent_id', data_mart_pk) value = request.query_params.get('parent_id', None) if value is not None: # try find object by `slug` try: value = int(value) except ValueError: # it was a string, not an int. if value.lower() in ('none', 'null'): queryset = DataMartModel.objects.toplevel() else: queryset = get_object_or_404(DataMartModel.objects.all(), slug=value).get_children() else: queryset = get_object_or_404(DataMartModel.objects.all(), pk=value).get_children() else: queryset = DataMartModel.objects.toplevel() serializer = DataMartTreeSerializer(queryset, many=True, context={"request": request}) return Response(serializer.data)
def check_permissions(self, request): """ Check if the request should be permitted. Raises an appropriate exception if the request is not permitted. """ try: request.GET['_mutable'] = True except AttributeError: request.GET = request.GET.copy() request.GET['_data_mart'] = None request.GET['_data_mart_permissions'] = { 'can_add': False, 'can_change': False, 'can_delete': False, 'has_owner': False } model_class = EntityModel if self.action in ('retrieve', 'update', 'partial_update', 'destroy'): obj = self.get_object() model_class = obj.__class__ elif self.action in ('create', 'list', 'bulk_update', 'partial_bulk_update', 'bulk_destroy'): value = self.kwargs.get('data_mart_pk', request.GET.get('data_mart_pk', None)) if value is not None: key = 'pk' # it was a string, not an int. Try find object by `slug` try: value = int(value) except ValueError: key = 'slug' request.GET['_data_mart'] = data_mart = get_object_or_404( DataMartModel.objects.active(), **{key: value}) # check data mart permissions if self.action != 'list': request.GET['_data_mart_permissions'] = data_mart_permissions = \ data_mart.get_permissions_from_request(request) if (self.action == 'create' and not data_mart_permissions['can_add'] or self.action in ('bulk_update', 'partial_bulk_update') and not data_mart_permissions['can_change'] or self.action == 'bulk_destroy' and not data_mart_permissions['can_delete']): self.permission_denied(request) # set model class model_class = data_mart.entities_model else: # в случаи списка пытаемся определить модель по полю 'entity_model' первого элемента if isinstance(request.data, list): entity_model = request.data[0].get( 'entity_model', None) if len(request.data) else None else: entity_model = request.data.get('entity_model', None) # пытаемся определить модель по параметру 'entity_model' словаря GET if entity_model is None: entity_model = request.GET.get('entity_model', None) if entity_model is not None: try: model_class = apps.get_model( EntityModel._meta.app_label, str(entity_model)) except LookupError: pass permissions = [ permission() for permission in model_class._rest_meta.permission_classes ] if not permissions: permissions = self.get_permissions() for permission in permissions: if not permission.has_permission(request, self): self.permission_denied(request, message=getattr(permission, 'message', None))
def filter_queryset(self, request, queryset, view): alike = self.get_alike_param(request, view) data_mart = request.GET['_data_mart'] annotation_meta, aggregation_meta = None, None # annotation if view.action == 'list' or alike is not None: if alike is True: # Perform the lookup filtering. lookup_url_kwarg = view.lookup_url_kwarg or view.lookup_field assert lookup_url_kwarg in view.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (view.__class__.__name__, lookup_url_kwarg)) filter_kwargs = { view.lookup_field: view.kwargs[lookup_url_kwarg] } obj = get_object_or_404(queryset, **filter_kwargs) model_class = obj.__class__ else: model_class = data_mart.entities_model if data_mart is not None else queryset.model annotation = model_class.get_summary_annotation(request) if isinstance(annotation, dict): annotation_meta, annotate_kwargs = {}, {} for key, value in annotation.items(): if isinstance(value, (tuple, list)): annotate = value[0] if isinstance(annotate, BaseExpression): annotate_kwargs[key] = annotate n = len(value) if n > 1: field = value[1] if isinstance(field, six.string_types): field = import_string(field)() name = value[2] if n > 2 else None annotation_meta[key] = (annotate, field, name) else: assert isinstance(value, BaseExpression), ( "value getting from dictionary key '%s' should be instance of a class or of a subclass `BaseExpression`" % key) annotate_kwargs[key] = value if annotate_kwargs: queryset = queryset.annotate(**annotate_kwargs) else: model_class = queryset.model if view.action in ("bulk_update", "partial_bulk_update"): if data_mart is not None: model_class = data_mart.entities_model else: # в случаи списка пытаемся определить модель по полю 'entity_model' первого элемента if isinstance(request.data, list): entity_model = request.data[0].get( 'entity_model', None) if len( request.data) else None else: entity_model = request.data.get('entity_model', None) # пытаемся определить модель по параметру 'entity_model' словаря GET if entity_model is None: entity_model = request.GET.get('entity_model', None) if entity_model is not None: try: model_class = apps.get_model( EntityModel._meta.app_label, str(entity_model)) except LookupError: pass # modify queryset for `bulk_update` and `partial_bulk_update` queryset = model_class.objects.filter( id__in=queryset.values_list('id', flat=True)) # aggregation if view.action == 'list': aggregation = model_class.get_summary_aggregation(request) if isinstance(aggregation, dict): aggregation_meta = OrderedDict() for key, value in aggregation.items(): assert isinstance(value, (tuple, list)), ( "type of value getting from dictionary key '%s' should be `tuple` or `list`" % key) aggregate = value[0] n = len(value) if n > 1: field = value[1] if isinstance(field, six.string_types): field = import_string(field)() name = value[2] if n > 2 else None else: field, name = None, None aggregation_meta[key] = (aggregate, field, name) request.GET.update({ '_annotation_meta': annotation_meta, '_aggregation_meta': aggregation_meta, '_filter_queryset': queryset, '_alike': alike, '_alike_param': self.alike_param, '_entity_model': model_class }) # select view component raw_view_component = request.GET.get('view_component', None) if raw_view_component is None: raw_view_component = get_data_mart_cookie_setting( request, "view_component") if raw_view_component is None: view_component = data_mart.view_component if data_mart is not None else None else: view_component = serializers.CharField().to_internal_value( raw_view_component) request.GET['_view_component'] = view_component return queryset