From 24a1900b3699fe883b027cfacfd7fe9ff117491f Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Wed, 10 Dec 2008 00:14:56 +0000 Subject: [PATCH] [1.0.X] Fixed #8248: made help() work on models and improved introspection support. Descriptors now return themselves when accessed via the class, as per standard Python descriptors like property(). Backported from r9550 and also r9562 and r9563 git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@9634 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/validation.py | 2 ++ django/contrib/contenttypes/generic.py | 4 ++-- django/db/models/fields/related.py | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py index 63be20f504..ccade8a3ef 100644 --- a/django/contrib/admin/validation.py +++ b/django/contrib/admin/validation.py @@ -36,6 +36,8 @@ def validate(cls, model): except models.FieldDoesNotExist: raise ImproperlyConfigured("%s.list_display[%d], %r is not a callable or an attribute of %r or found in the model %r." % (cls.__name__, idx, field, cls.__name__, model._meta.object_name)) + else: + # getattr(model, field) could be an X_RelatedObjectsDescriptor f = fetch_attr(cls, model, opts, "list_display[%d]" % idx, field) if isinstance(f, models.ManyToManyField): raise ImproperlyConfigured("'%s.list_display[%d]', '%s' is a ManyToManyField which is not supported." diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index 0504592ebb..c294f74500 100644 --- a/django/contrib/contenttypes/generic.py +++ b/django/contrib/contenttypes/generic.py @@ -59,7 +59,7 @@ class GenericForeignKey(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, u"%s must be accessed via instance" % self.name + return self try: return getattr(instance, self.cache_attr) @@ -183,7 +183,7 @@ class ReverseGenericRelatedObjectsDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "Manager must be accessed via instance" + return self # This import is done here to avoid circular import importing this module from django.contrib.contenttypes.models import ContentType diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index c87b823a69..146a1ae457 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -175,7 +175,7 @@ class SingleRelatedObjectDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name + return self try: return getattr(instance, self.cache_name) @@ -223,7 +223,7 @@ class ReverseSingleRelatedObjectDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "%s must be accessed via instance" % self.field.name + return self cache_name = self.field.get_cache_name() try: return getattr(instance, cache_name) @@ -287,7 +287,7 @@ class ForeignRelatedObjectsDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "Manager must be accessed via instance" + return self rel_field = self.related.field rel_model = self.related.model @@ -500,7 +500,7 @@ class ManyRelatedObjectsDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "Manager must be accessed via instance" + return self # Dynamically create a class that subclasses the related # model's default manager. @@ -545,7 +545,7 @@ class ReverseManyRelatedObjectsDescriptor(object): def __get__(self, instance, instance_type=None): if instance is None: - raise AttributeError, "Manager must be accessed via instance" + return self # Dynamically create a class that subclasses the related # model's default manager.