Django ImageField - render only the <input>

2019-03-04 18:00发布

问题:

I have a Django form which has an ImageField in it, and I render the field like this in my template:

{{ form.my_image_field }}

The resulting HTML looks like this:

Currently: <a href="https://....s3.amazonaws.com/....jpg">....jpg</a>
<input name="my_image_field-clear" id="my_image_field-clear_id" type="checkbox">
<label for="my_image_field-clear_id">Clear</label><br>
Change:
<input name="my_image_field" id="id_my_image_field" type="file">

I want to render only the <input element, since I am using the bootstra-fileinput library: https://www.npmjs.com/package/bootstrap-fileinput :

<input name="my_image_field" id="id_my_image_field" type="file">

Is it possible to do this without writing the <input> tag manually in the template?

回答1:

Normally, ImageFields use the ClearableFileInput widget. This widget by default uses the template name django/forms/widgets/clearable_file_input.html.

You can make your own ClearableFileInput widget subclass that uses a different template.

from django.forms.widgets import ClearableFileInput

class MyImageWidget(ClearableFileInput):
    template_name = "myapp/my_template.html"

The content of that template may just be simply the <input> part of the default template with the extraneous label and checkbox removed. You can customize it however you need. That might look like

<!-- myapp/my_template.html -->
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>

Then in your form specify the widget for the ImageField

class MyForm(forms.Form):
    #  ...
    my_image_field = forms.ImageField(widget=MyImageWidget)
    #  ...

Django also provides a FileInput widget which uses a plain template. If that suits your needs simply do

class MyForm(forms.Form):
    #  ...
    my_image_field = forms.ImageField(widget=forms.widgets.FileInput)

Alternatively, you could simply override the default template by creating the django/forms/widgets/clearable_file_input.html file in your project's template directory. However, this would apply the change to the rendering of all fields using the ClearableFileInput widget, so it is not as flexible of an approach.