Răsfoiți Sursa

Fixed #27532 -- Deprecated Model._meta.has_auto_field

Adam Chainz 8 ani în urmă
părinte
comite
6252fd6314

+ 2 - 2
django/contrib/admin/helpers.py

@@ -350,12 +350,12 @@ class InlineAdminForm(AdminForm):
 
     def needs_explicit_pk_field(self):
         # Auto fields are editable (oddly), so need to check for auto or non-editable pk
-        if self.form._meta.model._meta.has_auto_field or not self.form._meta.model._meta.pk.editable:
+        if self.form._meta.model._meta.auto_field or not self.form._meta.model._meta.pk.editable:
             return True
         # Also search any parents for an auto field. (The pk info is propagated to child
         # models so that does not need to be checked in parents.)
         for parent in self.form._meta.model._meta.get_parent_list():
-            if parent._meta.has_auto_field:
+            if parent._meta.auto_field:
                 return True
         return False
 

+ 1 - 1
django/db/models/base.py

@@ -900,7 +900,7 @@ class Model(six.with_metaclass(ModelBase)):
             if not pk_set:
                 fields = [f for f in fields if f is not meta.auto_field]
 
-            update_pk = bool(meta.has_auto_field and not pk_set)
+            update_pk = meta.auto_field and not pk_set
             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
             if update_pk:
                 setattr(self, meta.pk.attname, result)

+ 1 - 3
django/db/models/fields/__init__.py

@@ -948,10 +948,8 @@ class AutoField(Field):
         return int(value)
 
     def contribute_to_class(self, cls, name, **kwargs):
-        assert not cls._meta.has_auto_field, \
-            "A model can't have more than one AutoField."
+        assert not cls._meta.auto_field, "A model can't have more than one AutoField."
         super(AutoField, self).contribute_to_class(cls, name, **kwargs)
-        cls._meta.has_auto_field = True
         cls._meta.auto_field = self
 
     def formfield(self, **kwargs):

+ 15 - 2
django/db/models/options.py

@@ -17,7 +17,8 @@ from django.db.models.fields.related import OneToOneField
 from django.utils import six
 from django.utils.datastructures import ImmutableList, OrderedSet
 from django.utils.deprecation import (
-    RemovedInDjango20Warning, warn_about_renamed_method,
+    RemovedInDjango20Warning, RemovedInDjango21Warning,
+    warn_about_renamed_method,
 )
 from django.utils.encoding import force_text, python_2_unicode_compatible
 from django.utils.functional import cached_property
@@ -113,7 +114,6 @@ class Options(object):
         self.required_db_vendor = None
         self.meta = meta
         self.pk = None
-        self.has_auto_field = False
         self.auto_field = None
         self.abstract = False
         self.managed = True
@@ -825,3 +825,16 @@ class Options(object):
         # Store result into cache for later access
         self._get_fields_cache[cache_key] = fields
         return fields
+
+    @property
+    def has_auto_field(self):
+        warnings.warn(
+            'Model._meta.has_auto_field is deprecated in favor of checking if '
+            'Model._meta.auto_field is not None.',
+            RemovedInDjango21Warning, stacklevel=2
+        )
+        return self.auto_field is not None
+
+    @has_auto_field.setter
+    def has_auto_field(self, value):
+        pass

+ 2 - 0
docs/internals/deprecation.txt

@@ -46,6 +46,8 @@ details on these changes.
 * The ``USE_ETAGS`` setting will be removed. ``CommonMiddleware`` and
   ``django.utils.cache.patch_response_headers()`` will no longer set ETags.
 
+* The ``Model._meta.has_auto_field`` attribute will be removed.
+
 .. _deprecation-removed-in-2.0:
 
 2.0

+ 3 - 0
docs/releases/1.11.txt

@@ -707,3 +707,6 @@ Miscellaneous
   ``ETag`` header to responses regardless of the setting. ``CommonMiddleware``
   and ``django.utils.cache.patch_response_headers()`` will no longer set ETags
   when the deprecation ends.
+
+* ``Model._meta.has_auto_field`` is deprecated in favor of checking if
+  ``Model._meta.auto_field is not None``.

+ 22 - 0
tests/model_meta/test_removedindjango21.py

@@ -0,0 +1,22 @@
+import warnings
+
+from django.test import SimpleTestCase
+
+from .models import Person
+
+
+class HasAutoFieldTests(SimpleTestCase):
+
+    def test_get_warns(self):
+        with warnings.catch_warnings(record=True) as warns:
+            warnings.simplefilter('always')
+            Person._meta.has_auto_field
+        self.assertEqual(len(warns), 1)
+        self.assertEqual(
+            str(warns[0].message),
+            'Model._meta.has_auto_field is deprecated in favor of checking if '
+            'Model._meta.auto_field is not None.',
+        )
+
+    def test_set_does_nothing(self):
+        Person._meta.has_auto_field = True