"ManyToManyField with through and restrict() returns no results for related model from another plugin" #11336

Closed
opened 2025-12-29 21:43:49 +01:00 by adam · 3 comments
Owner

Originally created by @an-adestis on GitHub (Jul 1, 2025).

Deployment Type

NetBox Cloud

NetBox Version

v4.2.9

Python Version

3.10

Steps to Reproduce

  1. In your local NetBox development environment, you have two plugins installed:
  • adestis_netbox_applications (provides the InstalledApplication model)

  • adestis_netbox_certificate_management (plugin under development, which provides the Certificate model)

  1. Install the adestis-netbox-applications plugin via pip:
pip install adestis-netbox-applications
  1. Your Certificate model contains a ManyToMany relationship to InstalledApplication via a through model ApplicationAssignment:
class Certificate(NetBoxModel):
    installedapplication = models.ManyToManyField(
        'adestis_netbox_applications.InstalledApplication',
        through='ApplicationAssignment',
        related_name='certificate',
        verbose_name='Applications',
        blank=True
    )

class ApplicationAssignment(NetBoxModel):
    installedapplication = models.ForeignKey(
        'adestis_netbox_applications.InstalledApplication',
        on_delete=models.CASCADE,
        related_name='certificate_application_assignments',
        verbose_name='Application'
    )
    certificate = models.ForeignKey('Certificate', on_delete=models.CASCADE)

    class Meta:
        unique_together = ('certificate', 'installedapplication')
  1. Create instances of InstalledApplication and Certificate and link them through ApplicationAssignment.

  2. Register the following model view with a tab:

@register_model_view(InstalledApplication, name='certificate', path="my-certificates", detail=False)
class InstalledApplicationAffectedCertificateView(generic.ObjectChildrenView):
    queryset = InstalledApplication.objects.all()
    child_model = Certificate
    table = CertificateTable
    template_name = "adestis_netbox_certificate_management/certificate_application.html"
    actions = {
        'add': {'add'},
        'export': {'view'},
        'bulk_import': {'add'},
        'bulk_edit': {'change'},
        'bulk_remove_certificate': {'change'},
    }

    tab = ViewTab(
        label=_('Certificates'),
        badge=lambda obj: obj.certificate.count(),
        hide_if_empty=False
    )

    def get_children(self, request, parent):
        return Certificate.objects.restrict(request.user, 'view').filter(installedapplication=parent)
6. Attempt to view the InstalledApplication detail or list view expecting to see the Certificates tab.

Expected Behavior

The Certificates tab should be visible on the InstalledApplication views.

The tab badge should dynamically show the count of related certificates.

The queryset in get_children should return all related Certificate instances respecting permissions.

The ManyToMany relationship with through should work properly across plugins with permission filtering.

Additional Notes:
InstalledApplication model is provided by a separate plugin.

adestis_netbox_certificate_management plugin is under development and not yet released.

The issue is likely related to how ManyToMany with through models and .restrict() interact when related models come from different plugins.

Observed Behavior

The Certificates tab does not appear in the InstalledApplication views.

The queryset in get_children returns no results if accessed directly.

The badge count is never displayed since the tab is hidden.

As a result, linked certificates cannot be viewed through this UI.

