Fixed #30477 -- Made reverse lookup use Field.get_db_prep_value() from the target field.

This commit is contained in:
can 2019-06-24 18:48:10 +03:00 committed by Mariusz Felisiak
parent 76b993a117
commit 325d5d6445
3 changed files with 29 additions and 14 deletions

View File

@ -176,8 +176,9 @@ class FieldGetDbPrepValueMixin:
get_db_prep_lookup_value_is_iterable = False get_db_prep_lookup_value_is_iterable = False
def get_db_prep_lookup(self, value, connection): def get_db_prep_lookup(self, value, connection):
# For relational fields, use the output_field of the 'field' attribute. # For relational fields, use the 'target_field' attribute of the
field = getattr(self.lhs.output_field, 'field', None) # output_field.
field = getattr(self.lhs.output_field, 'target_field', None)
get_db_prep_value = getattr(field, 'get_db_prep_value', None) or self.lhs.output_field.get_db_prep_value get_db_prep_value = getattr(field, 'get_db_prep_value', None) or self.lhs.output_field.get_db_prep_value
return ( return (
'%s', '%s',

View File

@ -67,10 +67,15 @@ class Annotation(models.Model):
return self.name return self.name
class DateTimePK(models.Model):
date = models.DateTimeField(primary_key=True, auto_now_add=True)
class ExtraInfo(models.Model): class ExtraInfo(models.Model):
info = models.CharField(max_length=100) info = models.CharField(max_length=100)
note = models.ForeignKey(Note, models.CASCADE, null=True) note = models.ForeignKey(Note, models.CASCADE, null=True)
value = models.IntegerField(null=True) value = models.IntegerField(null=True)
date = models.ForeignKey(DateTimePK, models.SET_NULL, null=True)
class Meta: class Meta:
ordering = ['info'] ordering = ['info']

View File

@ -16,18 +16,19 @@ from .models import (
FK1, Annotation, Article, Author, BaseA, Book, CategoryItem, FK1, Annotation, Article, Author, BaseA, Book, CategoryItem,
CategoryRelationship, Celebrity, Channel, Chapter, Child, ChildObjectA, CategoryRelationship, Celebrity, Channel, Chapter, Child, ChildObjectA,
Classroom, CommonMixedCaseForeignKeys, Company, Cover, CustomPk, Classroom, CommonMixedCaseForeignKeys, Company, Cover, CustomPk,
CustomPkTag, Detail, DumbCategory, Eaten, Employment, ExtraInfo, Fan, Food, CustomPkTag, DateTimePK, Detail, DumbCategory, Eaten, Employment,
Identifier, Individual, Item, Job, JobResponsibilities, Join, LeafA, LeafB, ExtraInfo, Fan, Food, Identifier, Individual, Item, Job,
LoopX, LoopZ, ManagedModel, Member, MixedCaseDbColumnCategoryItem, JobResponsibilities, Join, LeafA, LeafB, LoopX, LoopZ, ManagedModel,
MixedCaseFieldCategoryItem, ModelA, ModelB, ModelC, ModelD, MyObject, Member, MixedCaseDbColumnCategoryItem, MixedCaseFieldCategoryItem, ModelA,
NamedCategory, Node, Note, NullableName, Number, ObjectA, ObjectB, ObjectC, ModelB, ModelC, ModelD, MyObject, NamedCategory, Node, Note, NullableName,
OneToOneCategory, Order, OrderItem, Page, Paragraph, Person, Plaything, Number, ObjectA, ObjectB, ObjectC, OneToOneCategory, Order, OrderItem,
PointerA, Program, ProxyCategory, ProxyObjectA, ProxyObjectB, Ranking, Page, Paragraph, Person, Plaything, PointerA, Program, ProxyCategory,
Related, RelatedIndividual, RelatedObject, Report, ReportComment, ProxyObjectA, ProxyObjectB, Ranking, Related, RelatedIndividual,
ReservedName, Responsibility, School, SharedConnection, SimpleCategory, RelatedObject, Report, ReportComment, ReservedName, Responsibility, School,
SingleObject, SpecialCategory, Staff, StaffUser, Student, Tag, Task, SharedConnection, SimpleCategory, SingleObject, SpecialCategory, Staff,
Teacher, Ticket21203Child, Ticket21203Parent, Ticket23605A, Ticket23605B, StaffUser, Student, Tag, Task, Teacher, Ticket21203Child,
Ticket23605C, TvChef, Valid, X, Ticket21203Parent, Ticket23605A, Ticket23605B, Ticket23605C, TvChef, Valid,
X,
) )
@ -1462,6 +1463,14 @@ class Queries4Tests(TestCase):
CategoryItem.objects.create(category=c1) CategoryItem.objects.create(category=c1)
self.assertSequenceEqual(SimpleCategory.objects.order_by('categoryitem', 'pk'), [c1, c2, c1]) self.assertSequenceEqual(SimpleCategory.objects.order_by('categoryitem', 'pk'), [c1, c2, c1])
def test_filter_reverse_non_integer_pk(self):
date_obj = DateTimePK.objects.create()
extra_obj = ExtraInfo.objects.create(info='extra', date=date_obj)
self.assertEqual(
DateTimePK.objects.filter(extrainfo=extra_obj).get(),
date_obj,
)
def test_ticket10181(self): def test_ticket10181(self):
# Avoid raising an EmptyResultSet if an inner query is probably # Avoid raising an EmptyResultSet if an inner query is probably
# empty (and hence, not executed). # empty (and hence, not executed).