Removed several deprecated features for 1.0 (refs #7830):

* "simple" cache backend
 * `ObjectPaginator`
 * `edit_inline_type` argument for `ForeignKey` fields
 * `QOperator`, `QNot`, `QAnd` and `QOr`
 * `maxlength` argument 


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8191 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Gary Wilson Jr 2008-08-02 04:56:11 +00:00
parent cbbd54d5cd
commit 351a3ca154
17 changed files with 10 additions and 464 deletions

View File

@ -30,22 +30,12 @@ BACKENDS = {
'dummy': 'dummy', 'dummy': 'dummy',
} }
DEPRECATED_BACKENDS = {
# deprecated backend --> replacement module
'simple': 'locmem',
}
def get_cache(backend_uri): def get_cache(backend_uri):
if backend_uri.find(':') == -1: if backend_uri.find(':') == -1:
raise InvalidCacheBackendError, "Backend URI must start with scheme://" raise InvalidCacheBackendError, "Backend URI must start with scheme://"
scheme, rest = backend_uri.split(':', 1) scheme, rest = backend_uri.split(':', 1)
if not rest.startswith('//'): if not rest.startswith('//'):
raise InvalidCacheBackendError, "Backend URI must start with scheme://" raise InvalidCacheBackendError, "Backend URI must start with scheme://"
if scheme in DEPRECATED_BACKENDS:
import warnings
warnings.warn("'%s' backend is deprecated. Use '%s' instead." %
(scheme, DEPRECATED_BACKENDS[scheme]), DeprecationWarning)
scheme = DEPRECATED_BACKENDS[scheme]
host = rest[2:] host = rest[2:]
qpos = rest.find('?') qpos = rest.find('?')

View File

@ -118,65 +118,3 @@ class Page(object):
if self.number == self.paginator.num_pages: if self.number == self.paginator.num_pages:
return self.paginator.count return self.paginator.count
return self.number * self.paginator.per_page return self.number * self.paginator.per_page
class ObjectPaginator(Paginator):
"""
Legacy ObjectPaginator class, for backwards compatibility.
Note that each method on this class that takes page_number expects a
zero-based page number, whereas the new API (Paginator/Page) uses one-based
page numbers.
"""
def __init__(self, query_set, num_per_page, orphans=0):
Paginator.__init__(self, query_set, num_per_page, orphans)
import warnings
warnings.warn("The ObjectPaginator is deprecated. Use django.core.paginator.Paginator instead.", DeprecationWarning)
# Keep these attributes around for backwards compatibility.
self.query_set = query_set
self.num_per_page = num_per_page
self._hits = self._pages = None
def validate_page_number(self, page_number):
try:
page_number = int(page_number) + 1
except ValueError:
raise PageNotAnInteger
return self.validate_number(page_number)
def get_page(self, page_number):
try:
page_number = int(page_number) + 1
except ValueError:
raise PageNotAnInteger
return self.page(page_number).object_list
def has_next_page(self, page_number):
return page_number < self.pages - 1
def has_previous_page(self, page_number):
return page_number > 0
def first_on_page(self, page_number):
"""
Returns the 1-based index of the first object on the given page,
relative to total objects found (hits).
"""
page_number = self.validate_page_number(page_number)
return (self.num_per_page * (page_number - 1)) + 1
def last_on_page(self, page_number):
"""
Returns the 1-based index of the last object on the given page,
relative to total objects found (hits).
"""
page_number = self.validate_page_number(page_number)
if page_number == self.num_pages:
return self.count
return page_number * self.num_per_page
# The old API called it "hits" instead of "count".
hits = Paginator.count
# The old API called it "pages" instead of "num_pages".
pages = Paginator.num_pages

View File

@ -22,7 +22,6 @@ from django.utils.itercompat import tee
from django.utils.text import capfirst from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy, ugettext as _ from django.utils.translation import ugettext_lazy, ugettext as _
from django.utils.encoding import smart_unicode, force_unicode, smart_str from django.utils.encoding import smart_unicode, force_unicode, smart_str
from django.utils.maxlength import LegacyMaxlength
from django.utils import datetime_safe from django.utils import datetime_safe
class NOT_PROVIDED: class NOT_PROVIDED:
@ -62,10 +61,6 @@ def manipulator_validator_unique(f, opts, self, field_data, all_data):
# getattr(obj, opts.pk.attname) # getattr(obj, opts.pk.attname)
class Field(object): class Field(object):
# Provide backwards compatibility for the maxlength attribute and
# argument for this class and all subclasses.
__metaclass__ = LegacyMaxlength
# Designates whether empty strings fundamentally are allowed at the # Designates whether empty strings fundamentally are allowed at the
# database level. # database level.
empty_strings_allowed = True empty_strings_allowed = True

