コード例 #1
0
ファイル: utils.py プロジェクト: ella/ella-newman
def user_category_filter(queryset, user):
    """
    Returns Queryset containing only user's prefered content (filtering based on categories).
    If queryset.model has no relation to ella.core.models.Category, original queryset is returned.
    """
    from ella_newman.permission import model_category_fk, is_category_model
    qs = queryset
    category_fk = model_category_fk(qs.model)
    if not category_fk:
        return qs
    root_category_ids = get_user_config(user, newman_settings.CATEGORY_FILTER)
    if not root_category_ids: # user has no custom category filter set or his filter set is empty.
        return qs
    if not user.is_superuser:
        helper = models.DenormalizedCategoryUserRole.objects.filter(
            user_id=user.pk,
            root_category_id__in=root_category_ids
        ).values('category_id')
        user_categories = [c['category_id'] for c in helper]
        if is_category_model(qs.model):
            lookup = 'id__in'
        else:
            lookup = '%s__in' % category_fk.name
        out = qs.filter(**{lookup: user_categories})
    else:
        cats = Category.objects.filter(pk__in=root_category_ids).values('site__pk')
        user_sites = [c['site__pk'] for c in cats]
        if is_category_model(qs.model):
            lookup = 'site__id__in'
        else:
            lookup = '%s__site__id__in' % category_fk.name
        out = qs.filter(**{lookup: user_sites})
    flag_queryset(out, 'user_category_filtered', True)
    return out
コード例 #2
0
def user_category_filter(queryset, user):
    """
    Returns Queryset containing only user's prefered content (filtering based on categories).
    If queryset.model has no relation to ella.core.models.Category, original queryset is returned.
    """
    from ella_newman.permission import model_category_fk, is_category_model
    qs = queryset
    category_fk = model_category_fk(qs.model)
    if not category_fk:
        return qs
    root_category_ids = get_user_config(user, newman_settings.CATEGORY_FILTER)
    if not root_category_ids:  # user has no custom category filter set or his filter set is empty.
        return qs
    if not user.is_superuser:
        helper = models.DenormalizedCategoryUserRole.objects.filter(
            user_id=user.pk,
            root_category_id__in=root_category_ids).values('category_id')
        user_categories = [c['category_id'] for c in helper]
        if is_category_model(qs.model):
            lookup = 'id__in'
        else:
            lookup = '%s__in' % category_fk.name
        out = qs.filter(**{lookup: user_categories})
    else:
        cats = Category.objects.filter(
            pk__in=root_category_ids).values('site__pk')
        user_sites = [c['site__pk'] for c in cats]
        if is_category_model(qs.model):
            lookup = 'site__id__in'
        else:
            lookup = '%s__site__id__in' % category_fk.name
        out = qs.filter(**{lookup: user_sites})
    flag_queryset(out, 'user_category_filtered', True)
    return out
コード例 #3
0
ファイル: options.py プロジェクト: ella/ella-newman
    def suggest_view(self, request, extra_context=None):
        self.register_newman_variables(request)

        if not ('f' in request.GET.keys() and 'q' in request.GET.keys()):
            raise AttributeError, 'Invalid query attributes. Example: ".../?f=field_a&f=field_b&q=search_term&o=offset"'
        elif len(request.GET.get('q')) < newman_settings.SUGGEST_VIEW_MIN_LENGTH:
            return HttpResponse( '', mimetype='text/plain;charset=utf-8' )

        offset = 0
        if 'o' in request.GET.keys() and request.GET.get('o'):
            offset = int(request.GET.get('o'))
        limit = offset + newman_settings.SUGGEST_VIEW_LIMIT

        model_fields = [mf.name for mf in self.model._meta.fields]
        lookup_fields = []
        lookup_value = request.GET.get('q')
        lookup = None
        has_non_lookup_attr = False
        all_fields = [u'id'] + request.GET.getlist('f')

        for lf in all_fields:
            if lf in model_fields or lf.split('__')[0] in model_fields:
                lookup_fields.append(lf)
            elif hasattr(self.model, lf):
                has_non_lookup_attr = True
            else:
                raise AttributeError, 'Model "%s" has not field "%s". Possible fields are "%s".' \
                                    % (self.model._meta.object_name, lf, ', '.join(model_fields))

        for f in lookup_fields:
            lookup_key = str('%s__icontains' % f)
            if not lookup:
                lookup = models.Q(**{lookup_key: lookup_value})
            else:
                lookup = lookup | models.Q(**{lookup_key: lookup_value})
        # user role based category filtering
        if not is_category_model(self.model):
            category_field = model_category_fk(self.model)
            if category_field and request.user:
                applicable = applicable_categories(request.user)
                args_lookup = { '%s__in' % category_field.name: applicable}
                lookup = lookup & models.Q(**args_lookup)
        else:
            applicable = applicable_categories(request.user)
            lookup = lookup & models.Q(pk__in=applicable)
        # user category filter
        qs = utils.user_category_filter(self.model.objects.filter(lookup), request.user)

        if not has_non_lookup_attr:
            data = qs.values(*lookup_fields)
        else:
            data = qs.only(*lookup_fields)

        def construct_row(inst, fields):
            row = {}
            for f in fields:
                attr = getattr(inst, f)
                if callable(attr):
                    row[f] = attr()
                else:
                    row[f] = attr
                row[f] = truncatewords(striptags(unicode(row[f])), 5)
            return row

        if has_non_lookup_attr:
            outdata = []
            for i in data:
                outdata.append(construct_row(i, all_fields))
            data = outdata

        # sort the suggested items so that those starting with the sought term come first
        def compare(a,b):
            def _cmp(a,b,sought):
                a_starts = unicode(a).lower().startswith(sought)
                b_starts = unicode(b).lower().startswith(sought)
                # if exactly one of (a,b) starts with sought, the one starting with it comes first
                if a_starts ^ b_starts:
                    if a_starts: return -1
                    if b_starts: return +1
                # else compare lexicographically
                return cmp(a,b)
            return _cmp(a,b,unicode(lookup_value).lower())
        cnt = len(data)
        data = list(data)
        if offset >= len(data): return HttpResponse('SPECIAL: OFFSET OUT OF RANGE', mimetype='text/plain')
        data.sort(cmp=compare, key=lambda x: x[lookup_fields[1]])
        data = data[offset:limit]

        ft = []
        ft.append('{cnt:%d}' % cnt)
        for item in data:
            ft.append( "%s".encode('utf-8') % '|'.join("%s" % item[f] for f in all_fields) )

        return HttpResponse( '\n'.join(ft), mimetype='text/plain;charset=utf-8' )
