Hello, I am trying to make the ModelForm rendered via the ModelAdmin show or hide one field based on the status of another field’s checkbox. I am also trying to learn and apply htmx rather than using javascript.
I have figured out how to do this for the add view. However, I am having trouble obtaining the form and having it render the one field I need in a change view.
I have added the URL and view that htmx uses to get the field html.
Here is my ModelAdmin. It will include/exclude the database field depending on the status of the db_required field, which is provided by htmx. In the db_required_view, I return an empty response if db_required is not in the htmx request, or I render the database form field. For the add view, self.model is None and the form is correctly returned. However, the form is not being built correctly when using this from the change view’s form.
class ApplicationAdmin(admin.ModelAdmin):
model = Application
list_display = ("name", "business_unit", "application_link", "notes")
inlines = [ApplicationComponentInline]
autocomplete_fields = ["business_unit"]
form = ApplicationModelForm
def get_urls(self):
urls = super().get_urls()
my_urls = [
path(
"add/db_required/",
self.admin_site.admin_view(self.db_required_view),
name="application-add-db_required",
),
path(
"<uuid:application_id>/change/db_required/",
self.admin_site.admin_view(self.db_required_view),
name="application-change-db_required",
),
]
return my_urls + urls
def get_exclude(self, request, obj=None):
if (
not request.GET.get("db_required")
and not request.POST.get("db_required")
and not obj.db_required
):
print("Excluding 'database' field.")
self.exclude = ("database",)
else:
self.exclude = tuple()
return super().get_exclude(request, obj)
def db_required_view(self, request, application_id=None):
if request.GET.get("db_required"):
context = {
**self.admin_site.each_context(request),
"form": self.get_form(request, self.model),
}
return TemplateResponse(
request,
"admin/power_application_usage_api/application/db_required_field.html",
context,
)
else:
return reswap(retarget(HttpResponse(""), "div.field-database"), "outerHTML")
And here is my template that renders the database field.
<div class="form-row field-database">
<div>
<label for="id_database">Database:</label>
{{ form.database }}
<div class="help" id="id_database_helptext">
If your application or tool does require a database,
please select which one.
</div>
</div>
</div>
Any pointers would be greatly appreciated. Also, if there is a better way to accomplish rendering a single ModelForm field, I would appreciate seeing that as well.
Thanks in advance.