diff options
| author | Loic Bistuer <loic.bistuer@sixmedia.com> | 2013-03-08 09:15:23 -0500 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2013-03-08 10:11:45 -0500 |
| commit | 6983a1a540a6e6c3bd941fa15ddd8cb49f9ec74e (patch) | |
| tree | e57559ebfd704705458e6e218dc1f3d868b2922c /django | |
| parent | 477d737e1e6bdf93950c8a381906925c594fac2f (diff) | |
Fixed #15363 -- Renamed and normalized to `get_queryset` the methods that return a QuerySet.
Diffstat (limited to 'django')
| -rw-r--r-- | django/contrib/admin/options.py | 31 | ||||
| -rw-r--r-- | django/contrib/admin/templatetags/admin_list.py | 10 | ||||
| -rw-r--r-- | django/contrib/admin/views/main.py | 39 | ||||
| -rw-r--r-- | django/contrib/auth/admin.py | 2 | ||||
| -rw-r--r-- | django/contrib/comments/managers.py | 4 | ||||
| -rw-r--r-- | django/contrib/comments/templatetags/comments.py | 17 | ||||
| -rw-r--r-- | django/contrib/contenttypes/generic.py | 20 | ||||
| -rw-r--r-- | django/contrib/gis/db/models/manager.py | 62 | ||||
| -rw-r--r-- | django/contrib/sites/managers.py | 4 | ||||
| -rw-r--r-- | django/core/serializers/__init__.py | 2 | ||||
| -rw-r--r-- | django/db/models/fields/related.py | 46 | ||||
| -rw-r--r-- | django/db/models/manager.py | 84 | ||||
| -rw-r--r-- | django/db/models/query.py | 14 | ||||
| -rw-r--r-- | django/forms/models.py | 6 | ||||
| -rw-r--r-- | django/utils/deprecation.py | 62 |
15 files changed, 264 insertions, 139 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 567f7cf990..de7614ff24 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -29,6 +29,7 @@ from django.utils.datastructures import SortedDict from django.utils.html import escape, escapejs from django.utils.safestring import mark_safe from django.utils import six +from django.utils.deprecation import RenameMethodsBase from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext as _ from django.utils.translation import ungettext @@ -64,7 +65,13 @@ FORMFIELD_FOR_DBFIELD_DEFAULTS = { csrf_protect_m = method_decorator(csrf_protect) -class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): +class RenameBaseModelAdminMethods(forms.MediaDefiningClass, RenameMethodsBase): + renamed_methods = ( + ('queryset', 'get_queryset', PendingDeprecationWarning), + ) + + +class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)): """Functionality common to both ModelAdmin and InlineAdmin.""" raw_id_fields = () @@ -239,12 +246,12 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): """ return self.prepopulated_fields - def queryset(self, request): + def get_queryset(self, request): """ Returns a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view. """ - qs = self.model._default_manager.get_query_set() + qs = self.model._default_manager.get_queryset() # TODO: this should be handled by some parameter to the ChangeList. ordering = self.get_ordering(request) if ordering: @@ -496,7 +503,7 @@ class ModelAdmin(BaseModelAdmin): returned if no match is found (or the object_id failed validation against the primary key field). """ - queryset = self.queryset(request) + queryset = self.get_queryset(request) model = queryset.model try: object_id = model._meta.pk.to_python(object_id) @@ -1008,7 +1015,7 @@ class ModelAdmin(BaseModelAdmin): formset = FormSet(data=request.POST, files=request.FILES, instance=new_object, save_as_new="_saveasnew" in request.POST, - prefix=prefix, queryset=inline.queryset(request)) + prefix=prefix, queryset=inline.get_queryset(request)) formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, False) @@ -1034,7 +1041,7 @@ class ModelAdmin(BaseModelAdmin): if prefixes[prefix] != 1 or not prefix: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix, - queryset=inline.queryset(request)) + queryset=inline.get_queryset(request)) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), @@ -1104,7 +1111,7 @@ class ModelAdmin(BaseModelAdmin): prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, - queryset=inline.queryset(request)) + queryset=inline.get_queryset(request)) formsets.append(formset) @@ -1124,7 +1131,7 @@ class ModelAdmin(BaseModelAdmin): if prefixes[prefix] != 1 or not prefix: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix, - queryset=inline.queryset(request)) + queryset=inline.get_queryset(request)) formsets.append(formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), @@ -1209,7 +1216,7 @@ class ModelAdmin(BaseModelAdmin): if (actions and request.method == 'POST' and 'index' in request.POST and '_save' not in request.POST): if selected: - response = self.response_action(request, queryset=cl.get_query_set(request)) + response = self.response_action(request, queryset=cl.get_queryset(request)) if response: return response else: @@ -1225,7 +1232,7 @@ class ModelAdmin(BaseModelAdmin): helpers.ACTION_CHECKBOX_NAME in request.POST and 'index' not in request.POST and '_save' not in request.POST): if selected: - response = self.response_action(request, queryset=cl.get_query_set(request)) + response = self.response_action(request, queryset=cl.get_queryset(request)) if response: return response else: @@ -1521,8 +1528,8 @@ class InlineModelAdmin(BaseModelAdmin): fields = list(form.base_fields) + list(self.get_readonly_fields(request, obj)) return [(None, {'fields': fields})] - def queryset(self, request): - queryset = super(InlineModelAdmin, self).queryset(request) + def get_queryset(self, request): + queryset = super(InlineModelAdmin, self).get_queryset(request) if not self.has_change_permission(request): queryset = queryset.none() return queryset diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index c08193d238..18a45a006f 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -306,8 +306,8 @@ def date_hierarchy(cl): if not (year_lookup or month_lookup or day_lookup): # select appropriate start level - date_range = cl.query_set.aggregate(first=models.Min(field_name), - last=models.Max(field_name)) + date_range = cl.queryset.aggregate(first=models.Min(field_name), + last=models.Max(field_name)) if date_range['first'] and date_range['last']: if date_range['first'].year == date_range['last'].year: year_lookup = date_range['first'].year @@ -325,7 +325,7 @@ def date_hierarchy(cl): 'choices': [{'title': capfirst(formats.date_format(day, 'MONTH_DAY_FORMAT'))}] } elif year_lookup and month_lookup: - days = cl.query_set.filter(**{year_field: year_lookup, month_field: month_lookup}) + days = cl.queryset.filter(**{year_field: year_lookup, month_field: month_lookup}) days = getattr(days, dates_or_datetimes)(field_name, 'day') return { 'show': True, @@ -339,7 +339,7 @@ def date_hierarchy(cl): } for day in days] } elif year_lookup: - months = cl.query_set.filter(**{year_field: year_lookup}) + months = cl.queryset.filter(**{year_field: year_lookup}) months = getattr(months, dates_or_datetimes)(field_name, 'month') return { 'show': True, @@ -353,7 +353,7 @@ def date_hierarchy(cl): } for month in months] } else: - years = getattr(cl.query_set, dates_or_datetimes)(field_name, 'year') + years = getattr(cl.queryset, dates_or_datetimes)(field_name, 'year') return { 'show': True, 'choices': [{ diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 8bda323d83..b7bf85ef9d 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -1,4 +1,5 @@ import operator +import warnings from functools import reduce from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured @@ -6,7 +7,9 @@ from django.core.paginator import InvalidPage from django.core.urlresolvers import reverse from django.db import models from django.db.models.fields import FieldDoesNotExist +from django.utils import six from django.utils.datastructures import SortedDict +from django.utils.deprecation import RenameMethodsBase from django.utils.encoding import force_str, force_text from django.utils.translation import ugettext, ugettext_lazy from django.utils.http import urlencode @@ -33,14 +36,20 @@ IGNORED_PARAMS = ( EMPTY_CHANGELIST_VALUE = ugettext_lazy('(None)') -class ChangeList(object): +class RenameChangeListMethods(RenameMethodsBase): + renamed_methods = ( + ('get_query_set', 'get_queryset', PendingDeprecationWarning), + ) + + +class ChangeList(six.with_metaclass(RenameChangeListMethods)): def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_max_show_all, list_editable, model_admin): self.model = model self.opts = model._meta self.lookup_opts = self.opts - self.root_query_set = model_admin.queryset(request) + self.root_queryset = model_admin.get_queryset(request) self.list_display = list_display self.list_display_links = list_display_links self.list_filter = list_filter @@ -70,7 +79,7 @@ class ChangeList(object): else: self.list_editable = list_editable self.query = request.GET.get(SEARCH_VAR, '') - self.query_set = self.get_query_set(request) + self.queryset = self.get_queryset(request) self.get_results(request) if self.is_popup: title = ugettext('Select %s') @@ -79,6 +88,20 @@ class ChangeList(object): self.title = title % force_text(self.opts.verbose_name) self.pk_attname = self.lookup_opts.pk.attname + @property + def root_query_set(self): + warnings.warn("`ChangeList.root_query_set` is deprecated, " + "use `root_queryset` instead.", + PendingDeprecationWarning, 2) + return self.root_queryset + + @property + def query_set(self): + warnings.warn("`ChangeList.query_set` is deprecated, " + "use `queryset` instead.", + PendingDeprecationWarning, 2) + return self.queryset + def get_filters_params(self, params=None): """ Returns all params except IGNORED_PARAMS @@ -169,7 +192,7 @@ class ChangeList(object): return '?%s' % urlencode(sorted(p.items())) def get_results(self, request): - paginator = self.model_admin.get_paginator(request, self.query_set, self.list_per_page) + paginator = self.model_admin.get_paginator(request, self.queryset, self.list_per_page) # Get the number of objects, with admin filters applied. result_count = paginator.count @@ -178,7 +201,7 @@ class ChangeList(object): # full_result_count is equal to paginator.count if no filters # were applied if self.get_filters_params(): - full_result_count = self.root_query_set.count() + full_result_count = self.root_queryset.count() else: full_result_count = result_count can_show_all = result_count <= self.list_max_show_all @@ -186,7 +209,7 @@ class ChangeList(object): # Get the list of objects to display on this page. if (self.show_all and can_show_all) or not multi_page: - result_list = self.query_set._clone() + result_list = self.queryset._clone() else: try: result_list = paginator.page(self.page_num+1).object_list @@ -304,13 +327,13 @@ class ChangeList(object): ordering_fields[idx] = 'desc' if pfx == '-' else 'asc' return ordering_fields - def get_query_set(self, request): + def get_queryset(self, request): # First, we collect all the declared list filters. (self.filter_specs, self.has_filters, remaining_lookup_params, use_distinct) = self.get_filters(request) # Then, we let every list filter modify the queryset to its liking. - qs = self.root_query_set + qs = self.root_queryset for filter_spec in self.filter_specs: new_qs = filter_spec.queryset(request, qs) if new_qs is not None: diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py index 7b816674d3..0abc361a41 100644 --- a/django/contrib/auth/admin.py +++ b/django/contrib/auth/admin.py @@ -118,7 +118,7 @@ class UserAdmin(admin.ModelAdmin): def user_change_password(self, request, id, form_url=''): if not self.has_change_permission(request): raise PermissionDenied - user = get_object_or_404(self.queryset(request), pk=id) + user = get_object_or_404(self.get_queryset(request), pk=id) if request.method == 'POST': form = self.change_password_form(user, request.POST) if form.is_valid(): diff --git a/django/contrib/comments/managers.py b/django/contrib/comments/managers.py index bc0fc5f332..656200437b 100644 --- a/django/contrib/comments/managers.py +++ b/django/contrib/comments/managers.py @@ -8,7 +8,7 @@ class CommentManager(models.Manager): """ QuerySet for all comments currently in the moderation queue. """ - return self.get_query_set().filter(is_public=False, is_removed=False) + return self.get_queryset().filter(is_public=False, is_removed=False) def for_model(self, model): """ @@ -16,7 +16,7 @@ class CommentManager(models.Manager): a class). """ ct = ContentType.objects.get_for_model(model) - qs = self.get_query_set().filter(content_type=ct) + qs = self.get_queryset().filter(content_type=ct) if isinstance(model, models.Model): qs = qs.filter(object_pk=force_text(model._get_pk_val())) return qs diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py index b5266d9bb3..d8eed76ad6 100644 --- a/django/contrib/comments/templatetags/comments.py +++ b/django/contrib/comments/templatetags/comments.py @@ -3,11 +3,20 @@ from django.template.loader import render_to_string from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.contrib import comments +from django.utils import six +from django.utils.deprecation import RenameMethodsBase from django.utils.encoding import smart_text register = template.Library() -class BaseCommentNode(template.Node): + +class RenameBaseCommentNodeMethods(RenameMethodsBase): + renamed_methods = ( + ('get_query_set', 'get_queryset', PendingDeprecationWarning), + ) + + +class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template.Node)): """ Base helper class (abstract) for handling the get_comment_* template tags. Looks a bit strange, but the subclasses below should make this a bit more @@ -64,11 +73,11 @@ class BaseCommentNode(template.Node): self.comment = comment def render(self, context): - qs = self.get_query_set(context) + qs = self.get_queryset(context) context[self.as_varname] = self.get_context_value_from_queryset(context, qs) return '' - def get_query_set(self, context): + def get_queryset(self, context): ctype, object_pk = self.get_target_ctype_pk(context) if not object_pk: return self.comment_model.objects.none() @@ -205,7 +214,7 @@ class RenderCommentListNode(CommentListNode): "comments/%s/list.html" % ctype.app_label, "comments/list.html" ] - qs = self.get_query_set(context) + qs = self.get_queryset(context) context.push() liststr = render_to_string(template_search_list, { "comment_list" : self.get_context_value_from_queryset(context, qs) diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index 20ff7042bc..fdb05a626a 100644 --- a/django/contrib/contenttypes/generic.py +++ b/django/contrib/contenttypes/generic.py @@ -16,10 +16,18 @@ from django.forms import ModelForm from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets from django.contrib.contenttypes.models import ContentType +from django.utils import six +from django.utils.deprecation import RenameMethodsBase from django.utils.encoding import smart_text -class GenericForeignKey(object): +class RenameGenericForeignKeyMethods(RenameMethodsBase): + renamed_methods = ( + ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning), + ) + + +class GenericForeignKey(six.with_metaclass(RenameGenericForeignKeyMethods)): """ Provides a generic relation to any object through content-type/object-id fields. @@ -60,7 +68,7 @@ class GenericForeignKey(object): # This should never happen. I love comments like this, don't you? raise Exception("Impossible arguments to GFK.get_content_type!") - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): # For efficiency, group the instances by content type and then do one # query per model fk_dict = defaultdict(set) @@ -316,21 +324,21 @@ def create_generic_related_manager(superclass): '%s__exact' % object_id_field_name: instance._get_pk_val(), } - def get_query_set(self): + def get_queryset(self): try: return self.instance._prefetched_objects_cache[self.prefetch_cache_name] except (AttributeError, KeyError): db = self._db or router.db_for_read(self.model, instance=self.instance) - return super(GenericRelatedObjectManager, self).get_query_set().using(db).filter(**self.core_filters) + return super(GenericRelatedObjectManager, self).get_queryset().using(db).filter(**self.core_filters) - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): db = self._db or router.db_for_read(self.model, instance=instances[0]) query = { '%s__pk' % self.content_type_field_name: self.content_type.id, '%s__in' % self.object_id_field_name: set(obj._get_pk_val() for obj in instances) } - qs = super(GenericRelatedObjectManager, self).get_query_set().using(db).filter(**query) + qs = super(GenericRelatedObjectManager, self).get_queryset().using(db).filter(**query) # We (possibly) need to convert object IDs to the type of the # instances' PK in order to match up instances: object_id_converter = instances[0]._meta.pk.to_python diff --git a/django/contrib/gis/db/models/manager.py b/django/contrib/gis/db/models/manager.py index 61fb82132b..aa57e3a507 100644 --- a/django/contrib/gis/db/models/manager.py +++ b/django/contrib/gis/db/models/manager.py @@ -9,95 +9,95 @@ class GeoManager(Manager): # properly. use_for_related_fields = True - def get_query_set(self): + def get_queryset(self): return GeoQuerySet(self.model, using=self._db) def area(self, *args, **kwargs): - return self.get_query_set().area(*args, **kwargs) + return self.get_queryset().area(*args, **kwargs) def centroid(self, *args, **kwargs): - return self.get_query_set().centroid(*args, **kwargs) + return self.get_queryset().centroid(*args, **kwargs) def collect(self, *args, **kwargs): - return self.get_query_set().collect(*args, **kwargs) + return self.get_queryset().collect(*args, **kwargs) def difference(self, *args, **kwargs): - return self.get_query_set().difference(*args, **kwargs) + return self.get_queryset().difference(*args, **kwargs) def distance(self, *args, **kwargs): - return self.get_query_set().distance(*args, **kwargs) + return self.get_queryset().distance(*args, **kwargs) def envelope(self, *args, **kwargs): - return self.get_query_set().envelope(*args, **kwargs) + return self.get_queryset().envelope(*args, **kwargs) def extent(self, *args, **kwargs): - return self.get_query_set().extent(*args, **kwargs) + return self.get_queryset().extent(*args, **kwargs) def extent3d(self, *args, **kwargs): - return self.get_query_set().extent3d(*args, **kwargs) + return self.get_queryset().extent3d(*args, **kwargs) def force_rhr(self, *args, **kwargs): - return self.get_query_set().force_rhr(*args, **kwargs) + return self.get_queryset().force_rhr(*args, **kwargs) def geohash(self, *args, **kwargs): - return self.get_query_set().geohash(*args, **kwargs) + return self.get_queryset().geohash(*args, **kwargs) def geojson(self, *args, **kwargs): - return self.get_query_set().geojson(*args, **kwargs) + return self.get_queryset().geojson(*args, **kwargs) def gml(self, *args, **kwargs): - return self.get_query_set().gml(*args, **kwargs) + return self.get_queryset().gml(*args, **kwargs) def intersection(self, *args, **kwargs): - return self.get_query_set().intersection(*args, **kwargs) + return self.get_queryset().intersection(*args, **kwargs) def kml(self, *args, **kwargs): - return self.get_query_set().kml(*args, **kwargs) + return self.get_queryset().kml(*args, **kwargs) def length(self, *args, **kwargs): - return self.get_query_set().length(*args, **kwargs) + return self.get_queryset().length(*args, **kwargs) def make_line(self, *args, **kwargs): - return self.get_query_set().make_line(*args, **kwargs) + return self.get_queryset().make_line(*args, **kwargs) def mem_size(self, *args, **kwargs): - return self.get_query_set().mem_size(*args, **kwargs) + return self.get_queryset().mem_size(*args, **kwargs) def num_geom(self, *args, **kwargs): - return self.get_query_set().num_geom(*args, **kwargs) + return self.get_queryset().num_geom(*args, **kwargs) def num_points(self, *args, **kwargs): - return self.get_query_set().num_points(*args, **kwargs) + return self.get_queryset().num_points(*args, **kwargs) def perimeter(self, *args, **kwargs): - return self.get_query_set().perimeter(*args, **kwargs) + return self.get_queryset().perimeter(*args, **kwargs) def point_on_surface(self, *args, **kwargs): - return self.get_query_set().point_on_surface(*args, **kwargs) + return self.get_queryset().point_on_surface(*args, **kwargs) def reverse_geom(self, *args, **kwargs): - return self.get_query_set().reverse_geom(*args, **kwargs) + return self.get_queryset().reverse_geom(*args, **kwargs) def scale(self, *args, **kwargs): - return self.get_query_set().scale(*args, **kwargs) + return self.get_queryset().scale(*args, **kwargs) def snap_to_grid(self, *args, **kwargs): - return self.get_query_set().snap_to_grid(*args, **kwargs) + return self.get_queryset().snap_to_grid(*args, **kwargs) def svg(self, *args, **kwargs): - return self.get_query_set().svg(*args, **kwargs) + return self.get_queryset().svg(*args, **kwargs) def sym_difference(self, *args, **kwargs): - return self.get_query_set().sym_difference(*args, **kwargs) + return self.get_queryset().sym_difference(*args, **kwargs) def transform(self, *args, **kwargs): - return self.get_query_set().transform(*args, **kwargs) + return self.get_queryset().transform(*args, **kwargs) def translate(self, *args, **kwargs): - return self.get_query_set().translate(*args, **kwargs) + return self.get_queryset().translate(*args, **kwargs) def union(self, *args, **kwargs): - return self.get_query_set().union(*args, **kwargs) + return self.get_queryset().union(*args, **kwargs) def unionagg(self, *args, **kwargs): - return self.get_query_set().unionagg(*args, **kwargs) + return self.get_queryset().unionagg(*args, **kwargs) diff --git a/django/contrib/sites/managers.py b/django/contrib/sites/managers.py index 3df485a040..becb35b404 100644 --- a/django/contrib/sites/managers.py +++ b/django/contrib/sites/managers.py @@ -35,7 +35,7 @@ class CurrentSiteManager(models.Manager): (self.__class__.__name__, self.__field_name, self.model._meta.object_name)) self.__is_validated = True - def get_query_set(self): + def get_queryset(self): if not self.__is_validated: self._validate_field_name() - return super(CurrentSiteManager, self).get_query_set().filter(**{self.__field_name + '__id__exact': settings.SITE_ID}) + return super(CurrentSiteManager, self).get_queryset().filter(**{self.__field_name + '__id__exact': settings.SITE_ID}) diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py index cf7e66190f..c48050415d 100644 --- a/django/core/serializers/__init__.py +++ b/django/core/serializers/__init__.py @@ -4,7 +4,7 @@ Interfaces for serializing Django objects. Usage:: from django.core import serializers - json = serializers.serialize("json", some_query_set) + json = serializers.serialize("json", some_queryset) objects = list(serializers.deserialize("json", json)) To add your own serializers, use the SERIALIZATION_MODULES setting:: diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 399d16600c..3b47eb86bb 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -11,6 +11,7 @@ from django.db.models.query_utils import QueryWrapper from django.db.models.deletion import CASCADE from django.utils.encoding import smart_text from django.utils import six +from django.utils.deprecation import RenameMethodsBase from django.utils.translation import ugettext_lazy as _, string_concat from django.utils.functional import curry, cached_property from django.core import exceptions @@ -225,7 +226,14 @@ class RelatedField(object): return self.rel.related_name or self.opts.model_name -class SingleRelatedObjectDescriptor(object): +class RenameRelatedObjectDescriptorMethods(RenameMethodsBase): + renamed_methods = ( + ('get_query_set', 'get_queryset', PendingDeprecationWarning), + ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning), + ) + + +class SingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescriptorMethods)): # This class provides the functionality that makes the related-object # managers available as attributes on a model class, for fields that have # a single "remote" value, on the class pointed to by a related field. @@ -238,16 +246,16 @@ class SingleRelatedObjectDescriptor(object): def is_cached(self, instance): return hasattr(instance, self.cache_name) - def get_query_set(self, **db_hints): + def get_queryset(self, **db_hints): db = router.db_for_read(self.related.model, **db_hints) return self.related.model._base_manager.using(db) - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): rel_obj_attr = attrgetter(self.related.field.attname) instance_attr = lambda obj: obj._get_pk_val() instances_dict = dict((instance_attr(inst), inst) for inst in instances) params = {'%s__pk__in' % self.related.field.name: list(instances_dict)} - qs = self.get_query_set(instance=instances[0]).filter(**params) + qs = self.get_queryset(instance=instances[0]).filter(**params) # Since we're going to assign directly in the cache, # we must manage the reverse relation cache manually. rel_obj_cache_name = self.related.field.get_cache_name() @@ -268,7 +276,7 @@ class SingleRelatedObjectDescriptor(object): else: params = {'%s__pk' % self.related.field.name: related_pk} try: - rel_obj = self.get_query_set(instance=instance).get(**params) + rel_obj = self.get_queryset(instance=instance).get(**params) except self.related.model.DoesNotExist: rel_obj = None else: @@ -321,7 +329,7 @@ class SingleRelatedObjectDescriptor(object): setattr(value, self.related.field.get_cache_name(), instance) -class ReverseSingleRelatedObjectDescriptor(object): +class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescriptorMethods)): # This class provides the functionality that makes the related-object # managers available as attributes on a model class, for fields that have # a single "remote" value, on the class that defines the related field. @@ -334,7 +342,7 @@ class ReverseSingleRelatedObjectDescriptor(object): def is_cached(self, instance): return hasattr(instance, self.cache_name) - def get_query_set(self, **db_hints): + def get_queryset(self, **db_hints): db = router.db_for_read(self.field.rel.to, **db_hints) rel_mgr = self.field.rel.to._default_manager # If the related manager indicates that it should be used for @@ -344,7 +352,7 @@ class ReverseSingleRelatedObjectDescriptor(object): else: return QuerySet(self.field.rel.to).using(db) - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): other_field = self.field.rel.get_related_field() rel_obj_attr = attrgetter(other_field.attname) instance_attr = attrgetter(self.field.attname) @@ -353,7 +361,7 @@ class ReverseSingleRelatedObjectDescriptor(object): params = {'%s__pk__in' % self.field.rel.field_name: list(instances_dict)} else: params = {'%s__in' % self.field.rel.field_name: list(instances_dict)} - qs = self.get_query_set(instance=instances[0]).filter(**params) + qs = self.get_queryset(instance=instances[0]).filter(**params) # Since we're going to assign directly in the cache, # we must manage the reverse relation cache manually. if not self.field.rel.multiple: @@ -378,7 +386,7 @@ class ReverseSingleRelatedObjectDescriptor(object): params = {'%s__%s' % (self.field.rel.field_name, other_field.rel.field_name): val} else: params = {'%s__exact' % self.field.rel.field_name: val} - qs = self.get_query_set(instance=instance) + qs = self.get_queryset(instance=instance) # Assuming the database enforces foreign keys, this won't fail. rel_obj = qs.get(**params) if not self.field.rel.multiple: @@ -490,26 +498,26 @@ class ForeignRelatedObjectsDescriptor(object): } self.model = rel_model - def get_query_set(self): + def get_queryset(self): try: return self.instance._prefetched_objects_cache[rel_field.related_query_name()] except (AttributeError, KeyError): db = self._db or router.db_for_read(self.model, instance=self.instance) - qs = super(RelatedManager, self).get_query_set().using(db).filter(**self.core_filters) + qs = super(RelatedManager, self).get_queryset().using(db).filter(**self.core_filters) val = getattr(self.instance, attname) if val is None or val == '' and connections[db].features.interprets_empty_strings_as_nulls: return qs.none() qs._known_related_objects = {rel_field: {self.instance.pk: self.instance}} return qs - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): rel_obj_attr = attrgetter(rel_field.attname) instance_attr = attrgetter(attname) instances_dict = dict((instance_attr(inst), inst) for inst in instances) db = self._db or router.db_for_read(self.model, instance=instances[0]) query = {'%s__%s__in' % (rel_field.name, attname): list(instances_dict)} - qs = super(RelatedManager, self).get_query_set().using(db).filter(**query) - # Since we just bypassed this class' get_query_set(), we must manage + qs = super(RelatedManager, self).get_queryset().using(db).filter(**query) + # Since we just bypassed this class' get_queryset(), we must manage # the reverse relation manually. for rel_obj in qs: instance = instances_dict[rel_obj_attr(rel_obj)] @@ -603,20 +611,20 @@ def create_many_related_manager(superclass, rel): else: return obj.pk - def get_query_set(self): + def get_queryset(self): try: return self.instance._prefetched_objects_cache[self.prefetch_cache_name] except (AttributeError, KeyError): db = self._db or router.db_for_read(self.instance.__class__, instance=self.instance) - return super(ManyRelatedManager, self).get_query_set().using(db)._next_is_sticky().filter(**self.core_filters) + return super(ManyRelatedManager, self).get_queryset().using(db)._next_is_sticky().filter(**self.core_filters) - def get_prefetch_query_set(self, instances): + def get_prefetch_queryset(self, instances): instance = instances[0] from django.db import connections db = self._db or router.db_for_read(instance.__class__, instance=instance) query = {'%s__pk__in' % self.query_field_name: set(obj._get_pk_val() for obj in instances)} - qs = super(ManyRelatedManager, self).get_query_set().using(db)._next_is_sticky().filter(**query) + qs = super(ManyRelatedManager, self).get_queryset().using(db)._next_is_sticky().filter(**query) # M2M: need to annotate the query in order to get the primary model # that the secondary model was actually related to. We know that diff --git a/django/db/models/manager.py b/django/db/models/manager.py index b1f2e10735..43a8264f11 100644 --- a/django/db/models/manager.py +++ b/django/db/models/manager.py @@ -3,7 +3,8 @@ from django.db import router from django.db.models.query import QuerySet, insert_query, RawQuerySet from django.db.models import signals from django.db.models.fields import FieldDoesNotExist - +from django.utils import six +from django.utils.deprecation import RenameMethodsBase def ensure_default_manager(sender, **kwargs): """ @@ -47,7 +48,14 @@ def ensure_default_manager(sender, **kwargs): signals.class_prepared.connect(ensure_default_manager) -class Manager(object): +class RenameManagerMethods(RenameMethodsBase): + renamed_methods = ( + ('get_query_set', 'get_queryset', PendingDeprecationWarning), + ('get_prefetch_query_set', 'get_prefetch_queryset', PendingDeprecationWarning), + ) + + +class Manager(six.with_metaclass(RenameManagerMethods)): # Tracks each time a Manager instance is created. Used to retain order. creation_counter = 0 @@ -112,113 +120,113 @@ class Manager(object): # PROXIES TO QUERYSET # ####################### - def get_query_set(self): + def get_queryset(self): """Returns a new QuerySet object. Subclasses can override this method to easily customize the behavior of the Manager. """ return QuerySet(self.model, using=self._db) def none(self): - return self.get_query_set().none() + return self.get_queryset().none() def all(self): - return self.get_query_set() + return self.get_queryset() def count(self): - return self.get_query_set().count() + return self.get_queryset().count() def dates(self, *args, **kwargs): - return self.get_query_set().dates(*args, **kwargs) + return self.get_queryset().dates(*args, **kwargs) def datetimes(self, *args, **kwargs): - return self.get_query_set().datetimes(*args, **kwargs) + return self.get_queryset().datetimes(*args, **kwargs) def distinct(self, *args, **kwargs): - return self.get_query_set().distinct(*args, **kwargs) + return self.get_queryset().distinct(*args, **kwargs) def extra(self, *args, **kwargs): - return self.get_query_set().extra(*args, **kwargs) + return self.get_queryset().extra(*args, **kwargs) def get(self, *args, **kwargs): - return self.get_query_set().get(*args, **kwargs) + return self.get_queryset().get(*args, **kwargs) def get_or_create(self, **kwargs): - return self.get_query_set().get_or_create(**kwargs) + return self.get_queryset().get_or_create(**kwargs) def create(self, **kwargs): - return self.get_query_set().create(**kwargs) + return self.get_queryset().create(**kwargs) def bulk_create(self, *args, **kwargs): - return self.get_query_set().bulk_create(*args, **kwargs) + return self.get_queryset().bulk_create(*args, **kwargs) def filter(self, *args, **kwargs): - return self.get_query_set().filter(*args, **kwargs) + return self.get_queryset().filter(*args, **kwargs) def aggregate(self, *args, **kwargs): - return self.get_query_set().aggregate(*args, **kwargs) + return self.get_queryset().aggregate(*args, **kwargs) def annotate(self, *args, **kwargs): - return self.get_query_set().annotate(*args, **kwargs) + return self.get_queryset().annotate(*args, **kwargs) def complex_filter(self, *args, **kwargs): - return self.get_query_set().complex_filter(*args, **kwargs) + return self.get_queryset().complex_filter(*args, **kwargs) def exclude(self, *args, **kwargs): - return self.get_query_set().exclude(*args, **kwargs) + return self.get_queryset().exclude(*args, **kwargs) def in_bulk(self, *args, **kwargs): - return self.get_query_set().in_bulk(*args, **kwargs) + return self.get_queryset().in_bulk(*args, **kwargs) def iterator(self, *args, **kwargs): - return self.get_query_set().iterator(*args, **kwargs) + return self.get_queryset().iterator(*args, **kwargs) def earliest(self, *args, **kwargs): - return self.get_query_set().earliest(*args, **kwargs) + return self.get_queryset().earliest(*args, **kwargs) def latest(self, *args, **kwargs): - return self.get_query_set().latest(*args, **kwargs) + return self.get_queryset().latest(*args, **kwargs) def order_by(self, *args, **kwargs): - return self.get_query_set().order_by(*args, **kwargs) + return self.get_queryset().order_by(*args, **kwargs) def select_for_update(self, *args, **kwargs): - return self.get_query_set().select_for_update(*args, **kwargs) + return self.get_queryset().select_for_update(*args, **kwargs) def select_related(self, *args, **kwargs): - return self.get_query_set().select_related(*args, **kwargs) + return self.get_queryset().select_related(*args, **kwargs) def prefetch_related(self, *args, **kwargs): - return self.get_query_set().prefetch_related(*args, **kwargs) + return self.get_queryset().prefetch_related(*args, **kwargs) def values(self, *args, **kwargs): - return self.get_query_set().values(*args, **kwargs) + return self.get_queryset().values(*args, **kwargs) def values_list(self, *args, **kwargs): - return self.get_query_set().values_list(*args, **kwargs) + return self.get_queryset().values_list(*args, **kwargs) def update(self, *args, **kwargs): - return self.get_query_set().update(*args, **kwargs) + return self.get_queryset().update(*args, **kwargs) def reverse(self, *args, **kwargs): - return self.get_query_set().reverse(*args, **kwargs) + return self.get_queryset().reverse(*args, **kwargs) def defer(self, *args, **kwargs): - return self.get_query_set().defer(*args, **kwargs) + return self.get_queryset().defer(*args, **kwargs) def only(self, *args, **kwargs): - return self.get_query_set().only(*args, **kwargs) + return self.get_queryset().only(*args, **kwargs) def using(self, *args, **kwargs): - return self.get_query_set().using(*args, **kwargs) + return self.get_queryset().using(*args, **kwargs) def exists(self, *args, **kwargs): - return self.get_query_set().exists(*args, **kwargs) + return self.get_queryset().exists(*args, **kwargs) def _insert(self, objs, fields, **kwargs): return insert_query(self.model, objs, fields, **kwargs) def _update(self, values, **kwargs): - return self.get_query_set()._update(values, **kwargs) + return self.get_queryset()._update(values, **kwargs) def raw(self, raw_query, params=None, *args, **kwargs): return RawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs) @@ -265,5 +273,5 @@ class EmptyManager(Manager): super(EmptyManager, self).__init__() self.model = model - def get_query_set(self): - return super(EmptyManager, self).get_query_set().none() + def get_queryset(self): + return super(EmptyManager, self).get_queryset().none() diff --git a/django/db/models/query.py b/django/db/models/query.py index ec35f8aba3..30be30ca43 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -1733,9 +1733,9 @@ def prefetch_related_objects(result_cache, related_lookups): def get_prefetcher(instance, attr): """ For the attribute 'attr' on the given instance, finds - an object that has a get_prefetch_query_set(). + an object that has a get_prefetch_queryset(). Returns a 4 tuple containing: - (the object with get_prefetch_query_set (or None), + (the object with get_prefetch_queryset (or None), the descriptor object representing this relationship (or None), a boolean that is False if the attribute was not found at all, a boolean that is True if the attribute has already been fetched) @@ -1758,8 +1758,8 @@ def get_prefetcher(instance, attr): attr_found = True if rel_obj_descriptor: # singly related object, descriptor object has the - # get_prefetch_query_set() method. - if hasattr(rel_obj_descriptor, 'get_prefetch_query_set'): + # get_prefetch_queryset() method. + if hasattr(rel_obj_descriptor, 'get_prefetch_queryset'): prefetcher = rel_obj_descriptor if rel_obj_descriptor.is_cached(instance): is_fetched = True @@ -1768,7 +1768,7 @@ def get_prefetcher(instance, attr): # the attribute on the instance rather than the class to # support many related managers rel_obj = getattr(instance, attr) - if hasattr(rel_obj, 'get_prefetch_query_set'): + if hasattr(rel_obj, 'get_prefetch_queryset'): prefetcher = rel_obj return prefetcher, rel_obj_descriptor, attr_found, is_fetched @@ -1784,7 +1784,7 @@ def prefetch_one_level(instances, prefetcher, attname): prefetches that must be done due to prefetch_related lookups found from default managers. """ - # prefetcher must have a method get_prefetch_query_set() which takes a list + # prefetcher must have a method get_prefetch_queryset() which takes a list # of instances, and returns a tuple: # (queryset of instances of self.model that are related to passed in instances, @@ -1797,7 +1797,7 @@ def prefetch_one_level(instances, prefetcher, attname): # in a dictionary. rel_qs, rel_obj_attr, instance_attr, single, cache_name =\ - prefetcher.get_prefetch_query_set(instances) + prefetcher.get_prefetch_queryset(instances) # We have to handle the possibility that the default manager itself added # prefetch_related lookups to the QuerySet we just got back. We don't want to # trigger the prefetch_related functionality by evaluating the query. diff --git a/django/forms/models.py b/django/forms/models.py index 7609bb7227..272f1ddee6 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -478,7 +478,7 @@ class BaseModelFormSet(BaseFormSet): if self.queryset is not None: qs = self.queryset else: - qs = self.model._default_manager.get_query_set() + qs = self.model._default_manager.get_queryset() # If the queryset isn't already ordered we need to add an # artificial ordering here to make sure that all formsets @@ -668,9 +668,9 @@ class BaseModelFormSet(BaseFormSet): except IndexError: pk_value = None if isinstance(pk, OneToOneField) or isinstance(pk, ForeignKey): - qs = pk.rel.to._default_manager.get_query_set() + qs = pk.rel.to._default_manager.get_queryset() else: - qs = self.model._default_manager.get_query_set() + qs = self.model._default_manager.get_queryset() qs = qs.using(form.instance._state.db) if form._meta.widgets: widget = form._meta.widgets.get(self._pk_field.name, HiddenInput) diff --git a/django/utils/deprecation.py b/django/utils/deprecation.py new file mode 100644 index 0000000000..edbb5ca5ea --- /dev/null +++ b/django/utils/deprecation.py @@ -0,0 +1,62 @@ +import inspect +import warnings + + +class warn_about_renamed_method(object): + def __init__(self, class_name, old_method_name, new_method_name, deprecation_warning): + self.class_name = class_name + self.old_method_name = old_method_name + self.new_method_name = new_method_name + self.deprecation_warning = deprecation_warning + + def __call__(self, f): + def wrapped(*args, **kwargs): + warnings.warn( + "`%s.%s` is deprecated, use `%s` instead." % + (self.class_name, self.old_method_name, self.new_method_name), + self.deprecation_warning, 2) + return f(*args, **kwargs) + return wrapped + + +class RenameMethodsBase(type): + """ + Handles the deprecation paths when renaming a method. + + It does the following: + 1) Define the new method if missing and complain about it. + 2) Define the old method if missing. + 3) Complain whenever an old method is called. + + See #15363 for more details. + """ + + renamed_methods = () + + def __new__(cls, name, bases, attrs): + new_class = super(RenameMethodsBase, cls).__new__(cls, name, bases, attrs) + + for base in inspect.getmro(new_class): + class_name = base.__name__ + for renamed_method in cls.renamed_methods: + old_method_name = renamed_method[0] + old_method = base.__dict__.get(old_method_name) + new_method_name = renamed_method[1] + new_method = base.__dict__.get(new_method_name) + deprecation_warning = renamed_method[2] + wrapper = warn_about_renamed_method(class_name, *renamed_method) + + # Define the new method if missing and complain about it + if not new_method and old_method: + warnings.warn( + "`%s.%s` method should be renamed `%s`." % + (class_name, old_method_name, new_method_name), + deprecation_warning, 2) + setattr(base, new_method_name, old_method) + setattr(base, old_method_name, wrapper(old_method)) + + # Define the old method as a wrapped call to the new method. + if not old_method and new_method: + setattr(base, old_method_name, wrapper(new_method)) + + return new_class |
