diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-17 14:02:41 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2012-12-30 11:19:35 +0200 |
| commit | 68985db48212c701a3d975636123a5d79bdc006f (patch) | |
| tree | 9272ad672f0a9762dee77ba39a0888a5b003b5f3 /django/db/models/sql/query.py | |
| parent | 4511aeb6b8b843ee913fb43a37c9686980210948 (diff) | |
Added Query.join_parent_model()
This simplifies especially compiler.py a lot, where almost the same
code was repeated multiple times.
Refs #19385
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index e5833b2b51..2546d6c889 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -1004,12 +1004,40 @@ class Query(object): for field, model in opts.get_fields_with_model(): if model not in seen: - link_field = opts.get_ancestor_link(model) - seen[model] = self.join( - (root_alias, model._meta.db_table, link_field.column, - model._meta.pk.column), join_field=link_field) + self.join_parent_model(opts, model, root_alias, seen) self.included_inherited_models = seen + def join_parent_model(self, opts, model, alias, seen): + """ + Makes sure the given 'model' is joined in the query. If 'model' isn't + a parent of 'opts' or if it is None this method is a no-op. + + The 'alias' is the root alias for starting the join, 'seen' is a dict + of model -> alias of existing joins. + """ + if model in seen: + return seen[model] + int_opts = opts + chain = opts.get_base_chain(model) + if chain is None: + return alias + for int_model in chain: + if int_model in seen: + return seen[int_model] + # Proxy model have elements in base chain + # with no parents, assign the new options + # object and skip to the next base in that + # case + if not int_opts.parents[int_model]: + int_opts = int_model._meta + continue + link_field = int_opts.get_ancestor_link(int_model) + int_opts = int_model._meta + connection = (alias, int_opts.db_table, link_field.column, int_opts.pk.column) + alias = seen[int_model] = self.join(connection, nullable=False, + join_field=link_field) + return alias + def remove_inherited_models(self): """ Undoes the effects of setup_inherited_models(). Should be called |
