Refs #16055 -- Deprecated get_joining_columns()/get_reverse_joining_columns() methods.

This commit is contained in:
David Wobrock 2023-04-18 10:20:32 +02:00 committed by Mariusz Felisiak
parent 9bbf97bcdb
commit 8b1ff0da4b
6 changed files with 94 additions and 0 deletions

View File

@ -1,5 +1,6 @@
import functools import functools
import inspect import inspect
import warnings
from functools import partial from functools import partial
from django import forms from django import forms
@ -13,6 +14,7 @@ from django.db.models.constants import LOOKUP_SEP
from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL
from django.db.models.query_utils import PathInfo from django.db.models.query_utils import PathInfo
from django.db.models.utils import make_model_tuple from django.db.models.utils import make_model_tuple
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -777,12 +779,22 @@ class ForeignObject(RelatedField):
return attname, None return attname, None
def get_joining_columns(self, reverse_join=False): def get_joining_columns(self, reverse_join=False):
warnings.warn(
"ForeignObject.get_joining_columns() is deprecated. Use "
"get_joining_fields() instead.",
RemovedInDjango60Warning,
)
source = self.reverse_related_fields if reverse_join else self.related_fields source = self.reverse_related_fields if reverse_join else self.related_fields
return tuple( return tuple(
(lhs_field.column, rhs_field.column) for lhs_field, rhs_field in source (lhs_field.column, rhs_field.column) for lhs_field, rhs_field in source
) )
def get_reverse_joining_columns(self): def get_reverse_joining_columns(self):
warnings.warn(
"ForeignObject.get_reverse_joining_columns() is deprecated. Use "
"get_reverse_joining_fields() instead.",
RemovedInDjango60Warning,
)
return self.get_joining_columns(reverse_join=True) return self.get_joining_columns(reverse_join=True)
def get_joining_fields(self, reverse_join=False): def get_joining_fields(self, reverse_join=False):

View File

@ -8,8 +8,10 @@ in the ``remote_field`` attribute of the field.
They also act as reverse fields for the purposes of the Meta API because They also act as reverse fields for the purposes of the Meta API because
they're the closest concept currently available. they're the closest concept currently available.
""" """
import warnings
from django.core import exceptions from django.core import exceptions
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.hashable import make_hashable from django.utils.hashable import make_hashable
@ -193,6 +195,11 @@ class ForeignObjectRel(FieldCacheMixin):
return bool(self.related_name) and self.related_name[-1] == "+" return bool(self.related_name) and self.related_name[-1] == "+"
def get_joining_columns(self): def get_joining_columns(self):
warnings.warn(
"ForeignObjectRel.get_joining_columns() is deprecated. Use "
"get_joining_fields() instead.",
RemovedInDjango60Warning,
)
return self.field.get_reverse_joining_columns() return self.field.get_reverse_joining_columns()
def get_joining_fields(self): def get_joining_fields(self):

View File

@ -2,8 +2,11 @@
Useful auxiliary data structures for query construction. Not useful outside Useful auxiliary data structures for query construction. Not useful outside
the SQL domain. the SQL domain.
""" """
import warnings
from django.core.exceptions import FullResultSet from django.core.exceptions import FullResultSet
from django.db.models.sql.constants import INNER, LOUTER from django.db.models.sql.constants import INNER, LOUTER
from django.utils.deprecation import RemovedInDjango60Warning
class MultiJoin(Exception): class MultiJoin(Exception):
@ -68,6 +71,11 @@ class Join:
for lhs_field, rhs_field in self.join_fields for lhs_field, rhs_field in self.join_fields
) )
else: else:
warnings.warn(
"The usage of get_joining_columns() in Join is deprecated. Implement "
"get_joining_fields() instead.",
RemovedInDjango60Warning,
)
self.join_fields = None self.join_fields = None
self.join_cols = join_field.get_joining_columns() self.join_cols = join_field.get_joining_columns()
# Along which field (or ForeignObjectRel in the reverse join case) # Along which field (or ForeignObjectRel in the reverse join case)
@ -87,9 +95,13 @@ class Join:
qn = compiler.quote_name_unless_alias qn = compiler.quote_name_unless_alias
qn2 = connection.ops.quote_name qn2 = connection.ops.quote_name
# Add a join condition for each pair of joining columns. # Add a join condition for each pair of joining columns.
# RemovedInDjango60Warning: when the depraction ends, replace with:
# for lhs, rhs in self.join_field:
join_fields = self.join_fields or self.join_cols join_fields = self.join_fields or self.join_cols
for lhs, rhs in join_fields: for lhs, rhs in join_fields:
if isinstance(lhs, str): if isinstance(lhs, str):
# RemovedInDjango60Warning: when the depraction ends, remove
# the branch for strings.
lhs_full_name = "%s.%s" % (qn(self.parent_alias), qn2(lhs)) lhs_full_name = "%s.%s" % (qn(self.parent_alias), qn2(lhs))
rhs_full_name = "%s.%s" % (qn(self.table_alias), qn2(rhs)) rhs_full_name = "%s.%s" % (qn(self.table_alias), qn2(rhs))
else: else:

