mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Rack reservations (#900)
* Initial work on rack reservations * Added views for rack reservations * Implemented ArrayFieldSelectMultiple form widget * Implemented API endpoints for rack reservations * Tweaked the database migration
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
@@ -478,6 +480,50 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
||||
return int(float(self.u_height - u_available) / self.u_height * 100)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class RackReservation(models.Model):
|
||||
"""
|
||||
One or more reserved units within a Rack.
|
||||
"""
|
||||
rack = models.ForeignKey('Rack', related_name='reservations', editable=False, on_delete=models.CASCADE)
|
||||
units = ArrayField(models.PositiveSmallIntegerField())
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
user = models.ForeignKey(User, editable=False, on_delete=models.PROTECT)
|
||||
description = models.CharField(max_length=100)
|
||||
|
||||
class Meta:
|
||||
ordering = ['created']
|
||||
|
||||
def __str__(self):
|
||||
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
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user