Ticket #10414: 10414_selectRelatedInvalidFields.diff

File 10414_selectRelatedInvalidFields.diff, 3.4 KB (added by trebor74hr, 4 years ago)

select_related("invalid_field") patch

  • django/db/models/sql/compiler.py

     
    55from django.db.models.sql.datastructures import EmptyResultSet
    66from django.db.models.sql.expressions import SQLEvaluator
    77from django.db.models.sql.query import get_proxied_model, get_order_dir, \
    8      select_related_descend, Query
     8     select_related_descend, Query, InvalidQuery
    99
    1010class SQLCompiler(object):
    1111    def __init__(self, query, connection, using):
     
    516516
    517517        # Setup for the case when only particular related fields should be
    518518        # included in the related selection.
     519        fields_found = set()
    519520        if requested is None:
    520521            if isinstance(self.query.select_related, dict):
    521522                requested = self.query.select_related
     
    526527        for f, model in opts.get_fields_with_model():
    527528            if not select_related_descend(f, restricted, requested):
    528529                continue
     530            fields_found.add(f.name)
    529531            # The "avoid" set is aliases we want to avoid just for this
    530532            # particular branch of the recursion. They aren't permanently
    531533            # forbidden from reuse in the related selection tables (which is
     
    591593                    used, next, restricted, new_nullable, dupe_set, avoid)
    592594
    593595        if restricted:
     596            fields_not_found = set(requested.keys()).difference(fields_found)
     597            if fields_not_found:
     598                raise InvalidQuery("Invalid field name(s) %s in select_related() %s" %
     599                                   (",".join(list(fields_not_found)),requested))
    594600            related_fields = [
    595601                (o.field, o.model)
    596602                for o in opts.get_all_related_objects()
  • tests/modeltests/select_related/tests.py

     
    11from django.test import TestCase
     2from django.db.models.sql.query import InvalidQuery
    23
    34from models import Domain, Kingdom, Phylum, Klass, Order, Family, Genus, Species
    45
     
    142143                ['Drosophilidae', 'Hominidae', 'Fabaceae', 'Amanitacae'])
    143144        self.assertNumQueries(1, test)
    144145
     146    def test_certain_fields_fails(self):
     147        """
     148        In this case we pass some invalid field name(s). InvalidQuery
     149        exception is expected.
     150        """
     151        def test(*args):
     152            world = list(Species.objects.select_related(*args))
     153
     154        self.assertNumQueries(1,        test, 'genus', 'genus__family')
     155        self.assertRaises(InvalidQuery, test, 'genusFAIL', 'genus__family')
     156        self.assertRaises(InvalidQuery, test, 'genus', 'genus__familyFAIL')
     157        self.assertRaises(InvalidQuery, test, 'genusFAIL', 'genusFAIL__family')
     158
     159        self.assertNumQueries(1,        test, 'genus__family__order')
     160        self.assertRaises(InvalidQuery, test, 'genusFAIL__family__order')
     161        self.assertRaises(InvalidQuery, test, 'genus__familyFAIL__order')
     162        self.assertRaises(InvalidQuery, test, 'genus__family__orderFAIL')
     163
     164
    145165    def test_more_certain_fields(self):
    146166        """
    147167        In this case, we explicitly say to select the 'genus' and
Back to Top