Ejemplo n.º 1
0
    def get(self, request):

        model = self.queryset.model
        content_type = ContentType.objects.get_for_model(model)

        if self.filterset:
            self.queryset = self.filterset(request.GET, self.queryset).qs

        # If this type of object has one or more custom fields, prefetch any relevant custom field values
        custom_fields = CustomField.objects.filter(
            obj_type=ContentType.objects.get_for_model(
                model)).prefetch_related('choices')
        if custom_fields:
            self.queryset = self.queryset.prefetch_related(
                'custom_field_values')

        # Check for export template rendering
        if request.GET.get('export'):
            et = get_object_or_404(ExportTemplate,
                                   content_type=content_type,
                                   name=request.GET.get('export'))
            queryset = CustomFieldQueryset(
                self.queryset,
                custom_fields) if custom_fields else self.queryset
            try:
                return et.render_to_response(queryset)
            except Exception as e:
                messages.error(
                    request,
                    "There was an error rendering the selected export template ({}): {}"
                    .format(et.name, e))

        # Check for YAML export support
        elif 'export' in request.GET and hasattr(model, 'to_yaml'):
            response = HttpResponse(self.queryset_to_yaml(),
                                    content_type='text/yaml')
            filename = 'netbox_{}.yaml'.format(
                self.queryset.model._meta.verbose_name_plural)
            response[
                'Content-Disposition'] = 'attachment; filename="{}"'.format(
                    filename)
            return response

        # Fall back to built-in CSV formatting if export requested but no template specified
        elif 'export' in request.GET and hasattr(model, 'to_csv'):
            response = HttpResponse(self.queryset_to_csv(),
                                    content_type='text/csv')
            filename = 'netbox_{}.csv'.format(
                self.queryset.model._meta.verbose_name_plural)
            response[
                'Content-Disposition'] = 'attachment; filename="{}"'.format(
                    filename)
            return response

        # Provide a hook to tweak the queryset based on the request immediately prior to rendering the object list
        self.queryset = self.alter_queryset(request)

        # Compile a dictionary indicating which permissions are available to the current user for this model
        permissions = {}
        for action in ('add', 'change', 'delete', 'view'):
            perm_name = '{}.{}_{}'.format(model._meta.app_label, action,
                                          model._meta.model_name)
            permissions[action] = request.user.has_perm(perm_name)

        # Construct the table based on the user's permissions
        if request.user.is_authenticated:
            columns = request.user.config.get(
                f"tables.{self.table.__name__}.columns")
        else:
            columns = None
        table = self.table(self.queryset, columns=columns)
        if 'pk' in table.base_columns and (permissions['change']
                                           or permissions['delete']):
            table.columns.show('pk')

        # Apply the request context
        paginate = {
            'paginator_class': EnhancedPaginator,
            'per_page': get_paginate_count(request)
        }
        RequestConfig(request, paginate).configure(table)

        context = {
            'content_type':
            content_type,
            'table':
            table,
            'permissions':
            permissions,
            'action_buttons':
            self.action_buttons,
            'table_config_form':
            TableConfigForm(table=table),
            'filter_form':
            self.filterset_form(request.GET, label_suffix='')
            if self.filterset_form else None,
        }
        context.update(self.extra_context())

        return render(request, self.template_name, context)
Ejemplo n.º 2
0
    def get(self, request):

        model = self.queryset.model
        content_type = ContentType.objects.get_for_model(model)

        if self.filter:
            self.queryset = self.filter(request.GET, self.queryset).qs

        # If this type of object has one or more custom fields, prefetch any relevant custom field values
        custom_fields = CustomField.objects.filter(
            obj_type=ContentType.objects.get_for_model(
                model)).prefetch_related('choices')
        if custom_fields:
            self.queryset = self.queryset.prefetch_related(
                'custom_field_values')

        # Check for export template rendering
        if request.GET.get('export'):
            et = get_object_or_404(ExportTemplate,
                                   content_type=content_type,
                                   name=request.GET.get('export'))
            queryset = CustomFieldQueryset(
                self.queryset,
                custom_fields) if custom_fields else self.queryset
            try:
                return et.render_to_response(queryset)
            except Exception as e:
                messages.error(
                    request,
                    "There was an error rendering the selected export template ({}): {}"
                    .format(et.name, e))

        # Fall back to built-in CSV formatting if export requested but no template specified
        elif 'export' in request.GET and hasattr(model, 'to_csv'):
            data = self.queryset_to_csv()
            response = HttpResponse('\n'.join(data), content_type='text/csv')
            filename = 'netbox_{}.csv'.format(
                self.queryset.model._meta.verbose_name_plural)
            response[
                'Content-Disposition'] = 'attachment; filename="{}"'.format(
                    filename)
            return response

        # Provide a hook to tweak the queryset based on the request immediately prior to rendering the object list
        self.queryset = self.alter_queryset(request)

        # Compile user model permissions for access from within the template
        perm_base_name = '{}.{{}}_{}'.format(model._meta.app_label,
                                             model._meta.model_name)
        permissions = {
            p: request.user.has_perm(perm_base_name.format(p))
            for p in ['add', 'change', 'delete']
        }

        # Construct the table based on the user's permissions
        table = self.table(self.queryset)
        if 'pk' in table.base_columns and (permissions['change']
                                           or permissions['delete']):
            table.columns.show('pk')

        # Construct queryset for tags list
        if hasattr(model, 'tags'):
            tags = model.tags.annotate(
                count=Count('extras_taggeditem_items')).order_by('name')
        else:
            tags = None

        # Apply the request context
        paginate = {
            'paginator_class': EnhancedPaginator,
            'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
        }
        RequestConfig(request, paginate).configure(table)

        context = {
            'content_type':
            content_type,
            'table':
            table,
            'permissions':
            permissions,
            'filter_form':
            self.filter_form(request.GET, label_suffix='')
            if self.filter_form else None,
            'tags':
            tags,
        }
        context.update(self.extra_context())

        return render(request, self.template_name, context)