View File

@ -626,11 +626,6 @@ class ForeignKey(RelatedField, Field):
to_field = to_field or to._meta.pk.name to_field = to_field or to._meta.pk.name
kwargs['verbose_name'] = kwargs.get('verbose_name', None) kwargs['verbose_name'] = kwargs.get('verbose_name', None)
if 'edit_inline_type' in kwargs:
import warnings
warnings.warn("edit_inline_type is deprecated. Use edit_inline instead.", DeprecationWarning)
kwargs['edit_inline'] = kwargs.pop('edit_inline_type')
kwargs['rel'] = rel_class(to, to_field, kwargs['rel'] = rel_class(to, to_field,
num_in_admin=kwargs.pop('num_in_admin', 3), num_in_admin=kwargs.pop('num_in_admin', 3),
min_num_in_admin=kwargs.pop('min_num_in_admin', None), min_num_in_admin=kwargs.pop('min_num_in_admin', None),

View File

@ -5,9 +5,7 @@ Add SubfieldBase as the __metaclass__ for your Field subclass, implement
to_python() and the other necessary methods and everything will work seamlessly. to_python() and the other necessary methods and everything will work seamlessly.
""" """
from django.utils.maxlength import LegacyMaxlength class SubfieldBase(type):
class SubfieldBase(LegacyMaxlength):
""" """
A metaclass for custom Field subclasses. This ensures the model's attribute A metaclass for custom Field subclasses. This ensures the model's attribute
has the descriptor protocol attached to it. has the descriptor protocol attached to it.
@ -50,4 +48,3 @@ def make_contrib(func=None):
setattr(cls, self.name, Creator(self)) setattr(cls, self.name, Creator(self))
return contribute_to_class return contribute_to_class

View File

@ -757,22 +757,6 @@ class EmptyQuerySet(QuerySet):
yield iter([]).next() yield iter([]).next()
# QOperator, QNot, QAnd and QOr are temporarily retained for backwards
# compatibility. All the old functionality is now part of the 'Q' class.
class QOperator(Q):
def __init__(self, *args, **kwargs):
warnings.warn('Use Q instead of QOr, QAnd or QOperation.',
DeprecationWarning, stacklevel=2)
super(QOperator, self).__init__(*args, **kwargs)
QOr = QAnd = QOperator
def QNot(q):
warnings.warn('Use ~q instead of QNot(q)', DeprecationWarning, stacklevel=2)
return ~q
def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0, def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
requested=None): requested=None):
""" """

View File

@ -5,7 +5,6 @@ from django.utils.safestring import mark_safe
from django.conf import settings from django.conf import settings
from django.utils.translation import ugettext, ungettext from django.utils.translation import ugettext, ungettext
from django.utils.encoding import smart_unicode, force_unicode from django.utils.encoding import smart_unicode, force_unicode
from django.utils.maxlength import LegacyMaxlength
FORM_FIELD_ID_PREFIX = 'id_' FORM_FIELD_ID_PREFIX = 'id_'
@ -304,9 +303,6 @@ class FormField(object):
Subclasses should also implement a render(data) method, which is responsible Subclasses should also implement a render(data) method, which is responsible
for rending the form field in XHTML. for rending the form field in XHTML.
""" """
# Provide backwards compatibility for the maxlength attribute and
# argument for this class and all subclasses.
__metaclass__ = LegacyMaxlength
def __str__(self): def __str__(self):
return unicode(self).encode('utf-8') return unicode(self).encode('utf-8')

View File

