diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index b2c93227e7..e3497f2494 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -230,7 +230,6 @@ class FileField(Field): def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs): self._primary_key_set_explicitly = 'primary_key' in kwargs - self._unique_set_explicitly = 'unique' in kwargs self.storage = storage or default_storage self.upload_to = upload_to @@ -240,22 +239,9 @@ class FileField(Field): def check(self, **kwargs): errors = super(FileField, self).check(**kwargs) - errors.extend(self._check_unique()) errors.extend(self._check_primary_key()) return errors - def _check_unique(self): - if self._unique_set_explicitly: - return [ - checks.Error( - "'unique' is not a valid argument for a %s." % self.__class__.__name__, - obj=self, - id='fields.E200', - ) - ] - else: - return [] - def _check_primary_key(self): if self._primary_key_set_explicitly: return [ diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index f71a1882be..638f9af564 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -183,6 +183,7 @@ File Fields ~~~~~~~~~~~ * **fields.E200**: ``unique`` is not a valid argument for a ``FileField``. + *This check is removed in Django 1.11*. * **fields.E201**: ``primary_key`` is not a valid argument for a ``FileField``. * **fields.E210**: Cannot use ``ImageField`` because Pillow is not installed. diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index df96fbf827..6c9c5057c2 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -306,12 +306,16 @@ you try to save a model with a duplicate value in a :attr:`~Field.unique` field, a :exc:`django.db.IntegrityError` will be raised by the model's :meth:`~django.db.models.Model.save` method. -This option is valid on all field types except :class:`ManyToManyField`, -:class:`OneToOneField`, and :class:`FileField`. +This option is valid on all field types except :class:`ManyToManyField` and +:class:`OneToOneField`. Note that when ``unique`` is ``True``, you don't need to specify :attr:`~Field.db_index`, because ``unique`` implies the creation of an index. +.. versionchanged:: 1.11 + + In older versions, ``unique=True`` can't be used on :class:`FileField`. + ``unique_for_date`` ------------------- @@ -628,8 +632,8 @@ uses :class:`~django.core.validators.EmailValidator` to validate the input. A file-upload field. .. note:: - The ``primary_key`` and ``unique`` arguments are not supported, and will - raise a ``TypeError`` if used. + The ``primary_key`` argument isn't supported and will raise a an error if + used. Has two optional arguments: diff --git a/docs/releases/1.11.txt b/docs/releases/1.11.txt index 7886d84a3b..55fe3be7f6 100644 --- a/docs/releases/1.11.txt +++ b/docs/releases/1.11.txt @@ -312,6 +312,9 @@ Models * Added support for query expressions on lookups that take multiple arguments, such as ``range``. +* You can now use the ``unique=True`` option with + :class:`~django.db.models.FileField`. + Requests and Responses ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py index 2f16e83d18..aff6a74659 100644 --- a/tests/invalid_models_tests/test_ordinary_fields.py +++ b/tests/invalid_models_tests/test_ordinary_fields.py @@ -440,21 +440,6 @@ class FileFieldTests(SimpleTestCase): expected = [] self.assertEqual(errors, expected) - def test_unique(self): - class Model(models.Model): - field = models.FileField(unique=False, upload_to='somewhere') - - field = Model._meta.get_field('field') - errors = field.check() - expected = [ - Error( - "'unique' is not a valid argument for a FileField.", - obj=field, - id='fields.E200', - ) - ] - self.assertEqual(errors, expected) - def test_primary_key(self): class Model(models.Model): field = models.FileField(primary_key=False, upload_to='somewhere') diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py index aeeb6e88da..faa7d08189 100644 --- a/tests/model_fields/models.py +++ b/tests/model_fields/models.py @@ -216,7 +216,7 @@ class DataModel(models.Model): class Document(models.Model): - myfile = models.FileField(upload_to='unused') + myfile = models.FileField(upload_to='unused', unique=True) ############################################################################### # ImageField diff --git a/tests/model_fields/test_filefield.py b/tests/model_fields/test_filefield.py index e67b6dd515..3fefcd1fb6 100644 --- a/tests/model_fields/test_filefield.py +++ b/tests/model_fields/test_filefield.py @@ -4,6 +4,7 @@ import unittest from django.core.files import temp from django.core.files.uploadedfile import TemporaryUploadedFile +from django.db.utils import IntegrityError from django.test import TestCase, override_settings from .models import Document @@ -61,6 +62,15 @@ class FileFieldTests(TestCase): Document.objects.create(myfile='something.txt') self.assertEqual(Document.objects.defer('myfile')[0].myfile, 'something.txt') + def test_unique_when_same_filename(self): + """ + A FileField with unique=True shouldn't allow two instances with the + same name to be saved. + """ + Document.objects.create(myfile='something.txt') + with self.assertRaises(IntegrityError): + Document.objects.create(myfile='something.txt') + @unittest.skipIf(sys.platform.startswith('win'), "Windows doesn't support moving open files.") # The file's source and destination must be on the same filesystem. @override_settings(MEDIA_ROOT=temp.gettempdir())