summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/utils.py2
-rw-r--r--django/contrib/contenttypes/fields.py31
-rw-r--r--django/db/models/options.py9
3 files changed, 20 insertions, 22 deletions
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index 91a7eb248c..0c8ac1c6fc 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -168,7 +168,7 @@ class NestedObjects(Collector):
def collect(self, objs, source=None, source_attr=None, **kwargs):
for obj in objs:
- if source_attr:
+ if source_attr and not source_attr.endswith('+'):
related_name = source_attr % {
'class': source._meta.model_name,
'app_label': source._meta.app_label,
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index c68379b6ab..db45b79fb4 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -6,7 +6,7 @@ from django.core import checks
from django.core.exceptions import ObjectDoesNotExist
from django.db import connection
from django.db import models, router, transaction, DEFAULT_DB_ALIAS
-from django.db.models import signals, FieldDoesNotExist
+from django.db.models import signals, FieldDoesNotExist, DO_NOTHING
from django.db.models.base import ModelBase
from django.db.models.fields.related import ForeignObject, ForeignObjectRel
from django.db.models.related import PathInfo
@@ -243,8 +243,10 @@ class GenericRelation(ForeignObject):
def __init__(self, to, **kwargs):
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
kwargs['rel'] = GenericRel(
- self, to, related_name=kwargs.pop('related_name', None),
- limit_choices_to=kwargs.pop('limit_choices_to', None),)
+ self, to,
+ related_query_name=kwargs.pop('related_query_name', None),
+ limit_choices_to=kwargs.pop('limit_choices_to', None),
+ )
# Override content-type/object-id field names on the related class
self.object_id_field_name = kwargs.pop("object_id_field", "object_id")
self.content_type_field_name = kwargs.pop("content_type_field", "content_type")
@@ -300,11 +302,16 @@ class GenericRelation(ForeignObject):
return [(self.rel.to._meta.get_field_by_name(self.object_id_field_name)[0],
self.model._meta.pk)]
- def get_reverse_path_info(self):
+ def get_path_info(self):
opts = self.rel.to._meta
target = opts.get_field_by_name(self.object_id_field_name)[0]
return [PathInfo(self.model._meta, opts, (target,), self.rel, True, False)]
+ def get_reverse_path_info(self):
+ opts = self.model._meta
+ from_opts = self.rel.to._meta
+ return [PathInfo(from_opts, opts, (opts.pk,), self, not self.unique, False)]
+
def get_choices_default(self):
return super(GenericRelation, self).get_choices(include_blank=False)
@@ -312,13 +319,6 @@ class GenericRelation(ForeignObject):
qs = getattr(obj, self.name).all()
return smart_text([instance._get_pk_val() for instance in qs])
- def get_joining_columns(self, reverse_join=False):
- if not reverse_join:
- # This error message is meant for the user, and from user
- # perspective this is a reverse join along the GenericRelation.
- raise ValueError('Joining in reverse direction not allowed.')
- return super(GenericRelation, self).get_joining_columns(reverse_join)
-
def contribute_to_class(self, cls, name):
super(GenericRelation, self).contribute_to_class(cls, name, virtual_only=True)
# Save a reference to which model this class is on for future use
@@ -326,9 +326,6 @@ class GenericRelation(ForeignObject):
# Add the descriptor for the relation
setattr(cls, self.name, ReverseGenericRelatedObjectsDescriptor(self, self.for_concrete_model))
- def contribute_to_related_class(self, cls, related):
- pass
-
def set_attributes_from_rel(self):
pass
@@ -527,5 +524,7 @@ def create_generic_related_manager(superclass):
class GenericRel(ForeignObjectRel):
- def __init__(self, field, to, related_name=None, limit_choices_to=None):
- super(GenericRel, self).__init__(field, to, related_name, limit_choices_to)
+ def __init__(self, field, to, related_name=None, limit_choices_to=None, related_query_name=None):
+ super(GenericRel, self).__init__(field=field, to=to, related_name=related_query_name or '+',
+ limit_choices_to=limit_choices_to, on_delete=DO_NOTHING,
+ related_query_name=related_query_name)
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 4e0307fc4f..4eec2df17c 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -449,9 +449,7 @@ class Options(object):
for f, model in self.get_fields_with_model():
cache[f.name] = cache[f.attname] = (f, model, True, False)
for f in self.virtual_fields:
- if hasattr(f, 'related'):
- cache[f.name] = cache[f.attname] = (
- f.related, None if f.model == self.model else f.model, True, False)
+ cache[f.name] = (f, None if f.model == self.model else f.model, True, False)
if apps.ready:
self._name_map = cache
return cache
@@ -530,8 +528,9 @@ class Options(object):
proxy_cache = cache.copy()
for klass in self.apps.get_models(include_auto_created=True):
if not klass._meta.swapped:
- for f in klass._meta.local_fields:
- if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation:
+ for f in klass._meta.local_fields + klass._meta.virtual_fields:
+ if (hasattr(f, 'rel') and f.rel and not isinstance(f.rel.to, six.string_types)
+ and f.generate_reverse_relation):
if self == f.rel.to._meta:
cache[f.related] = None
proxy_cache[f.related] = None