@ -1,65 +0,0 @@
"""
Utilities for providing backwards compatibility for the maxlength argument,
which has been replaced by max_length. See ticket #2101.
"""
from warnings import warn
def get_maxlength(self):
return self.max_length
def set_maxlength(self, value):
self.max_length = value
def legacy_maxlength(max_length, maxlength):
"""
Consolidates max_length and maxlength, providing backwards compatibilty
for the legacy "maxlength" argument.
If one of max_length or maxlength is given, then that value is returned.
If both are given, a TypeError is raised. If maxlength is used at all, a
deprecation warning is issued.
"""
if maxlength is not None:
warn("maxlength is deprecated. Use max_length instead.", DeprecationWarning, stacklevel=3)
if max_length is not None:
raise TypeError("Field cannot take both the max_length argument and the legacy maxlength argument.")
max_length = maxlength
return max_length
def remove_maxlength(func):
"""
A decorator to be used on a class's __init__ that provides backwards
compatibilty for the legacy "maxlength" keyword argument, i.e.
name = models.CharField(maxlength=20)
It does this by changing the passed "maxlength" keyword argument
(if it exists) into a "max_length" keyword argument.
"""
def inner(self, *args, **kwargs):
max_length = kwargs.get('max_length', None)
# pop maxlength because we don't want this going to __init__.
maxlength = kwargs.pop('maxlength', None)
max_length = legacy_maxlength(max_length, maxlength)
# Only set the max_length keyword argument if we got a value back.
if max_length is not None:
kwargs['max_length'] = max_length
func(self, *args, **kwargs)
return inner
# This metaclass is used in two places, and should be removed when legacy
# support for maxlength is dropped.
# * oldforms.FormField
# * db.models.fields.Field
class LegacyMaxlength(type):
"""
Metaclass for providing backwards compatibility support for the
"maxlength" keyword argument.
"""
def __init__(cls, name, bases, attrs):
super(LegacyMaxlength, cls).__init__(name, bases, attrs)
# Decorate the class's __init__ to remove any maxlength keyword.
cls.__init__ = remove_maxlength(cls.__init__)
# Support accessing and setting to the legacy maxlength attribute.
cls.maxlength = property(get_maxlength, set_maxlength)

View File

@ -159,19 +159,6 @@ cache is multi-process and thread-safe. To use it, set ``CACHE_BACKEND`` to
CACHE_BACKEND = 'locmem:///' CACHE_BACKEND = 'locmem:///'
Simple caching (for development)
--------------------------------
A simple, single-process memory cache is available as ``"simple:///"``. This
merely saves cached data in-process, which means it should only be used in
development or testing environments. For example::
CACHE_BACKEND = 'simple:///'
**New in Django development version:** This cache backend is deprecated and
will be removed in a future release. New code should use the ``locmem`` backend
instead.
Dummy caching (for development) Dummy caching (for development)
------------------------------- -------------------------------

View File

@ -144,10 +144,6 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
(in characters) of the field. The max_length is enforced at the database level (in characters) of the field. The max_length is enforced at the database level
and in Django's validation. and in Django's validation.
Django veterans: Note that the argument is now called ``max_length`` to
provide consistency throughout Django. There is full legacy support for
the old ``maxlength`` argument, but ``max_length`` is preferred.
``CommaSeparatedIntegerField`` ``CommaSeparatedIntegerField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -137,12 +137,3 @@ Attributes
``number`` -- The 1-based page number for this page. ``number`` -- The 1-based page number for this page.
``paginator`` -- The associated ``Paginator`` object. ``paginator`` -- The associated ``Paginator`` object.
The legacy ``ObjectPaginator`` class
====================================
The ``Paginator`` and ``Page`` classes are new in the Django development
version, as of revision 7306. In previous versions, Django provided an
``ObjectPaginator`` class that offered similar functionality but wasn't as
convenient. This class still exists, for backwards compatibility, but Django
now issues a ``DeprecationWarning`` if you try to use it.

View File

@ -65,10 +65,10 @@ you've configured your cache; see the `cache documentation`_ for details.
.. note:: .. note::
You should probably only use cache-based sessions if you're using the You should probably only use cache-based sessions if you're using the
memcached cache backend. The local memory and simple cache backends Memcached cache backend. The local-memory cache backend doesn't retain data
don't retain data long enough to be good choices, and it'll be faster long enough to be a good choice, and it'll be faster to use file or
to use file or database sessions directly instead of sending everything database sessions directly instead of sending everything through the file
through the file or database cache backends. or database cache backends.
Using sessions in views Using sessions in views
======================= =======================

View File

