Commit a301061f authored by Simon Charette's avatar Simon Charette
Browse files

[1.8.x] Fixed #23940 -- Allowed model fields to be named `exact`.

An explicit `__exact` lookup in the related managers filters
was interpreted as a reference to a foreign `exact` field.

Thanks to Trac alias zhiyajun11 for the report, Josh for the investigation,
Loïc for the test name and Tim for the review.

Backport of eb4cdfbd from master
parent 7b92acea
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -681,7 +681,7 @@ def create_foreign_related_manager(superclass, rel_field, rel_model):
        def __init__(self, instance):
            super(RelatedManager, self).__init__()
            self.instance = instance
            self.core_filters = {'%s__exact' % rel_field.name: instance}
            self.core_filters = {rel_field.name: instance}
            self.model = rel_model

        def __call__(self, **kwargs):
+3 −2
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ class Child7(Parent):
@python_2_unicode_compatible
class RelatedModel(models.Model):
    test_gfk = GenericRelation('RelationModel', content_type_field='gfk_ctype', object_id_field='gfk_id')
    exact = models.NullBooleanField()

    def __str__(self):
        return force_text(self.pk)
@@ -140,8 +141,8 @@ class RelationModel(models.Model):

    m2m = models.ManyToManyField(RelatedModel, related_name='test_m2m')

    gfk_ctype = models.ForeignKey(ContentType)
    gfk_id = models.IntegerField()
    gfk_ctype = models.ForeignKey(ContentType, null=True)
    gfk_id = models.IntegerField(null=True)
    gfk = GenericForeignKey(ct_field='gfk_ctype', fk_field='gfk_id')

    def __str__(self):
+8 −0
Original line number Diff line number Diff line
@@ -201,3 +201,11 @@ class ManagersRegressionTests(TestCase):
            t.render(Context({'related': related})),
            ''.join([force_text(relation.pk)] * 3),
        )

    def test_field_can_be_called_exact(self):
        # Make sure related managers core filters don't include an
        # explicit `__exact` lookup that could be interpreted as a
        # reference to a foreign `exact` field. refs #23940.
        related = RelatedModel.objects.create(exact=False)
        relation = related.test_fk.create()
        self.assertEqual(related.test_fk.get(), relation)