-
{{ component_name|title }} to Add
+
{{ model_name|title }} to Add
{% for field in form.visible_fields %}
{% render_field field %}
diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py
index e7bc40846..11fa789ec 100644
--- a/netbox/utilities/templatetags/helpers.py
+++ b/netbox/utilities/templatetags/helpers.py
@@ -1,11 +1,13 @@
import datetime
import json
+import re
from django import template
from django.utils.safestring import mark_safe
from markdown import markdown
from utilities.forms import unpack_grouped_choices
+from utilities.utils import foreground_color
register = template.Library()
@@ -152,6 +154,17 @@ def tzoffset(value):
return datetime.datetime.now(value).strftime('%z')
+@register.filter()
+def fgcolor(value):
+ """
+ Return black (#000000) or white (#ffffff) given an arbitrary background color in RRGGBB format.
+ """
+ value = value.lower().strip('#')
+ if not re.match('^[0-9a-f]{6}$', value):
+ return ''
+ return '#{}'.format(foreground_color(value))
+
+
#
# Tags
#
diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py
index ee13533bc..f52f4ea9e 100644
--- a/netbox/utilities/views.py
+++ b/netbox/utilities/views.py
@@ -55,8 +55,9 @@ class GetReturnURLMixin(object):
def get_return_url(self, request, obj=None):
- # First, see if `return_url` was specified as a query parameter. Use it only if it's considered safe.
- query_param = request.GET.get('return_url')
+ # First, see if `return_url` was specified as a query parameter or form data. Use this URL only if it's
+ # considered safe.
+ query_param = request.GET.get('return_url') or request.POST.get('return_url')
if query_param and is_safe_url(url=query_param, allowed_hosts=request.get_host()):
return query_param
@@ -789,9 +790,12 @@ class BulkComponentCreateView(GetReturnURLMixin, View):
def post(self, request):
+ parent_model_name = self.parent_model._meta.verbose_name_plural
+ model_name = self.model._meta.verbose_name_plural
+
# Are we editing *all* objects in the queryset or just a selected subset?
if request.POST.get('_all') and self.filter is not None:
- pk_list = [obj.pk for obj in self.filter(request.GET, self.model.objects.only('pk')).qs]
+ pk_list = [obj.pk for obj in self.filter(request.GET, self.parent_model.objects.only('pk')).qs]
else:
pk_list = [int(pk) for pk in request.POST.getlist('pk')]
@@ -829,9 +833,9 @@ class BulkComponentCreateView(GetReturnURLMixin, View):
messages.success(request, "Added {} {} to {} {}.".format(
len(new_components),
- self.model._meta.verbose_name_plural,
+ model_name,
len(form.cleaned_data['pk']),
- self.parent_model._meta.verbose_name_plural
+ parent_model_name
))
return redirect(self.get_return_url(request))
@@ -840,7 +844,8 @@ class BulkComponentCreateView(GetReturnURLMixin, View):
return render(request, self.template_name, {
'form': form,
- 'component_name': self.model._meta.verbose_name_plural,
+ 'parent_model_name': parent_model_name,
+ 'model_name': model_name,
'table': table,
'return_url': self.get_return_url(request),
})
diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py
index b578cf455..aa8a585a9 100644
--- a/netbox/virtualization/views.py
+++ b/netbox/virtualization/views.py
@@ -369,5 +369,6 @@ class VirtualMachineBulkAddInterfaceView(PermissionRequiredMixin, BulkComponentC
form = forms.VirtualMachineBulkAddInterfaceForm
model = Interface
model_form = forms.InterfaceForm
+ filter = filters.VirtualMachineFilter
table = tables.VirtualMachineTable
default_return_url = 'virtualization:virtualmachine_list'