@ -4,11 +4,6 @@
Django provides a framework for paginating a list of objects in a few lines Django provides a framework for paginating a list of objects in a few lines
of code. This is often useful for dividing search results or long lists of of code. This is often useful for dividing search results or long lists of
objects into easily readable pages. objects into easily readable pages.
In Django 0.96 and earlier, a single ObjectPaginator class implemented this
functionality. In the Django development version, the behavior is split across
two classes -- Paginator and Page -- that are more easier to use. The legacy
ObjectPaginator class is deprecated.
""" """
from django.db import models from django.db import models
@ -27,9 +22,9 @@ __test__ = {'API_TESTS':"""
... a = Article(headline='Article %s' % x, pub_date=datetime(2005, 7, 29)) ... a = Article(headline='Article %s' % x, pub_date=datetime(2005, 7, 29))
... a.save() ... a.save()
#################################### ##################
# New/current API (Paginator/Page) # # Paginator/Page #
#################################### ##################
>>> from django.core.paginator import Paginator >>> from django.core.paginator import Paginator
>>> paginator = Paginator(Article.objects.all(), 5) >>> paginator = Paginator(Article.objects.all(), 5)
@ -165,89 +160,6 @@ True
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
################################
# Legacy API (ObjectPaginator) #
################################
# Don't print out the deprecation warnings during testing.
>>> from warnings import filterwarnings
>>> filterwarnings("ignore")
>>> from django.core.paginator import ObjectPaginator, EmptyPage
>>> paginator = ObjectPaginator(Article.objects.all(), 5)
>>> paginator.hits
9
>>> paginator.pages
2
>>> paginator.page_range
[1, 2]
# Get the first page.
>>> paginator.get_page(0)
[<Article: Article 1>, <Article: Article 2>, <Article: Article 3>, <Article: Article 4>, <Article: Article 5>]
>>> paginator.has_next_page(0)
True
>>> paginator.has_previous_page(0)
False
>>> paginator.first_on_page(0)
1
>>> paginator.last_on_page(0)
5
# Get the second page.
>>> paginator.get_page(1)
[<Article: Article 6>, <Article: Article 7>, <Article: Article 8>, <Article: Article 9>]
>>> paginator.has_next_page(1)
False
>>> paginator.has_previous_page(1)
True
>>> paginator.first_on_page(1)
6
>>> paginator.last_on_page(1)
9
# Invalid pages raise EmptyPage.
>>> paginator.get_page(-1)
Traceback (most recent call last):
...
EmptyPage: ...
>>> paginator.get_page(2)
Traceback (most recent call last):
...
EmptyPage: ...
# Empty paginators with allow_empty_first_page=True.
>>> paginator = ObjectPaginator(Article.objects.filter(id=0), 5)
>>> paginator.count
0
>>> paginator.num_pages
1
>>> paginator.page_range
[1]
# ObjectPaginator can be passed lists too.
>>> paginator = ObjectPaginator([1, 2, 3], 5)
>>> paginator.hits
3
>>> paginator.pages
1
>>> paginator.page_range
[1]
# ObjectPaginator can be passed other objects without a count() method.
>>> class Container:
... def __len__(self):
... return 42
>>> paginator = ObjectPaginator(Container(), 10)
>>> paginator.hits
42
>>> paginator.pages
5
>>> paginator.page_range
[1, 2, 3, 4, 5]
################## ##################
# Orphan support # # Orphan support #
################## ##################
@ -262,17 +174,7 @@ EmptyPage: ...
1 1
# With orphans only set to 1, we should get two pages. # With orphans only set to 1, we should get two pages.
>>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=1) >>> paginator = Paginator(Article.objects.all(), 10, orphans=1)
>>> paginator.num_pages >>> paginator.num_pages
2 2
# LEGACY: With orphans set to 3 and 10 items per page, we should get all 12 items on a single page.
>>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=3)
>>> paginator.pages
1
# LEGACY: With orphans only set to 1, we should get two pages.
>>> paginator = ObjectPaginator(Article.objects.all(), 10, orphans=1)
>>> paginator.pages
2
"""} """}

View File

@ -13,7 +13,7 @@ class MaxLengthArgumentsTests(TestCase):
self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200) self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200)
self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100) self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100)
def test_custom_maxlengths(self): def test_custom_max_lengths(self):
self.verify_max_length(PersonWithCustomMaxLengths, 'email', 384) self.verify_max_length(PersonWithCustomMaxLengths, 'email', 384)
self.verify_max_length(PersonWithCustomMaxLengths, 'vcard', 1024) self.verify_max_length(PersonWithCustomMaxLengths, 'vcard', 1024)
self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 256) self.verify_max_length(PersonWithCustomMaxLengths, 'homepage', 256)

View File

@ -1,160 +0,0 @@
# Test access to max_length while still providing full backwards compatibility
# with legacy maxlength attribute.
"""
Don't print out the deprecation warnings during testing.
>>> from warnings import filterwarnings
>>> filterwarnings("ignore")
# legacy_maxlength function
>>> from django.utils.maxlength import legacy_maxlength
>>> legacy_maxlength(None, None)
>>> legacy_maxlength(10, None)
10
>>> legacy_maxlength(None, 10)
10
>>> legacy_maxlength(10, 12)
Traceback (most recent call last):
...
TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
>>> legacy_maxlength(0, 10)
Traceback (most recent call last):
...
TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
>>> legacy_maxlength(0, None)
0
>>> legacy_maxlength(None, 0)
0
#===============================================================================
# Fields
#===============================================================================
# Set up fields
>>> from django.db.models import fields
>>> new = fields.Field(max_length=15)
>>> old = fields.Field(maxlength=10)
# Ensure both max_length and legacy maxlength are not able to both be specified
>>> fields.Field(maxlength=10, max_length=15)
Traceback (most recent call last):
...
TypeError: Field cannot take both the max_length argument and the legacy maxlength argument.
# Test max_length
>>> new.max_length
15
>>> old.max_length
10
# Test accessing maxlength
>>> new.maxlength
15
>>> old.maxlength
10
# Test setting maxlength
>>> new.maxlength += 1
>>> old.maxlength += 1
>>> new.max_length
16
>>> old.max_length
11
# SlugField __init__ passes through max_length so test that too
>>> fields.SlugField('new', max_length=15).max_length
15
>>> fields.SlugField('empty').max_length
50
>>> fields.SlugField('old', maxlength=10).max_length
10
#===============================================================================
# (old)forms
#===============================================================================
>>> from django import oldforms
# Test max_length attribute
>>> oldforms.TextField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vTextField" name="new" size="30" value="" maxlength="15" />'
>>> oldforms.IntegerField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vIntegerField" name="new" size="10" value="" maxlength="15" />'
>>> oldforms.SmallIntegerField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vSmallIntegerField" name="new" size="5" value="" maxlength="15" />'
>>> oldforms.PositiveIntegerField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vPositiveIntegerField" name="new" size="10" value="" maxlength="15" />'
>>> oldforms.PositiveSmallIntegerField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vPositiveSmallIntegerField" name="new" size="5" value="" maxlength="15" />'
>>> oldforms.DatetimeField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vDatetimeField" name="new" size="30" value="" maxlength="15" />'
>>> oldforms.EmailField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vEmailField" name="new" size="50" value="" maxlength="15" />'
>>> oldforms.EmailField('new').render('')
u'<input type="text" id="id_new" class="vEmailField" name="new" size="50" value="" maxlength="75" />'
>>> oldforms.URLField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vURLField" name="new" size="50" value="" maxlength="15" />'
>>> oldforms.URLField('new').render('')
u'<input type="text" id="id_new" class="vURLField" name="new" size="50" value="" maxlength="200" />'
>>> oldforms.IPAddressField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vIPAddressField" name="new" size="15" value="" maxlength="15" />'
>>> oldforms.IPAddressField('new').render('')
u'<input type="text" id="id_new" class="vIPAddressField" name="new" size="15" value="" maxlength="15" />'
>>> oldforms.CommaSeparatedIntegerField('new', max_length=15).render('')
u'<input type="text" id="id_new" class="vCommaSeparatedIntegerField" name="new" size="20" value="" maxlength="15" />'
# Test legacy maxlength attribute
>>> oldforms.TextField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vTextField" name="old" size="30" value="" maxlength="10" />'
>>> oldforms.IntegerField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vIntegerField" name="old" size="10" value="" maxlength="10" />'
>>> oldforms.SmallIntegerField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vSmallIntegerField" name="old" size="5" value="" maxlength="10" />'
>>> oldforms.PositiveIntegerField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vPositiveIntegerField" name="old" size="10" value="" maxlength="10" />'
>>> oldforms.PositiveSmallIntegerField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vPositiveSmallIntegerField" name="old" size="5" value="" maxlength="10" />'
>>> oldforms.DatetimeField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vDatetimeField" name="old" size="30" value="" maxlength="10" />'
>>> oldforms.EmailField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vEmailField" name="old" size="50" value="" maxlength="10" />'
>>> oldforms.URLField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vURLField" name="old" size="50" value="" maxlength="10" />'
>>> oldforms.IPAddressField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vIPAddressField" name="old" size="15" value="" maxlength="10" />'
>>> oldforms.CommaSeparatedIntegerField('old', maxlength=10).render('')
u'<input type="text" id="id_old" class="vCommaSeparatedIntegerField" name="old" size="20" value="" maxlength="10" />'
"""
if __name__ == "__main__":
import doctest
doctest.testmod()