Originally created by @an-adestis on GitHub (Jul 1, 2025). ### Deployment Type NetBox Cloud ### NetBox Version v4.2.9 ### Python Version 3.10 ### Steps to Reproduce 1. In your local NetBox development environment, you have two plugins installed: - adestis_netbox_applications (provides the InstalledApplication model) - adestis_netbox_certificate_management (plugin under development, which provides the Certificate model) 2. Install the adestis-netbox-applications plugin via pip: ``` pip install adestis-netbox-applications ``` 3. Your Certificate model contains a ManyToMany relationship to InstalledApplication via a through model ApplicationAssignment: ``` class Certificate(NetBoxModel): installedapplication = models.ManyToManyField( 'adestis_netbox_applications.InstalledApplication', through='ApplicationAssignment', related_name='certificate', verbose_name='Applications', blank=True ) class ApplicationAssignment(NetBoxModel): installedapplication = models.ForeignKey( 'adestis_netbox_applications.InstalledApplication', on_delete=models.CASCADE, related_name='certificate_application_assignments', verbose_name='Application' ) certificate = models.ForeignKey('Certificate', on_delete=models.CASCADE) class Meta: unique_together = ('certificate', 'installedapplication') ``` 4. Create instances of InstalledApplication and Certificate and link them through ApplicationAssignment. 5. Register the following model view with a tab: ``` @register_model_view(InstalledApplication, name='certificate', path="my-certificates", detail=False) class InstalledApplicationAffectedCertificateView(generic.ObjectChildrenView): queryset = InstalledApplication.objects.all() child_model = Certificate table = CertificateTable template_name = "adestis_netbox_certificate_management/certificate_application.html" actions = { 'add': {'add'}, 'export': {'view'}, 'bulk_import': {'add'}, 'bulk_edit': {'change'}, 'bulk_remove_certificate': {'change'}, } tab = ViewTab( label=_('Certificates'), badge=lambda obj: obj.certificate.count(), hide_if_empty=False ) def get_children(self, request, parent): return Certificate.objects.restrict(request.user, 'view').filter(installedapplication=parent) 6. Attempt to view the InstalledApplication detail or list view expecting to see the Certificates tab. ``` ### Expected Behavior The Certificates tab should be visible on the InstalledApplication views. The tab badge should dynamically show the count of related certificates. The queryset in get_children should return all related Certificate instances respecting permissions. The ManyToMany relationship with through should work properly across plugins with permission filtering. Additional Notes: InstalledApplication model is provided by a separate plugin. adestis_netbox_certificate_management plugin is under development and not yet released. The issue is likely related to how ManyToMany with through models and .restrict() interact when related models come from different plugins. ### Observed Behavior The Certificates tab does not appear in the InstalledApplication views. The queryset in get_children returns no results if accessed directly. The badge count is never displayed since the tab is hidden. As a result, linked certificates cannot be viewed through this UI.
adam added the type: bugpending closurestatus: revisions needed labels 2025-12-29 21:43:49 +01:00
adam closed this issue 2025-12-29 21:43:50 +01:00
Author
Owner

@arthanson commented on GitHub (Jul 1, 2025):

@an-adestis Thank you for opening a bug report. Unfortunately, the information you have provided is not sufficient for someone else to attempt to reproduce the reported behavior. Remember, each bug report must include detailed steps that someone else can follow on a clean, empty NetBox installation to reproduce the exact problem you're experiencing. These instructions should include the creation of any involved objects, any configuration changes, and complete accounting of the actions being taken.

While you outline where you think it isn't working in your apps a reviewer would have to make a lot of assumptions trying to re-create it with the information you have provided. I would suggest:

  1. Try to put this code in the same app / plugin and see if it works (or doesn't) there. If it doesn't work in a single plugin then there is something else wrong with the code.
  2. If it does work in a single plugin, narrow down the code and create a two example plugins with only this code to see if it reproduces the issue. You could submit those example plugins with the bug report.

Given that - this is fairly specialized (having one plugin field depend on another plugin field) and not really something we have tried or explicitly guarantee to work but I can't think of anything off-hand why it wouldn't. I'm assuming there is reason why this is split between two plugins.

@arthanson commented on GitHub (Jul 1, 2025): @an-adestis Thank you for opening a bug report. Unfortunately, the information you have provided is not sufficient for someone else to attempt to reproduce the reported behavior. Remember, each bug report must include detailed steps that someone else can follow on a clean, empty NetBox installation to reproduce the exact problem you're experiencing. These instructions should include the creation of any involved objects, any configuration changes, and complete accounting of the actions being taken. While you outline where you think it isn't working in your apps a reviewer would have to make a lot of assumptions trying to re-create it with the information you have provided. I would suggest: 1. Try to put this code in the same app / plugin and see if it works (or doesn't) there. If it doesn't work in a single plugin then there is something else wrong with the code. 2. If it does work in a single plugin, narrow down the code and create a two example plugins with **only this code** to see if it reproduces the issue. You could submit those example plugins with the bug report. Given that - this is fairly specialized (having one plugin field depend on another plugin field) and not really something we have tried or explicitly guarantee to work but I can't think of anything off-hand why it wouldn't. I'm assuming there is reason why this is split between two plugins.
Author
Owner

@github-actions[bot] commented on GitHub (Jul 9, 2025):

This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.

@github-actions[bot] commented on GitHub (Jul 9, 2025): This is a reminder that additional information is needed in order to further triage this issue. If the requested details are not provided, the issue will soon be closed automatically.
Author
Owner

@github-actions[bot] commented on GitHub (Jul 16, 2025):

This issue is being closed as no further information has been provided. If you would like to revisit this topic, please first modify your original post to include all the requested detail, and then ask that the issue be reopened.

@github-actions[bot] commented on GitHub (Jul 16, 2025): This issue is being closed as no further information has been provided. If you would like to revisit this topic, please first modify your original post to include all the requested detail, and then ask that the issue be reopened.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11336