1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #3190: Fix custom field rendering for Jinja2 export templates

This commit is contained in:
Jeremy Stretch
2019-05-16 19:45:36 -04:00
parent 62d497dd0b
commit 2f32488c25
4 changed files with 25 additions and 21 deletions

View File

@ -6,6 +6,7 @@
* [#3150](https://github.com/digitalocean/netbox/issues/3150) - Fix formatting of cable length during cable trace * [#3150](https://github.com/digitalocean/netbox/issues/3150) - Fix formatting of cable length during cable trace
* [#3085](https://github.com/digitalocean/netbox/issues/3085) - Catch all exceptions during export template rendering * [#3085](https://github.com/digitalocean/netbox/issues/3085) - Catch all exceptions during export template rendering
* [#3186](https://github.com/digitalocean/netbox/issues/3186) - Add interface name filter for IP addresses * [#3186](https://github.com/digitalocean/netbox/issues/3186) - Add interface name filter for IP addresses
* [#3190](https://github.com/digitalocean/netbox/issues/3190) - Fix custom field rendering for Jinja2 export templates
## Bug Fixes ## Bug Fixes

View File

@ -106,6 +106,7 @@ class CustomFieldModel(models.Model):
class Meta: class Meta:
abstract = True abstract = True
@property
def cf(self): def cf(self):
""" """
Name-based CustomFieldValue accessor for use in templates Name-based CustomFieldValue accessor for use in templates

View File

@ -1,6 +1,24 @@
from collections import OrderedDict
from django.db.models import Q, QuerySet from django.db.models import Q, QuerySet
class CustomFieldQueryset:
"""
Annotate custom fields on objects within a QuerySet.
"""
def __init__(self, queryset, custom_fields):
self.queryset = queryset
self.model = queryset.model
self.custom_fields = custom_fields
def __iter__(self):
for obj in self.queryset:
values_dict = {cfv.field_id: cfv.value for cfv in obj.custom_field_values.all()}
obj.custom_fields = OrderedDict([(field, values_dict.get(field.pk)) for field in self.custom_fields])
yield obj
class ConfigContextQuerySet(QuerySet): class ConfigContextQuerySet(QuerySet):
def get_for_object(self, obj): def get_for_object(self, obj):

View File

@ -1,5 +1,4 @@
import sys import sys
from collections import OrderedDict
from copy import deepcopy from copy import deepcopy
from django.conf import settings from django.conf import settings
@ -12,7 +11,7 @@ from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleHidd
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import get_object_or_404, redirect, render from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader from django.template import loader
from django.template.exceptions import TemplateDoesNotExist, TemplateSyntaxError from django.template.exceptions import TemplateDoesNotExist
from django.urls import reverse from django.urls import reverse
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import is_safe_url from django.utils.http import is_safe_url
@ -23,6 +22,7 @@ from django.views.generic import View
from django_tables2 import RequestConfig from django_tables2 import RequestConfig
from extras.models import CustomField, CustomFieldValue, ExportTemplate from extras.models import CustomField, CustomFieldValue, ExportTemplate
from extras.querysets import CustomFieldQueryset
from utilities.forms import BootstrapMixin, CSVDataField from utilities.forms import BootstrapMixin, CSVDataField
from utilities.utils import csv_format from utilities.utils import csv_format
from .error_handlers import handle_protectederror from .error_handlers import handle_protectederror
@ -30,23 +30,6 @@ from .forms import ConfirmationForm
from .paginator import EnhancedPaginator from .paginator import EnhancedPaginator
class CustomFieldQueryset:
"""
Annotate custom fields on objects within a QuerySet.
"""
def __init__(self, queryset, custom_fields):
self.queryset = queryset
self.model = queryset.model
self.custom_fields = custom_fields
def __iter__(self):
for obj in self.queryset:
values_dict = {cfv.field_id: cfv.value for cfv in obj.custom_field_values.all()}
obj.custom_fields = OrderedDict([(field, values_dict.get(field.pk)) for field in self.custom_fields])
yield obj
class GetReturnURLMixin(object): class GetReturnURLMixin(object):
""" """
Provides logic for determining where a user should be redirected after processing a form. Provides logic for determining where a user should be redirected after processing a form.
@ -115,8 +98,9 @@ class ObjectListView(View):
self.queryset = self.filter(request.GET, self.queryset).qs 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 # 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))\ custom_fields = CustomField.objects.filter(
.prefetch_related('choices') obj_type=ContentType.objects.get_for_model(model)
).prefetch_related('choices')
if custom_fields: if custom_fields:
self.queryset = self.queryset.prefetch_related('custom_field_values') self.queryset = self.queryset.prefetch_related('custom_field_values')