Repository: netbox-community/netbox

Issue:
Adding reservation on rack
<!--
    Before opening a new issue, please search through the existing issues to
    see if your topic has already been addressed. Note that you may need to
    remove the "is:open" filter from the search bar to include closed issues.

    Check the appropriate type for your issue below by placing an x between the
    brackets. For assistance with installation issues, or for any other issues
    other than those listed below, please raise your topic for discussion on
    our mailing list:

        https://groups.google.com/forum/#!forum/netbox-discuss

    Please note that issues which do not fall under any of the below categories
    will be closed. Due to an excessive backlog of feature requests, we are
    not currently accepting any proposals which extend NetBox's feature scope.

    Do not prepend any sort of tag to your issue's title. An administrator will
    review your issue and assign labels as appropriate.
--->
### Issue type
[ ] Feature request <!-- An enhancement of existing functionality -->
[X ] Bug report      <!-- Unexpected or erroneous behavior -->
[ ] Documentation   <!-- A modification to the documentation -->

<!--
    Please describe the environment in which you are running NetBox. (Be sure
    to verify that you are running the latest stable release of NetBox before
    submitting a bug report.) If you are submitting a bug report and have made
    any changes to the code base, please first validate that your bug can be
    recreated while running an official release.
-->
### Environment
* Python version:  3.5.2<!-- Example: 3.5.4 -->
* NetBox version:  2.3.2<!-- Example: 2.1.3 -->

<!--
    BUG REPORTS must include:
        * A list of the steps needed for someone else to reproduce the bug
        * A description of the expected and observed behavior
        * Any relevant error messages (screenshots may also help)

    FEATURE REQUESTS must include:
        * A detailed description of the proposed functionality
        * A use case for the new feature
        * A rough description of any necessary changes to the database schema
        * Any relevant third-party libraries which would be needed
-->
### Description
When trying to add a reservation in a rack it isnt possible to do this. When clicking the add reservation button it redirects me to a Server Error. The exception i get is: 
<class 'IndexError'>
list index out of range

Did i break something perhaps?


Discussion:
I can confirm this bug after upgrading to 2.3.2.

After enabling Debug, I get this additional info:

```
Template error:
In template /opt/netbox-2.3.2/netbox/templates/utilities/render_field.html, error at line 49
   list index out of range   39 :                 <ul>
   40 :                     {% for error in field.errors %}
   41 :                         <li class="text-danger">{{ error }}</li>
   42 :                     {% endfor %}
   43 :                 </ul>
   44 :             {% endif %}
   45 :         </div>
   46 :     {% else %}
   47 :         <label class="col-md-3 control-label{% if field.field.required %} required{% endif %}" for="{{ field.id_for_label }}">{{ field.label }}</label>
   48 :         <div class="col-md-9">
   49 :              {{ field }} 
   50 :             {% if bulk_nullable %}
   51 :                 <label class="checkbox-inline">
   52 :                     <input type="checkbox" name="_nullify" value="{{ field.name }}" /> Set null
   53 :                 </label>
   54 :             {% endif %}
   55 :             {% if field.help_text %}
   56 :                 <span class="help-block">{{ field.help_text|safe }}</span>
   57 :             {% endif %}
   58 :             {% if field.errors %}
   59 :                 <ul>


Traceback:

File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python3.5/dist-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python3.5/dist-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/usr/local/lib/python3.5/dist-packages/django/contrib/auth/mixins.py" in dispatch
  92.         return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs)

File "/usr/local/lib/python3.5/dist-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/opt/netbox-2.3.2/netbox/utilities/views.py" in get
  185.             'return_url': self.get_return_url(request, obj),

File "/usr/local/lib/python3.5/dist-packages/django/shortcuts.py" in render
  30.     content = loader.render_to_string(template_name, context, request, using=using)

File "/usr/local/lib/python3.5/dist-packages/django/template/loader.py" in render_to_string
  68.     return template.render(context, request)

File "/usr/local/lib/python3.5/dist-packages/django/template/backends/django.py" in render
  66.             return self.template.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  207.                     return self._render(context)

File "/usr/local/lib/python3.5/dist-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/loader_tags.py" in render
  177.             return compiled_parent._render(context)

File "/usr/local/lib/python3.5/dist-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/loader_tags.py" in render
  72.                 result = block.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/loader_tags.py" in render
  72.                 result = block.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/library.py" in render
  245.         return t.render(new_context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  209.                 return self._render(context)

File "/usr/local/lib/python3.5/dist-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/defaulttags.py" in render
  216.                     nodelist.append(node.render_annotated(context))

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/library.py" in render
  245.         return t.render(new_context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  209.                 return self._render(context)

File "/usr/local/lib/python3.5/dist-packages/django/test/utils.py" in instrumented_test_render
  107.     return self.nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/defaulttags.py" in render
  322.                 return nodelist.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  990.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_annotated
  957.             return self.render(context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render
  1046.         return render_value_in_context(output, context)

File "/usr/local/lib/python3.5/dist-packages/django/template/base.py" in render_value_in_context
  1024.     value = force_text(value)

File "/usr/local/lib/python3.5/dist-packages/django/utils/encoding.py" in force_text
  76.                     s = six.text_type(s)

File "/usr/local/lib/python3.5/dist-packages/django/utils/html.py" in <lambda>
  394.         klass.__str__ = lambda self: mark_safe(klass_str(self))

File "/usr/local/lib/python3.5/dist-packages/django/forms/boundfield.py" in __str__
  41.         return self.as_widget()

File "/usr/local/lib/python3.5/dist-packages/django/forms/boundfield.py" in as_widget
  127.             **kwargs

File "/usr/local/lib/python3.5/dist-packages/django/forms/widgets.py" in render
  220.         context = self.get_context(name, value, attrs)

File "/usr/local/lib/python3.5/dist-packages/django/forms/widgets.py" in get_context
  667.         context = super(Select, self).get_context(name, value, attrs)

File "/usr/local/lib/python3.5/dist-packages/django/forms/widgets.py" in get_context
  627.         context['widget']['optgroups'] = self.optgroups(name, context['widget']['value'], attrs)

File "/opt/netbox-2.3.2/netbox/utilities/forms.py" in optgroups
  208.         value = value[0].split(self.delimiter)

Exception Type: IndexError at /dcim/racks/1/reservations/add/
Exception Value: list index out of range
```


Resolving patch:
diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py
--- a/netbox/utilities/forms.py
+++ b/netbox/utilities/forms.py
@@ -205,7 +205,8 @@ def __init__(self, *args, **kwargs):
 
     def optgroups(self, name, value, attrs=None):
         # Split the delimited string of values into a list
-        value = value[0].split(self.delimiter)
+        if value:
+            value = value[0].split(self.delimiter)
         return super(ArrayFieldSelectMultiple, self).optgroups(name, value, attrs)
 
     def value_from_datadict(self, data, files, name):


Test patch: