Reputation: 31
I'm writing and app to manage my network equipments. I created a model, RJ45port, which I can add to my equipment as needed. A RJ45port can be plugged into an other RJ45port and only one.
Here is the model I created :
class RJ45port(models.Model):
plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True)
When I "plug" a RJ45port into another, I want the second one to have "plugged_into" set to the first one. I want the relation to be symmetrical. If I "unplug", I want both of the RJ45 ports to have "plugged_into" set to null, or blank.
I found a bit of code, it might be a hint :
def save(self, *args, **kwargs):
super(RJ45port, self).save()
self.plugged_into.plugged_into = self
To be honest I'm a bit lost here and it's the final step I need to get this app functional...
Upvotes: 2
Views: 588
Reputation: 5452
Another option is to use a related_name
so you can make a reverse access from the referenced instance, so you can say that the relationship becomes "symetrical". The only downside is that you can't use the same name to reference both connections:
class RJ45port(models.Model):
plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True, related_name='plugged_from')
In this example, plugged_from
can be queried like any other field from the referenced instance.
Upvotes: 0
Reputation: 536
You are right. Simply override the save method. But call super().save()
at the end:
class RJ45port(models.Model):
plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True)
def save(self, *args, **kwargs):
self.plugged_into.plugged_into = self
super(RJ45port, self).save()
Upvotes: 1
Reputation: 7049
You are best suited just making a model plug_into()
method, and then using it to "plug" one instance into another, as well as an unplug()
method.
Example:
class RJ45port(models.Model):
plugged_into = models.OneToOneField('self', on_delete=models.SET_NULL, blank=True, null=True)
def plug_into(self, instance):
self.plugged_into = instance
instance.plugged_into = self
self.save(update_fields=['plugged_into'])
instance.save(update_fields=['plugged_into'])
return [self.plugged_into, instance.plugged_into]
def unplug(self):
self.plugged_into.plugged_into = None
self.plugged_into = None
self.plugged_into.save(update_fields=['plugged_into'])
self.save(update_fields=['plugged_into'])
return [self.plugged_into, instance.plugged_into]
And then you can call it like this:
port_1 = Port.objects.all()[0] # First port
port_2 = Port.objects.all()[1] # Second port
port_1.plug_into(port_2) # Should return [instance, instance]
port_1.unplug() # Should return [None, None]
Upvotes: 1