def queryset(self, request): """ First semi-working draft of category-based permissions. It will allow permissions to be set per category effectively hiding the content the user has no permission to see/change. """ # return cached queryset, if possible if self._cached_queryset_request_id == id(request) and type(self._cached_queryset) != type(None): return self._cached_queryset q = super(NewmanModelAdmin, self).queryset(request) # user category filter qs = utils.user_category_filter(q, request.user) # if self.model is licensed filter queryset if License._meta.installed: exclude_pks = License.objects.unapplicable_for_model(self.model) qs_tmp = qs.exclude(pk__in=exclude_pks) utils.copy_queryset_flags(qs_tmp, qs) qs = qs_tmp if request.user.is_superuser: return qs view_perm = self.opts.app_label + '.' + 'view_' + self.model._meta.module_name.lower() change_perm = self.opts.app_label + '.' + 'change_' + self.model._meta.module_name.lower() perms = (view_perm, change_perm,) # return permission_filtered_model_qs(qs, request.user, perms) qs_tmp = permission_filtered_model_qs(qs, request.user, perms) utils.copy_queryset_flags(qs_tmp, qs) # cache the result self._cached_queryset_request_id = id(request) self._cached_queryset = qs_tmp return qs_tmp
def filter_func(self): qs = Category.objects.filter(pk__in=applicable_categories(self.user)) lookup_var = self.get_lookup_kwarg() for cat in user_category_filter(qs, self.user): link = ( cat, {lookup_var: cat.pk}) self.links.append(link) return True
def newman_index(self, request, extra_context=None): def translate_and_upper(text): return ugettext(text).upper() """ Displays the main Newman index page, without installed apps. """ data = {'sites': []} try: data['sites'] = get_user_config(request.user, newman_settings.CATEGORY_FILTER) except KeyError: data['sites'] = [] publishable_lookup_fields = { 'day': 'publish_from__day', 'month': 'publish_from__month', 'year': 'publish_from__year' } site_filter_form = SiteFilterForm(data=data, user=request.user) if site_filter_form.sites_count == 1: site_filter_form = None cts = [] last_filters = {} for model, model_admin in self._registry.items(): if has_model_list_permission(request.user, model) and model_admin.search_fields: ct = ContentType.objects.get_for_model(model) cts.append(ct) # Load saved filter configurations for changelists key = 'filter__%s__%s' % (ct.app_label, ct.model) last_filter = AdminSetting.objects.filter(var=key, user=request.user) if last_filter: last_filters[key] = '?%s' % json_decode(last_filter[0].value) future_qs = Publishable.objects.select_related().filter(publish_from__gt=datetime.datetime.now()).order_by('publish_from', 'category__tree_path') future_qs_perm = permission_filtered_model_qs(future_qs, request.user) future_publishables = user_category_filter(future_qs_perm, request.user) cts.sort( lambda a, b: cmp(translate_and_upper(a.name), translate_and_upper(b.name)) ) context = { 'title': _('Site administration'), 'site_filter_form': site_filter_form, 'searchable_content_types': cts, 'last_filters': last_filters, 'future_publishables': future_publishables, 'publishable_lookup_fields': publishable_lookup_fields, 'show_calendar': has_model_list_permission(request.user, Publishable), } context.update(extra_context or {}) return render_to_response('newman/newman-index.html', context, context_instance=template.RequestContext(request) )
def get_queryset(self): # Avoid a circular import. from django.contrib.contenttypes.models import ContentType user = self.form._magic_user if self.instance is None: return self.model._default_manager.empty() out = self.model._default_manager.filter(**{ self.ct_field.name: ContentType.objects.get_for_model(self.instance), self.ct_fk_field.name: self.instance.pk, }) if user.is_superuser: return out # filtering -- view permitted categories only cfield = model_category_fk_value(self.model) if not cfield: return out # self.instance .. Article, self.model .. Placement (in GenericInlineFormSet for Placement Inline) view_perm = get_permission('view', self.model) change_perm = get_permission('change', self.model) perms = (view_perm, change_perm,) qs = permission_filtered_model_qs(out, user, perms) qs = utils.user_category_filter(qs, user) return qs
def get_queryset(self): user = self.form._magic_user if not hasattr(self, '_queryset'): if self.queryset is not None: qs = self.queryset else: qs = self.model._default_manager.get_query_set() # category based permissions if not user.is_superuser: category_fk = model_category_fk(self.model) if category_fk: # in ListingInlineOptions: self.instance .. Placement instance, self.model .. Listing view_perm = get_permission('view', self.model) change_perm = get_permission('change', self.model) perms = (view_perm, change_perm,) qs = permission_filtered_model_qs(qs, user, perms) # user filtered categories qs = utils.user_category_filter(qs, user) if self.max_num > 0: self._queryset = qs[:self.max_num] else: self._queryset = qs return self._queryset
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' )