0

I guess my understanding in django models are too shallow and I couldn't come up with a solution even with searching for in the internet. Here is the problem:

I have a MAC Address model that holds mac addresses. Also I have many models that is related to this MAC Address model like PCs, Access Points, Swtiches etc. Since all these models can have multiple network interfaces (ex. A Laptop can have LAN and WLAN interfaces that has different MAC Addresses or a Server can have multiple LAN interfaces) I decided to make a seperate model for MAC Addresses. But I don't really need to see which mac address is related to which asset. So is there a way to make bidirectional one-to-many relationship in django?

class MACAddress(models.Model):
    addr = models.CharField(_('MAC Address'), max_length=17)

class AccessPoint(models.Model):
    #...
    # This property must be in a form of list or array.
    mac_addresses = models.OneToManyField(MACAddress)

Something like that is possible? I saw some Many-to-one relationship examples but all of them shows just how to get related model data. (ex. In a User, Contact model relationship, examples shows how to get User model from Contact model. Which I need the other way around)

Valour
  • 773
  • 10
  • 32

2 Answers2

0

If I've understood you correctly, you'll want to add a ForeignKey on MACAddress.

# in MACAddress:

    access_point = models.ForeignKey('AccessPoint')

One way to think of it is that a MACAddress always "belongs" to a single AccessPoint, so it needs a ForeignKey to tell it which AccessPoint it belongs to.

Now, if you want to find all MAC addresses for a particular AccessPoint, use the _set syntax on the MACAddress model. See this answer for an example.

Matt Howell
  • 15,750
  • 7
  • 49
  • 56
  • So do I need to add a `ForeignKey` to `MACAddress` model for every asset that is related to? Because Django has no `OneToManyField` relationship. – Valour Feb 26 '21 at 08:20
  • I've revised my answer -- see above. – Matt Howell Feb 26 '21 at 18:43
  • Yes I already doing it like this in the current models. I just wanted to know if the other way (like I show in the example in my question) is possible. But it seems that kind of bidirectional relationship is not possible. I just accept your answer. – Valour Mar 01 '21 at 05:41
  • You can still get at the data from the other direction using the `_set` syntax. So, in the model (and database), it's a one-to-many relationship, but you have access to it from either side. Hope that helps. – Matt Howell Mar 02 '21 at 01:13
0

Since you have multiple types of devices that have a Mac Address you need the devices to inherit from some common ancestor (i.e. one to one relationship with a common model).
Let's call a device that has a Mac Address as a Networking Device then you can make your models as:

class NetworkingDevice(models.Model):
    pass # OR have any common fields here. Also a field that signifies which kind of device it is might be beneficial for e.g. a CharField with choices.

class MACAddress(models.Model):
    addr = models.CharField(_('MAC Address'), max_length=17)
    device = models.ForeignKey(NetworkingDevice, on_delete=models.CASCADE, related_name="mac_addresses")

Now any model that has some mac addresses just have it inherit from NetworkingDevice to use Multi-table inheritance this will implicitly create a OneToOneField between the models, or you can simply set a OneToOneField yourself.

class AccessPoint(NetworkingDevice):
    pass # have fields that are unique to AccessPoint here
Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33