Added views for rack reservations

This commit is contained in:
Jeremy Stretch 2017-02-15 16:44:45 -05:00
parent 6b53570039
commit ac2bf91a87
4 changed files with 57 additions and 11 deletions

View File

@ -488,7 +488,7 @@ class RackReservation(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, editable=False, on_delete=models.PROTECT) user = models.ForeignKey(User, editable=False, on_delete=models.PROTECT)
rack = models.ForeignKey('Rack', related_name='reservations', editable=False, on_delete=models.CASCADE) rack = models.ForeignKey('Rack', related_name='reservations', editable=False, on_delete=models.CASCADE)
units = ArrayField(models.PositiveSmallIntegerField(validators=[MinValueValidator(1)])) units = ArrayField(models.PositiveSmallIntegerField())
description = models.CharField(max_length=100) description = models.CharField(max_length=100)
class Meta: class Meta:
@ -497,6 +497,32 @@ class RackReservation(models.Model):
def __str__(self): def __str__(self):
return u"Reservation for rack {}".format(self.rack) return u"Reservation for rack {}".format(self.rack)
def clean(self):
if self.units:
# Validate that all specified units exist in the Rack.
invalid_units = [u for u in self.units if u not in self.rack.units]
if invalid_units:
raise ValidationError({
'units': u"Invalid unit(s) for {}U rack: {}".format(
self.rack.u_height,
', '.join([str(u) for u in invalid_units]),
),
})
# Check that none of the units has already been reserved for this Rack.
reserved_units = []
for resv in self.rack.reservations.exclude(pk=self.pk):
reserved_units += resv.units
conflicting_units = [u for u in self.units if u in reserved_units]
if conflicting_units:
raise ValidationError({
'units': 'The following units have already been reserved: {}'.format(
', '.join([str(u) for u in conflicting_units]),
)
})
# #
# Device Types # Device Types

View File

@ -31,6 +31,7 @@ urlpatterns = [
# Rack reservations # Rack reservations
url(r'^rack-reservations/(?P<pk>\d+)/edit/$', views.RackReservationEditView.as_view(), name='rackreservation_edit'), url(r'^rack-reservations/(?P<pk>\d+)/edit/$', views.RackReservationEditView.as_view(), name='rackreservation_edit'),
url(r'^rack-reservations/(?P<pk>\d+)/delete/$', views.RackReservationDeleteView.as_view(), name='rackreservation_delete'),
# Racks # Racks
url(r'^racks/$', views.RackListView.as_view(), name='rack_list'), url(r'^racks/$', views.RackListView.as_view(), name='rack_list'),

View File

@ -334,15 +334,24 @@ class RackReservationEditView(PermissionRequiredMixin, ObjectEditView):
model = RackReservation model = RackReservation
form_class = forms.RackReservationForm form_class = forms.RackReservationForm
def alter_obj(self, obj, args, kwargs): def alter_obj(self, obj, request, args, kwargs):
if 'rack' in kwargs: if not obj.pk:
obj.rack = get_object_or_404(Rack, pk=kwargs['rack']) obj.rack = get_object_or_404(Rack, pk=kwargs['rack'])
obj.user = request.user
return obj return obj
def get_return_url(self, obj): def get_return_url(self, obj):
return obj.rack.get_absolute_url() return obj.rack.get_absolute_url()
class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
permission_required = 'dcim.delete_rackreservation'
model = RackReservation
def get_return_url(self, obj):
return obj.rack.get_absolute_url()
# #
# Manufacturers # Manufacturers
# #

View File

@ -198,22 +198,32 @@
<tr> <tr>
<th>Units</th> <th>Units</th>
<th>Description</th> <th>Description</th>
<th>User</th>
<th>Created</th>
<th></th> <th></th>
</tr> </tr>
{% for resv in reservations %} {% for resv in reservations %}
<tr> <tr>
<td>{{ resv.units }}</td> <td>{{ resv.units|join:', ' }}</td>
<td>{{ resv.description }}</td> <td>
<td>{{ resv.user }}</td> {{ resv.description }}<br />
<td>{{ resv.created }}</td> <small>{{ resv.user }} &middot; {{ resv.created }}</small>
<td>{% if perms.change_rackreservation %}<a href="{% url 'dcim:rackreservation_edit' pk=resv.pk %}">edit</a>{% endif %}</td> </td>
<td class="text-right">
{% if perms.change_rackreservation %}
<a href="{% url 'dcim:rackreservation_edit' pk=resv.pk %}" class="btn btn-warning btn-xs" title="Edit reservation">
<i class="glyphicon glyphicon-pencil" aria-hidden="true"></i>
</a>
{% endif %}
{% if perms.delete_rackreservation %}
<a href="{% url 'dcim:rackreservation_delete' pk=resv.pk %}" class="btn btn-danger btn-xs" title="Delete reservation">
<i class="glyphicon glyphicon-trash" aria-hidden="true"></i>
</a>
{% endif %}
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
{% else %} {% else %}
<span class="text-muted">None</span> <div class="panel-body text-muted">None</div>
{% endif %} {% endif %}
{% if perms.dcim.add_rackreservation %} {% if perms.dcim.add_rackreservation %}
<div class="panel-footer text-right"> <div class="panel-footer text-right">