views:

21

answers:

1

my example (I know it's not technically correct, it's just an example):

class ipAddy(models.Model):
    network=models.ForeignKey(network)
    ipAddy=models.IPAddressField(foo)

class device(models.Model):
    hostname=models.CharField(foo)
    foo=models.CharField(bar)
    bar=models.CharField(foo)

    class Meta:
        abstract = True

class linuxServer(device):
    linuxInfo - models.CharField(foo)

class macServer(device):
    macInfo = models.CharField(foo)

My goal:

For each device-based model to have a many-to-one relationship to the ipAddy model. In the real world speak: I'd like each type of server or device to be able to have multiple IP addresses.

What would be the best way to accomplish this in Django 1.2?

All constructive thoughts are appreciated.

+1  A: 

The most obvious way to do this is to add a many to many field to the abstract device class. Something like this:

class device(models.Model):
    hostname=models.CharField(foo)
    foo=models.CharField(bar)
    bar=models.CharField(foo)
    ip_addresses=models.ManyToManyField(ipAddy) # <=== m2m

    class Meta:
        abstract = True

The above structure assumes that you do not want to store any other, additional information with the many to many relationship.

If you do want to attach more data to each many to many relationship then you can use an intermediary table. This cannot be done using the abstract class. It has to be done at the child model level. For e.g.

class linuxServer(device):
    linuxInfo = models.CharField(foo)        
    ip_addresses=models.ManyToManyField(ipAddy, 
            through='LinuxIPAssociation') # <=== m2m

    class Meta:
        abstract = True

class LinuxIPAssociation(models.Model):
    device = models.ForeignKey(linuxServer)
    ip_addy = models.ForeignKey(ipAddy) 
    custom_field_1 = models.CharField(...)
    custom_field_2 = models.IntegerField(...)

# Similarly for Mac also. 

The reason for the above is that you require a foreign key to both the models when using an intermediary table and Django does not allow you to declare a foreign key to an abstract model class. Consequently you are obliged to declare two separate intermediate models yourself.

PS: your use of lower case class names is bugging me. Cease and desist!

Manoj Govindan
Thanks for the thoughts. The ManyToManyField did build out, but it would require having every IP address defined within the database an then scrolling through them all to select the address(es) you wanted to use on a given device. Just not a practical solution.
jduncan
The second suggestion (thanks again) has a circular reference, doesn't it? the linuxServer class is referencing the LinuxIPAssociation class which doesn't yet exist... right?
jduncan
`the linuxServer class is referencing the LinuxIPAssociation class which doesn't yet exist... right?`: Correct. And that is why the name of the class is in quotes. You can see a similar example in the docs: http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships
Manoj Govindan