View File

@ -24,6 +24,14 @@ details on these changes.
* ``request`` will be required in the signature of * ``request`` will be required in the signature of
``ModelAdmin.lookup_allowed()`` subclasses. ``ModelAdmin.lookup_allowed()`` subclasses.
* The ``django.db.models.sql.datastructures.Join`` will no longer fallback to
``get_joining_columns()``.
* The ``get_joining_columns()`` method of ``ForeignObject`` and
``ForeignObjectRel`` will be removed.
* The ``ForeignObject.get_reverse_joining_columns()`` method will be removed.
.. _deprecation-removed-in-5.1: .. _deprecation-removed-in-5.1:
5.1 5.1

View File

@ -391,6 +391,14 @@ Miscellaneous
Support for ``ModelAdmin`` subclasses that do not accept this argument is Support for ``ModelAdmin`` subclasses that do not accept this argument is
deprecated. deprecated.
* The ``get_joining_columns()`` method of ``ForeignObject`` and
``ForeignObjectRel`` is deprecated. Starting with Django 6.0,
``django.db.models.sql.datastructures.Join`` will no longer fallback to
``get_joining_columns()``. Subclasses should implement
``get_joining_fields()`` instead.
* The ``ForeignObject.get_reverse_joining_columns()`` method is deprecated.
Features removed in 5.0 Features removed in 5.0
======================= =======================

View File

@ -8,6 +8,7 @@ from django.db import models
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
from django.test.utils import isolate_apps from django.test.utils import isolate_apps
from django.utils import translation from django.utils import translation
from django.utils.deprecation import RemovedInDjango60Warning
from .models import ( from .models import (
Article, Article,
@ -687,3 +688,49 @@ class TestCachedPathInfo(TestCase):
foreign_object_restored = pickle.loads(pickle.dumps(foreign_object)) foreign_object_restored = pickle.loads(pickle.dumps(foreign_object))
self.assertIn("path_infos", foreign_object_restored.__dict__) self.assertIn("path_infos", foreign_object_restored.__dict__)
self.assertIn("reverse_path_infos", foreign_object_restored.__dict__) self.assertIn("reverse_path_infos", foreign_object_restored.__dict__)
class GetJoiningDeprecationTests(TestCase):
def test_foreign_object_get_joining_columns_warning(self):
msg = (
"ForeignObject.get_joining_columns() is deprecated. Use "
"get_joining_fields() instead."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
Membership.person.field.get_joining_columns()
def test_foreign_object_get_reverse_joining_columns_warning(self):
msg = (
"ForeignObject.get_reverse_joining_columns() is deprecated. Use "
"get_reverse_joining_fields() instead."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
Membership.person.field.get_reverse_joining_columns()
def test_foreign_object_rel_get_joining_columns_warning(self):
msg = (
"ForeignObjectRel.get_joining_columns() is deprecated. Use "
"get_joining_fields() instead."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
Membership.person.field.remote_field.get_joining_columns()
def test_join_get_joining_columns_warning(self):
class CustomForeignKey(models.ForeignKey):
def __getattribute__(self, attr):
if attr == "get_joining_fields":
raise AttributeError
return super().__getattribute__(attr)
class CustomParent(models.Model):
value = models.CharField(max_length=255)
class CustomChild(models.Model):
links = CustomForeignKey(CustomParent, models.CASCADE)
msg = (
"The usage of get_joining_columns() in Join is deprecated. Implement "
"get_joining_fields() instead."
)
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
CustomChild.objects.filter(links__value="value")