From 622ead6aaf55288cd355f22e8bb9c56d8e12556c Mon Sep 17 00:00:00 2001 From: Cameron Curry Date: Mon, 18 Dec 2017 21:19:57 +0100 Subject: [PATCH] Fixed #28937 -- Allowed BinaryField to be editable=True. --- AUTHORS | 1 + django/db/models/fields/__init__.py | 7 +++++-- docs/ref/models/fields.txt | 10 ++++++++-- docs/releases/2.1.txt | 3 +++ docs/topics/forms/modelforms.txt | 5 +++++ tests/field_deconstruction/tests.py | 4 ++++ tests/model_fields/test_binaryfield.py | 9 +++++++++ 7 files changed, 35 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index a46cf625cb..97d512dea1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -138,6 +138,7 @@ answer newbie questions, and generally made Django that much better: btoll@bestweb.net C8E Calvin Spealman + Cameron Curry Cameron Knight (ckknight) Can Burak Çilingir Carl Meyer diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 999b37a4f4..1aafa83a1f 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -2295,14 +2295,17 @@ class BinaryField(Field): empty_values = [None, b''] def __init__(self, *args, **kwargs): - kwargs['editable'] = False + kwargs.setdefault('editable', False) super().__init__(*args, **kwargs) if self.max_length is not None: self.validators.append(validators.MaxLengthValidator(self.max_length)) def deconstruct(self): name, path, args, kwargs = super().deconstruct() - del kwargs['editable'] + if self.editable: + kwargs['editable'] = True + else: + del kwargs['editable'] return name, path, args, kwargs def get_internal_type(self): diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index bcbda45145..afd0d6ff0c 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -420,8 +420,14 @@ guaranteed to fit numbers from ``-9223372036854775808`` to A field to store raw binary data. It only supports ``bytes`` assignment. Be aware that this field has limited functionality. For example, it is not possible -to filter a queryset on a ``BinaryField`` value. It is also not possible to -include a ``BinaryField`` in a :class:`~django.forms.ModelForm`. +to filter a queryset on a ``BinaryField`` value. + +By default, ``BinaryField`` sets :attr:`~Field.editable` to ``False``, in which +case it can't be included in a :class:`~django.forms.ModelForm`. + +.. versionchanged:: 2.1 + + Older versions don't allow setting ``editable`` to ``True``. .. admonition:: Abusing ``BinaryField`` diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt index 1183bd3121..b786fdae11 100644 --- a/docs/releases/2.1.txt +++ b/docs/releases/2.1.txt @@ -157,6 +157,9 @@ Models * Models can now use ``__init_subclass__()`` from :pep:`487`. +* A ``BinaryField`` may now be set to ``editable=True`` if you wish to include + it in model forms. + Requests and Responses ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt index 1969474b89..c261fb75d7 100644 --- a/docs/topics/forms/modelforms.txt +++ b/docs/topics/forms/modelforms.txt @@ -62,6 +62,11 @@ Model field Form field ``min_value`` set to -9223372036854775808 and ``max_value`` set to 9223372036854775807. +:class:`BinaryField` :class:`~django.forms.CharField`, if + :attr:`~.Field.editable` is set to + ``True`` on the model field, otherwise not + represented in the form. + :class:`BooleanField` :class:`~django.forms.BooleanField` :class:`CharField` :class:`~django.forms.CharField` with diff --git a/tests/field_deconstruction/tests.py b/tests/field_deconstruction/tests.py index f1652e2c40..2cf1f93e22 100644 --- a/tests/field_deconstruction/tests.py +++ b/tests/field_deconstruction/tests.py @@ -514,3 +514,7 @@ class FieldDeconstructionTests(SimpleTestCase): self.assertEqual(path, "django.db.models.BinaryField") self.assertEqual(args, []) self.assertEqual(kwargs, {}) + field = models.BinaryField(editable=True) + name, path, args, kwargs = field.deconstruct() + self.assertEqual(args, []) + self.assertEqual(kwargs, {'editable': True}) diff --git a/tests/model_fields/test_binaryfield.py b/tests/model_fields/test_binaryfield.py index 9d97d1118f..ee40ed48fb 100644 --- a/tests/model_fields/test_binaryfield.py +++ b/tests/model_fields/test_binaryfield.py @@ -1,4 +1,5 @@ from django.core.exceptions import ValidationError +from django.db import models from django.test import TestCase from .models import DataModel @@ -25,3 +26,11 @@ class BinaryFieldTests(TestCase): dm = DataModel(short_data=self.binary_data * 4) with self.assertRaises(ValidationError): dm.full_clean() + + def test_editable(self): + field = models.BinaryField() + self.assertIs(field.editable, False) + field = models.BinaryField(editable=True) + self.assertIs(field.editable, True) + field = models.BinaryField(editable=False) + self.assertIs(field.editable, False)