diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index d5cf38e2ea..3396dc66ad 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -56,12 +56,12 @@ class AdminForm(object): **options ) - def _media(self): + @property + def media(self): media = self.form.media for fs in self: media = media + fs.media return media - media = property(_media) class Fieldset(object): @@ -74,7 +74,8 @@ class Fieldset(object): self.model_admin = model_admin self.readonly_fields = readonly_fields - def _media(self): + @property + def media(self): if 'collapse' in self.classes: extra = '' if settings.DEBUG else '.min' js = [ @@ -84,7 +85,6 @@ class Fieldset(object): ] return forms.Media(js=['admin/js/%s' % url for url in js]) return forms.Media() - media = property(_media) def __iter__(self): for field in self.fields: @@ -303,12 +303,12 @@ class InlineAdminFormSet(object): } }) - def _media(self): + @property + def media(self): media = self.opts.media + self.formset.media for fs in self: media = media + fs.media return media - media = property(_media) class InlineAdminForm(AdminForm): diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index fe65bf3a6e..c75d988c2f 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -412,10 +412,10 @@ class AdminPasswordChangeForm(forms.Form): self.user.save() return self.user - def _get_changed_data(self): + @property + def changed_data(self): data = super(AdminPasswordChangeForm, self).changed_data for name in self.fields.keys(): if name not in data: return [] return ['password'] - changed_data = property(_get_changed_data) diff --git a/django/contrib/auth/models.py b/django/contrib/auth/models.py index d49730b16b..e62307a0a7 100644 --- a/django/contrib/auth/models.py +++ b/django/contrib/auth/models.py @@ -412,13 +412,13 @@ class AnonymousUser(object): def check_password(self, raw_password): raise NotImplementedError("Django doesn't provide a DB representation for AnonymousUser.") - def _get_groups(self): + @property + def groups(self): return self._groups - groups = property(_get_groups) - def _get_user_permissions(self): + @property + def user_permissions(self): return self._user_permissions - user_permissions = property(_get_user_permissions) def get_group_permissions(self, obj=None): return set() diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index 74f1ce7d9c..a2e54486c7 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -38,7 +38,8 @@ class Message(object): def __str__(self): return force_text(self.message) - def _get_tags(self): + @property + def tags(self): extra_tags = force_text(self.extra_tags, strings_only=True) if extra_tags and self.level_tag: return ' '.join([extra_tags, self.level_tag]) @@ -47,7 +48,6 @@ class Message(object): elif self.level_tag: return self.level_tag return '' - tags = property(_get_tags) @property def level_tag(self): diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py index f540812a08..8d779ca2bd 100644 --- a/django/contrib/sitemaps/__init__.py +++ b/django/contrib/sitemaps/__init__.py @@ -68,9 +68,9 @@ class Sitemap(object): def location(self, obj): return obj.get_absolute_url() - def _get_paginator(self): + @property + def paginator(self): return paginator.Paginator(self.items(), self.limit) - paginator = property(_get_paginator) def get_urls(self, page=1, site=None, protocol=None): # Determine protocol diff --git a/django/core/files/images.py b/django/core/files/images.py index 20c338250f..5bd0f638fe 100644 --- a/django/core/files/images.py +++ b/django/core/files/images.py @@ -14,13 +14,13 @@ class ImageFile(File): A mixin for use alongside django.core.files.base.File, which provides additional features for dealing with images. """ - def _get_width(self): + @property + def width(self): return self._get_image_dimensions()[0] - width = property(_get_width) - def _get_height(self): + @property + def height(self): return self._get_image_dimensions()[1] - height = property(_get_height) def _get_image_dimensions(self): if not hasattr(self, '_dimensions_cache'): diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index f04ebca981..4486754d41 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -134,13 +134,13 @@ class WSGIRequest(http.HttpRequest): raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '') return http.parse_cookie(raw_cookie) - def _get_files(self): + @property + def FILES(self): if not hasattr(self, '_files'): self._load_post_and_files() return self._files POST = property(_get_post, _set_post) - FILES = property(_get_files) class WSGIHandler(base.BaseHandler): diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 715b5527f8..0d83ef5d0f 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -60,22 +60,22 @@ class FieldFile(File): file = property(_get_file, _set_file, _del_file) - def _get_path(self): + @property + def path(self): self._require_file() return self.storage.path(self.name) - path = property(_get_path) - def _get_url(self): + @property + def url(self): self._require_file() return self.storage.url(self.name) - url = property(_get_url) - def _get_size(self): + @property + def size(self): self._require_file() if not self._committed: return self.file.size return self.storage.size(self.name) - size = property(_get_size) def open(self, mode='rb'): self._require_file() @@ -120,10 +120,10 @@ class FieldFile(File): self.instance.save() delete.alters_data = True - def _get_closed(self): + @property + def closed(self): file = getattr(self, '_file', None) return file is None or file.closed - closed = property(_get_closed) def close(self): file = getattr(self, '_file', None) diff --git a/django/test/client.py b/django/test/client.py index 2b5840b49e..af55f9efb4 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -438,7 +438,8 @@ class Client(RequestFactory): """ self.exc_info = sys.exc_info() - def _session(self): + @property + def session(self): """ Obtains the current session variables. """ @@ -451,7 +452,6 @@ class Client(RequestFactory): session.save() self.cookies[settings.SESSION_COOKIE_NAME] = session.session_key return session - session = property(_session) def request(self, **request): """ diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index d08d044979..e8468cd26c 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -751,10 +751,10 @@ For example, this model has a few custom methods:: else: return "Post-boomer" - def _get_full_name(self): + @property + def full_name(self): "Returns the person's full name." return '%s %s' % (self.first_name, self.last_name) - full_name = property(_get_full_name) The last method in this example is a :term:`property`. diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt index 1e2345ba20..adbd2c377e 100644 --- a/docs/topics/forms/media.txt +++ b/docs/topics/forms/media.txt @@ -188,10 +188,10 @@ For example, the static definition for our Calendar Widget could also be defined in a dynamic fashion:: class CalendarWidget(forms.TextInput): - def _media(self): + @property + def media(self): return forms.Media(css={'all': ('pretty.css',)}, js=('animations.js', 'actions.js')) - media = property(_media) See the section on `Media objects`_ for more details on how to construct return values for dynamic ``media`` properties.