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.