コード例 #4
0
    def suggest_view(self, request, extra_context=None):
        self.register_newman_variables(request)

        if not ('f' in request.GET.keys() and 'q' in request.GET.keys()):
            raise AttributeError, 'Invalid query attributes. Example: ".../?f=field_a&f=field_b&q=search_term&o=offset"'
        elif len(request.GET.get(
                'q')) < newman_settings.SUGGEST_VIEW_MIN_LENGTH:
            return HttpResponse('', mimetype='text/plain;charset=utf-8')

        offset = 0
        if 'o' in request.GET.keys() and request.GET.get('o'):
            offset = int(request.GET.get('o'))
        limit = offset + newman_settings.SUGGEST_VIEW_LIMIT

        model_fields = [mf.name for mf in self.model._meta.fields]
        lookup_fields = []
        lookup_value = request.GET.get('q')
        lookup = None
        has_non_lookup_attr = False
        all_fields = [u'id'] + request.GET.getlist('f')

        for lf in all_fields:
            if lf in model_fields or lf.split('__')[0] in model_fields:
                lookup_fields.append(lf)
            elif hasattr(self.model, lf):
                has_non_lookup_attr = True
            else:
                raise AttributeError, 'Model "%s" has not field "%s". Possible fields are "%s".' \
                                    % (self.model._meta.object_name, lf, ', '.join(model_fields))

        for f in lookup_fields:
            lookup_key = str('%s__icontains' % f)
            if not lookup:
                lookup = models.Q(**{lookup_key: lookup_value})
            else:
                lookup = lookup | models.Q(**{lookup_key: lookup_value})
        # user role based category filtering
        if not is_category_model(self.model):
            category_field = model_category_fk(self.model)
            if category_field and request.user:
                applicable = applicable_categories(request.user)
                args_lookup = {'%s__in' % category_field.name: applicable}
                lookup = lookup & models.Q(**args_lookup)
        else:
            applicable = applicable_categories(request.user)
            lookup = lookup & models.Q(pk__in=applicable)
        # user category filter
        qs = utils.user_category_filter(self.model.objects.filter(lookup),
                                        request.user)

        if not has_non_lookup_attr:
            data = qs.values(*lookup_fields)
        else:
            data = qs.only(*lookup_fields)

        def construct_row(inst, fields):
            row = {}
            for f in fields:
                attr = getattr(inst, f)
                if callable(attr):
                    row[f] = attr()
                else:
                    row[f] = attr
                row[f] = truncatewords(striptags(unicode(row[f])), 5)
            return row

        if has_non_lookup_attr:
            outdata = []
            for i in data:
                outdata.append(construct_row(i, all_fields))
            data = outdata

        # sort the suggested items so that those starting with the sought term come first
        def compare(a, b):
            def _cmp(a, b, sought):
                a_starts = unicode(a).lower().startswith(sought)
                b_starts = unicode(b).lower().startswith(sought)
                # if exactly one of (a,b) starts with sought, the one starting with it comes first
                if a_starts ^ b_starts:
                    if a_starts: return -1
                    if b_starts: return +1
                # else compare lexicographically
                return cmp(a, b)

            return _cmp(a, b, unicode(lookup_value).lower())

        cnt = len(data)
        data = list(data)
        if offset >= len(data):
            return HttpResponse('SPECIAL: OFFSET OUT OF RANGE',
                                mimetype='text/plain')
        data.sort(cmp=compare, key=lambda x: x[lookup_fields[1]])
        data = data[offset:limit]

        ft = []
        ft.append('{cnt:%d}' % cnt)
        for item in data:
            ft.append("%s".encode('utf-8') % '|'.join("%s" % item[f]
                                                      for f in all_fields))

        return HttpResponse('\n'.join(ft), mimetype='text/plain;charset=utf-8')