Fixed #29284 -- Made ImageField render with accept="image/*"' HTML attribute.

This commit is contained in:
safu9 2018-04-03 12:06:08 +09:00 committed by Tim Graham
parent cf8fc47974
commit 9fd9f8bbb2
3 changed files with 33 additions and 4 deletions

View File

@ -20,7 +20,7 @@ from django.forms.boundfield import BoundField
from django.forms.utils import from_current_timezone, to_current_timezone from django.forms.utils import from_current_timezone, to_current_timezone
from django.forms.widgets import ( from django.forms.widgets import (
FILE_INPUT_CONTRADICTION, CheckboxInput, ClearableFileInput, DateInput, FILE_INPUT_CONTRADICTION, CheckboxInput, ClearableFileInput, DateInput,
DateTimeInput, EmailInput, HiddenInput, MultipleHiddenInput, DateTimeInput, EmailInput, FileInput, HiddenInput, MultipleHiddenInput,
NullBooleanSelect, NumberInput, Select, SelectMultiple, NullBooleanSelect, NumberInput, Select, SelectMultiple,
SplitDateTimeWidget, SplitHiddenDateTimeWidget, TextInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget, TextInput, TimeInput,
URLInput, URLInput,
@ -646,6 +646,12 @@ class ImageField(FileField):
f.seek(0) f.seek(0)
return f 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): class URLField(CharField):
widget = URLInput widget = URLInput

View File

@ -166,7 +166,8 @@ File Uploads
Forms Forms
~~~~~ ~~~~~
* ... * The widget for ``ImageField`` now renders with the HTML attribute
``accept="image/*"``.
Generic Views Generic Views
~~~~~~~~~~~~~ ~~~~~~~~~~~~~

View File

@ -2,9 +2,13 @@ import os
import unittest import unittest
from django.core.files.uploadedfile import SimpleUploadedFile 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 django.test import SimpleTestCase
from . import FormFieldAssertionsMixin
try: try:
from PIL import Image from PIL import Image
except ImportError: except ImportError:
@ -16,7 +20,7 @@ def get_img_path(path):
@unittest.skipUnless(Image, "Pillow is required to test ImageField") @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): def test_imagefield_annotate_with_image_after_clean(self):
f = ImageField() f = ImageField()
@ -64,3 +68,21 @@ class ImageFieldTest(SimpleTestCase):
img_file = SimpleUploadedFile('1x1.txt', img_data) img_file = SimpleUploadedFile('1x1.txt', img_data)
with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."): with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."):
f.clean(img_file) 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, '<input type="file" name="f" accept="image/*" required id="id_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, '<input type="file" name="f" accept="image/png" required id="id_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, '<input type="file" name="f" required id="id_f" />')