Skip to content

DynamicModelChoiceField doesn't render error message on submit #18916

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
chii0815 opened this issue Mar 16, 2025 · 3 comments
Open

DynamicModelChoiceField doesn't render error message on submit #18916

chii0815 opened this issue Mar 16, 2025 · 3 comments
Assignees
Labels
severity: low Does not significantly disrupt application functionality, or a workaround is available status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application

Comments

@chii0815
Copy link

Deployment Type

Self-hosted

NetBox Version

v.4.2.5

Python Version

3.11

Steps to Reproduce

While developing a plugin I realized that the DynamicModelChoiceField doesn't display an error if required=True and the nothing is selected. The form just doesn't submit and the view doesn't give a hint why.

  1. create a form with two choice fields (one django.forms.ModelChoiceField and one DynamicModelChoiceField)
  2. set both to be required

Expected Behavior

When both are empty the form should show an error message on submit

Observed Behavior

only the forms.ModelChoiceField shows an error message

Image

@chii0815 chii0815 added status: needs triage This issue is awaiting triage by a maintainer type: bug A confirmed report of unexpected behavior in the application labels Mar 16, 2025
@chii0815
Copy link
Author

this is my py file for this form

from django import forms
from circuits.models import Provider
from tenancy.models import Tenant
from netbox.forms import NetBoxModelForm
from django.utils.translation import gettext_lazy as _
from utilities.forms.fields import DynamicModelChoiceField
from ..models import CVS

class CVSForm(NetBoxModelForm):

    provider = forms.ModelChoiceField(
        queryset = Provider.objects.all(),
        required = True,
        label = _('provider')
    )

    tenant = DynamicModelChoiceField(
        queryset = Tenant.objects.all(),
        required = True,
        selector= True,
        label= _('tenant')
    )  

    class Meta:
        model = CVS
        fields = ('name', 'provider', 'tenant', 'tags')

    def clean(self):
        super().clean()

@chii0815
Copy link
Author

chii0815 commented Mar 16, 2025

this also happens on netboxes dcim model device-types:

Image

@bctiemann bctiemann added status: needs owner This issue is tentatively accepted pending a volunteer committed to its implementation severity: low Does not significantly disrupt application functionality, or a workaround is available and removed status: needs triage This issue is awaiting triage by a maintainer labels Mar 18, 2025
@jnovinger
Copy link
Member

jnovinger commented Apr 9, 2025

I've tracked this down to the core cause, which is that this is being caused by the underlying APISelect widget. Any form field that uses APISelect, either through DynamicModelChoiceField or some other way, is affected by this bug.

The tl;dr is that APISelect uses its own template, netbox/utilities/templates/widgets/apiselect.html which ends up wrapping the base django/forms/widgets/select.html template from Django core in a <div class="d-flex">...</div> and sets up either the object selector modal and/or the quick add modal.

It' this extra div that causes the problem, because it changes the DOM tree structure just enough that when our form submit handler marks the element as invalid, it doesn't see a sibling element with the class="invalid-feedback" which it should make visible.

You can observe this behavior in a couple of ways:

  1. Remove the wrapping <div>...</div>, which breaks the display of the modal buttons
  2. Add a widget=Select(), which comes from django.forms.widgets, and doesn't break the modal buttons but just flat out will not display them since it uses a different template.

Alright, enough for now. I think I'm going to might have to fix this for my work on #8423.

@jeremystretch jeremystretch added status: accepted This issue has been accepted for implementation and removed status: needs owner This issue is tentatively accepted pending a volunteer committed to its implementation labels Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
severity: low Does not significantly disrupt application functionality, or a workaround is available status: accepted This issue has been accepted for implementation type: bug A confirmed report of unexpected behavior in the application
Projects
None yet
Development

No branches or pull requests

4 participants