Просмотр исходного кода

Add template_language field to Graph

Jeremy Stretch 6 лет назад
Родитель
Сommit
9399652dd0

+ 5 - 0
docs/additional-features/graphs.md

@@ -8,6 +8,11 @@ NetBox does not have the ability to generate graphs natively, but this feature a
 * **Source URL:** The source of the image to be embedded. The associated object will be available as a template variable named `obj`.
 * **Link URL (optional):** A URL to which the graph will be linked. The associated object will be available as a template variable named `obj`.
 
+Graph names and links can be rendered using the Django or Jinja2 template languages.
+
+!!! warning
+    Support for the Django templating language will be removed in NetBox v2.8. Jinja2 is recommended.
+
 ## Examples
 
 You only need to define one graph object for each graph you want to include when viewing an object. For example, if you want to include a graph of traffic through an interface over the past five minutes, your graph source might looks like this:

+ 2 - 2
netbox/extras/admin.py

@@ -131,10 +131,10 @@ class CustomLinkAdmin(admin.ModelAdmin):
 @admin.register(Graph, site=admin_site)
 class GraphAdmin(admin.ModelAdmin):
     list_display = [
-        'name', 'type', 'weight', 'source',
+        'name', 'type', 'weight', 'template_language', 'source',
     ]
     list_filter = [
-        'type',
+        'type', 'template_language',
     ]
 
 

+ 1 - 1
netbox/extras/api/serializers.py

@@ -34,7 +34,7 @@ class GraphSerializer(ValidatedModelSerializer):
 
     class Meta:
         model = Graph
-        fields = ['id', 'type', 'weight', 'name', 'source', 'link']
+        fields = ['id', 'type', 'weight', 'name', 'template_language', 'source', 'link']
 
 
 class RenderedGraphSerializer(serializers.ModelSerializer):

+ 1 - 1
netbox/extras/api/views.py

@@ -26,7 +26,7 @@ from . import serializers
 class ExtrasFieldChoicesViewSet(FieldChoicesViewSet):
     fields = (
         (ExportTemplate, ['template_language']),
-        (Graph, ['type']),
+        (Graph, ['type', 'template_language']),
         (ObjectChange, ['action']),
     )
 

+ 1 - 1
netbox/extras/filters.py

@@ -92,7 +92,7 @@ class GraphFilterSet(django_filters.FilterSet):
 
     class Meta:
         model = Graph
-        fields = ['type', 'name']
+        fields = ['type', 'name', 'template_language']
 
 
 class ExportTemplateFilterSet(django_filters.FilterSet):

+ 13 - 0
netbox/extras/migrations/0033_graph_type_to_fk.py → netbox/extras/migrations/0033_graph_type_template_language.py

@@ -43,4 +43,17 @@ class Migration(migrations.Migration):
                 to='contenttypes.ContentType'
             ),
         ),
+
+        # Add the template_language field with an initial default of Django to preserve current behavior. Then,
+        # alter the field to set the default for any *new* Graphs to Jinja2.
+        migrations.AddField(
+            model_name='graph',
+            name='template_language',
+            field=models.CharField(default='django', max_length=50),
+        ),
+        migrations.AlterField(
+            model_name='graph',
+            name='template_language',
+            field=models.CharField(default='jinja2', max_length=50),
+        ),
     ]

+ 1 - 1
netbox/extras/migrations/0034_configcontext_tags.py

@@ -6,7 +6,7 @@ from django.db import migrations, models
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('extras', '0033_graph_type_to_fk'),
+        ('extras', '0033_graph_type_template_language'),
     ]
 
     operations = [

+ 24 - 4
netbox/extras/models.py

@@ -421,6 +421,11 @@ class Graph(models.Model):
         max_length=100,
         verbose_name='Name'
     )
+    template_language = models.CharField(
+        max_length=50,
+        choices=ExportTemplateLanguageChoices,
+        default=ExportTemplateLanguageChoices.LANGUAGE_JINJA2
+    )
     source = models.CharField(
         max_length=500,
         verbose_name='Source URL'
@@ -437,14 +442,29 @@ class Graph(models.Model):
         return self.name
 
     def embed_url(self, obj):
-        template = Template(self.source)
-        return template.render(Context({'obj': obj}))
+        context = {'obj': obj}
+
+        # TODO: Remove in v2.8
+        if self.template_language == ExportTemplateLanguageChoices.LANGUAGE_DJANGO:
+            template = Template(self.source)
+            return template.render(Context(context))
+
+        elif self.template_language == ExportTemplateLanguageChoices.LANGUAGE_JINJA2:
+            return render_jinja2(self.source, context)
 
     def embed_link(self, obj):
         if self.link is None:
             return ''
-        template = Template(self.link)
-        return template.render(Context({'obj': obj}))
+
+        context = {'obj': obj}
+
+        # TODO: Remove in v2.8
+        if self.template_language == ExportTemplateLanguageChoices.LANGUAGE_DJANGO:
+            template = Template(self.link)
+            return template.render(Context(context))
+
+        elif self.template_language == ExportTemplateLanguageChoices.LANGUAGE_JINJA2:
+            return render_jinja2(self.link, context)
 
 
 #

+ 8 - 3
netbox/extras/tests/test_filters.py

@@ -18,9 +18,9 @@ class GraphTestCase(TestCase):
         content_types = ContentType.objects.filter(model__in=['site', 'device', 'interface'])
 
         graphs = (
-            Graph(name='Graph 1', type=content_types[0], source='http://example.com/1'),
-            Graph(name='Graph 2', type=content_types[1], source='http://example.com/2'),
-            Graph(name='Graph 3', type=content_types[2], source='http://example.com/3'),
+            Graph(name='Graph 1', type=content_types[0], template_language=ExportTemplateLanguageChoices.LANGUAGE_DJANGO, source='http://example.com/1'),
+            Graph(name='Graph 2', type=content_types[1], template_language=ExportTemplateLanguageChoices.LANGUAGE_JINJA2, source='http://example.com/2'),
+            Graph(name='Graph 3', type=content_types[2], template_language=ExportTemplateLanguageChoices.LANGUAGE_JINJA2, source='http://example.com/3'),
         )
         Graph.objects.bulk_create(graphs)
 
@@ -32,6 +32,11 @@ class GraphTestCase(TestCase):
         params = {'type': ContentType.objects.get(model='site').pk}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
 
+    # TODO: Remove in v2.8
+    def test_template_language(self):
+        params = {'template_language': ExportTemplateLanguageChoices.LANGUAGE_JINJA2}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
 
 class ExportTemplateTestCase(TestCase):
     queryset = ExportTemplate.objects.all()