Plugin development: List Interfaces if they're referred to by a plugin's model's ManyToManyField? #13578
-
|
Hi! I'm currently working on a NetBox plugin to model MC-LAGs. See this repository for my current state of the code: https://github.com/pv2b/netbox-plugin-mclag This is the data model of my plugin: class McDomain(NetBoxModel):
name = models.CharField(max_length=100)
domain_id = models.CharField(max_length=20, blank=True, null=True)
description = models.TextField(max_length=200, blank=True, null=True)
devices = models.ManyToManyField(
to='dcim.Device',
related_name="mc_domains"
)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('plugins:netbox_plugin_mclag:mcdomain', args=[self.pk])
class Meta:
verbose_name="Multi-Chassis Domain"
verbose_name_plural="Multi-Chassis Domains"
class McLag(NetBoxModel):
name = models.CharField(max_length=100)
lag_id = models.CharField(max_length=20, blank=True, null=True)
description = models.TextField(max_length=200, blank=True, null=True)
mc_domain = models.ForeignKey(
to=McDomain,
on_delete=models.CASCADE,
related_name="mc_lags"
)
interfaces = models.ManyToManyField(
to='dcim.Interface',
related_name="mc_lags"
)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('plugins:netbox_plugin_mclag:mclag', args=[self.pk])
class Meta:
verbose_name="Multi-Chassis Link Aggregation Group"
verbose_name_plural="Multi-Chassis Link Aggregation Groups"To summarize, the McDomain model refers to one or more Interface objects using a ManyToManyField, and a McLag model refers to a McDomain using a ForeignKey. I'm currently working on the form for McLag, and it currently looks like this: class McLagForm(NetBoxModelForm):
interfaces = DynamicModelMultipleChoiceField(
queryset = Interface.objects.all(),
selector = True,
query_params = {
'device__mc_domains': '$mc_domain'
}
)
# Override the data-url to a custom API endpoint that gets a list of endpoints filtered by McDomain
#interfaces.widget.attrs['data-url'] = "/asdf"
class Meta:
model = McLag
fields = ('name', 'lag_id', 'description', 'mc_domain', 'tags', 'interfaces')What I'm trying to do do right now is to make it so that only interfaces that belong to the devices referred to by the McDomain are offered to the user as selections. Or, in real-world terms, if you want to add an interface to a Multi-Chassis Link Aggregation Group, that interface has to be part of the Multi-Chassis Domain that the MC-LAG is associated with. From what I've been able to figure out so far, DynamicModelMultipleChoiceField uses some client-side Javascript trickery to populate the form based on the results of an API call to list Interface objects, and also offers the That means, right now, when I click on the selection button, my web browser sends a GET request to To recap, the following works in nbshell: But the following is what I get from the API when I ask for {
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": 3,
"url": "http://localhost:8000/api/dcim/interfaces/3/",
"display": "Coffee1/0/1",
"device": {
"id": 3,
"url": "http://localhost:8000/api/dcim/devices/3/",
"display": "Coffee Machine",
"name": "Coffee Machine"
},
"name": "Coffee1/0/1",
"cable": null,
"_occupied": false
},
{
"id": 1,
"url": "http://localhost:8000/api/dcim/interfaces/1/",
"display": "Te1/0/1",
"device": {
"id": 1,
"url": "http://localhost:8000/api/dcim/devices/1/",
"display": "Switch1",
"name": "Switch1"
},
"name": "Te1/0/1",
"cable": null,
"_occupied": false
},
{
"id": 2,
"url": "http://localhost:8000/api/dcim/interfaces/2/",
"display": "Te1/0/1",
"device": {
"id": 2,
"url": "http://localhost:8000/api/dcim/devices/2/",
"display": "Switch2",
"name": "Switch2"
},
"name": "Te1/0/1",
"cable": null,
"_occupied": false
}
]
}As we can see we get the Coffee1/0/1 interface which we don't want (because we want Te...) I feel I'm very close to the right solution now. So, with all this background my question is, how do I get all the way there? Am I doing something wrong with my API parameter |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
The ORM and the filtersets are not the same. Only explicitly defined filters are available for filtering in the API and to my knowledge it's not possible to modify the core netbox filtersets. So the solution would be to create your own API endpoint for the Interface model, with your own filterset. |
Beta Was this translation helpful? Give feedback.
The ORM and the filtersets are not the same. Only explicitly defined filters are available for filtering in the API and to my knowledge it's not possible to modify the core netbox filtersets. So the solution would be to create your own API endpoint for the Interface model, with your own filterset.