# Admin/htmx: Render single modelform field

**URL:** <https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901>\
**Category:** The Admin\
**Created:** [February 16, 2023, 10:58pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901 "2023-02-16T22:58:22Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![idahogray](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/idahogray/32/9595_2.png) [@idahogray](https://forum.djangoproject.com/u/idahogray)\
**Post date:** [February 16, 2023, 10:58pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/1 "2023-02-16T22:58:23Z")

</div>

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.

```auto
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.

```auto
<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.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 17, 2023, 3:40am UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/2 "2023-02-17T03:40:10Z")

</div>

Personally, I wouldn’t even think of issuing a request to render a single field for a situation like this.

If I had to do something like this, I’d create a small JavaScript function that can be added to the admin page as a [media asset](https://docs.djangoproject.com/en/4.1/ref/contrib/admin/#modeladmin-asset-definitions). This function would toggle that element between “enabled & visible” and “disabled & hidden” based upon the value of the other field.

---

<div class="post-metadata">

**Author:** ![leandrodesouzadev](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/leandrodesouzadev/32/8981_2.png) [@leandrodesouzadev](https://forum.djangoproject.com/u/leandrodesouzadev)\
**Post date:** [February 17, 2023, 11:20am UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/3 "2023-02-17T11:20:45Z")

</div>

I know that you want to use HTMX, but if you’re open to another solution, and you don’t want to actually write the javascript, [Alpine.js](https://alpinejs.dev/) can be handy in this situation.

---

<div class="post-metadata">

**Author:** ![idahogray](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/idahogray/32/9595_2.png) [@idahogray](https://forum.djangoproject.com/u/idahogray)\
**Post date:** [February 17, 2023, 3:05pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/4 "2023-02-17T15:05:37Z")

</div>

Hi @KenWhitesell , I realize I am probably making this harder than necessary and I may eventually go to using javascript. I was trying to use this as a learning exercise for htmx and I do realize I am making it harder than it needs to be. Thanks for the response.

---

<div class="post-metadata">

**Author:** ![idahogray](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/idahogray/32/9595_2.png) [@idahogray](https://forum.djangoproject.com/u/idahogray)\
**Post date:** [February 17, 2023, 3:07pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/5 "2023-02-17T15:07:12Z")

</div>

Hi @leandrodesouzadev, thanks for the response. I have heard of Alpine.js and will probably look into it once my stubbornness runs out and I abadon htmx in this use-case.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 17, 2023, 4:04pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/6 "2023-02-17T16:04:08Z")

</div>

I understand - I’m a big fan of HTMX myself.

However, when it comes to the addition or removal of fields in forms, it potentially adds another layer of complexity, particularly when form validation is involved on the server side. It’s one thing to have HTMX add a field to a form. It’s something else for that form to be submitted and to have the view be able to validate that modified form.

---

<div class="post-metadata">

**Author:** ![idahogray](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/idahogray/32/9595_2.png) [@idahogray](https://forum.djangoproject.com/u/idahogray)\
**Post date:** [February 18, 2023, 2:22pm UTC](https://forum.djangoproject.com/t/admin-htmx-render-single-modelform-field/18901/7 "2023-02-18T14:22:16Z")

</div>

Just in case someone else is silly enough to try this…I made some progress today. I stepped through the `_changeform_view` method of `ModelAdmin` in `django.contrib.admin.options.py` and had a key realization. `ModelAdmin.get_form` returns a form class, not the instance. I needed to create the instance before I could render it. I changed my `db_required_view` to the following and was able to successfully render the `database` field.

```auto
    def db_required_view(self, request, application_id=None):
        if request.GET.get("db_required"):
            ModelForm = self.get_form(request, self.model, change=True)
            obj = self.get_object(request, application_id)
            context = {
                **self.admin_site.each_context(request),
                "form": ModelForm(
                    {"database": obj.database if obj else None},
                    None,
                    obj,
                ),
            }
            return TemplateResponse(
                request,
                "admin/power_application_usage_api/application/db_required_field.html",
                context,
            )
        else:
            return reswap(retarget(HttpResponse(""), "div.field-database"), "outerHTML")

```
