views:

49

answers:

1

I'm working on a server / datacenter inventory management tool. I have a class to define a default "device", which is then used to express custom devices (linux servers, windows servers, routers, switches, etc.)

I also have data models set up to express IP addresses within a network.

My question is, what would be the best way to express the relationship between all of the various device models and the ipv4 address model?

class device(models.Model):
    '''the primary object. all types of networked devices are based on and inherit this class'''
    STATUS_CHOICES = (('0', 'unknown'),('1','active'),('2','pending'),('3','inactive'),('4', 'inventory'),('5','mothballed'),('6','surplus'),)

    '''technical information'''
    hostname = models.CharField(max_length=45, unique=True, db_index=True, help_text="The published hostname for this device")

    '''misc. information'''
    description = models.TextField(blank=True, null=True, help_text="A free-form description field")

    type = models.ForeignKey(deviceStatus, help_text="The classification for this device")
    status = models.IntegerField(choices=STATUS_CHOICES, help_text="current status of device")
    is_monitored = models.BooleanField(default=True, help_text="is the device monitored?")
    date_added = models.DateTimeField(auto_now=True, help_text="Date and Time device is entered into Barrelhouse", editable=False)
    warranty_expriry = models.DateField(help_text="Date Manufacturer warranty expires")
    extended_warranty = models.BooleanField(help_text="Whether or not device has some extended warranty in addition to the manufacturer",default=False, validators=[validate_extended_warr])
    ext_warranty_expiry = models.DateField(help_text="Date Extended Warranty Expires", null=True)
    account = models.ForeignKey(vendorAccount, help_text="account associated with this device")

    class Meta:
            abstract = True

class deviceLinuxSystem(device):
    '''a typcial linux system --- you can get as specific as you want to in various server and desktop types.'''
    ip_address = generic.GenericRelation(ipv4address)

    def get_absolute_url(self):
            return "linux_devices/%i/" % self.id

    def __unicode__(self):
            return self.hostname

    class Meta:
            verbose_name = "Linux System"
class deviceWindowsSystem(device):
    '''a typical windws system'''

    def get_absolute_url(self):
            return "windows_devices/%i/" % self.id

    def __unicode__(self):
            return self.hostname

    class Meta:
            verbose_name = "Windows System"


class ipv4address(models.Model):
    '''a model to represent all used IPv4 addresses on networks'''
    netIP = models.IPAddressField(help_text="associated address", verbose_name="IP Address", unique=True, db_index=True)
    network = models.ForeignKey(network, help_text="Network this IP lives on")
+1  A: 

Focusing on the question at hand:

My question is, what would be the best way to express the relationship between all of the various device models and the ipv4 address model?

I'd recommend adding dev = models.ForeignKey(device, related_name="address") (and possibly a portNumber = models.PositiveSmallIntegerField(default=0)) to ipv4address. A device can have more than one network port, and therefore more than one IP address, unless you've got something enforcing one address going to a host regardless of port (e.g. wired or wifi).

If you guarantee only one address per host, then you'd want dev = models.OneToOneField(device, related_name="address") instead.

Mike DeSimone
+1 A Fk or a OnetoOneKey seems appropriate. I don't see why the OP is using a GenericRelation
Lakshman Prasad
I don't know why the OP is 1) putting `hostname` in `device`, since a `device` could have multiple names (often the case with servers), 2) putting extended warranties in with the `device` (I guess you can buy only one?), or 3) using the `id` in URLs, instead of `hostname` or some other slug which can be changed later if needed.
Mike DeSimone
because this is a first scratch model as I think through the process. Thanks for the input, however.
jduncan
Mike,Sadly you can't define a foregin key relationship to an abstract class. That was the first thing I tried. I think the generic foreginkey methodology in Django is the best bet, I was just looking for alternative thoughts.AssertionError: ForeignKey cannot define a relation with abstract class device
jduncan
Yeah, this is where my head explodes. Defining `device` as abstract means you can't have a query of all devices, IIRC... and that seems a rather useful thing to have, compared to using one less table. Anyway, use `GenericRelation` relation instead of `ForeignKey` and see how it goes.
Mike DeSimone