diff --git a/django/forms/fields.py b/django/forms/fields.py
index ad94ea4740..370f78e8b5 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -20,7 +20,7 @@ from django.forms.boundfield import BoundField
from django.forms.utils import from_current_timezone, to_current_timezone
from django.forms.widgets import (
FILE_INPUT_CONTRADICTION, CheckboxInput, ClearableFileInput, DateInput,
- DateTimeInput, EmailInput, HiddenInput, MultipleHiddenInput,
+ DateTimeInput, EmailInput, FileInput, HiddenInput, MultipleHiddenInput,
NullBooleanSelect, NumberInput, Select, SelectMultiple,
SplitDateTimeWidget, SplitHiddenDateTimeWidget, TextInput, TimeInput,
URLInput,
@@ -646,6 +646,12 @@ class ImageField(FileField):
f.seek(0)
return f
+ def widget_attrs(self, widget):
+ attrs = super().widget_attrs(widget)
+ if isinstance(widget, FileInput) and 'accept' not in widget.attrs:
+ attrs.setdefault('accept', 'image/*')
+ return attrs
+
class URLField(CharField):
widget = URLInput
diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt
index 8ad64f250a..87181fb33d 100644
--- a/docs/releases/2.1.txt
+++ b/docs/releases/2.1.txt
@@ -166,7 +166,8 @@ File Uploads
Forms
~~~~~
-* ...
+* The widget for ``ImageField`` now renders with the HTML attribute
+ ``accept="image/*"``.
Generic Views
~~~~~~~~~~~~~
diff --git a/tests/forms_tests/field_tests/test_imagefield.py b/tests/forms_tests/field_tests/test_imagefield.py
index 0a0f60440e..e38abc332d 100644
--- a/tests/forms_tests/field_tests/test_imagefield.py
+++ b/tests/forms_tests/field_tests/test_imagefield.py
@@ -2,9 +2,13 @@ import os
import unittest
from django.core.files.uploadedfile import SimpleUploadedFile
-from django.forms import ImageField, ValidationError
+from django.forms import (
+ ClearableFileInput, FileInput, ImageField, ValidationError, Widget,
+)
from django.test import SimpleTestCase
+from . import FormFieldAssertionsMixin
+
try:
from PIL import Image
except ImportError:
@@ -16,7 +20,7 @@ def get_img_path(path):
@unittest.skipUnless(Image, "Pillow is required to test ImageField")
-class ImageFieldTest(SimpleTestCase):
+class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
def test_imagefield_annotate_with_image_after_clean(self):
f = ImageField()
@@ -64,3 +68,21 @@ class ImageFieldTest(SimpleTestCase):
img_file = SimpleUploadedFile('1x1.txt', img_data)
with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."):
f.clean(img_file)
+
+ def test_widget_attrs_default_accept(self):
+ f = ImageField()
+ # Nothing added for non-FileInput widgets.
+ self.assertEqual(f.widget_attrs(Widget()), {})
+ self.assertEqual(f.widget_attrs(FileInput()), {'accept': 'image/*'})
+ self.assertEqual(f.widget_attrs(ClearableFileInput()), {'accept': 'image/*'})
+ self.assertWidgetRendersTo(f, '')
+
+ def test_widge_attrs_accept_specified(self):
+ f = ImageField(widget=FileInput(attrs={'accept': 'image/png'}))
+ self.assertEqual(f.widget_attrs(f.widget), {})
+ self.assertWidgetRendersTo(f, '')
+
+ def test_widge_attrs_accept_false(self):
+ f = ImageField(widget=FileInput(attrs={'accept': False}))
+ self.assertEqual(f.widget_attrs(f.widget), {})
+ self.assertWidgetRendersTo(f, '')