diff --git a/README.rst b/README.rst index 0221f8d..287bed1 100644 --- a/README.rst +++ b/README.rst @@ -13,6 +13,15 @@ Django Categories grew out of our need to provide a basic hierarchical taxonomy As a news site, our stories, photos, and other content get divided into "sections" and we wanted all the apps to use the same set of sections. As our needs grew, the Django Categories grew in the functionality it gave to category handling within web pages. +New in 1.2 +========== + +* Support for Django 1.5 +* Dropped support for Django 1.2 +* Dropped caching within the app +* Removed the old settings compatibility layer. *Must use new dictionary-based settings!* + + New in 1.1 ========== diff --git a/categories/settings.py b/categories/settings.py index 4d0679b..2d1589d 100644 --- a/categories/settings.py +++ b/categories/settings.py @@ -1,12 +1,9 @@ -import warnings - from django.conf import settings from django.db.models import Q from django.utils.translation import ugettext_lazy as _ DEFAULT_SETTINGS = { 'ALLOW_SLUG_CHANGE': False, - 'CACHE_VIEW_LENGTH': 600, 'RELATION_MODELS': [], 'M2M_REGISTRY': {}, 'FK_REGISTRY': {}, @@ -31,29 +28,10 @@ if DEFAULT_SETTINGS['SLUG_TRANSLITERATOR']: else: from django.core.exceptions import ImproperlyConfigured raise ImproperlyConfigured(_('%(transliterator) must be a callable or a string.') % - {'transliterator' : 'SLUG_TRANSLITERATOR'}) + {'transliterator': 'SLUG_TRANSLITERATOR'}) else: DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'] = lambda x: x -def warn_deprecated(deprecated_setting, replacement): - warnings.warn(_('%(deprecated_setting) is deprecated; use %(replacement)s instead.') % - {'deprecated_setting' : deprecated_setting, 'replacement' : replacement}, DeprecationWarning) - -if hasattr(settings, 'CATEGORIES_ALLOW_SLUG_CHANGE'): - warn_deprecated('settings.CATEGORIES_ALLOW_SLUG_CHANGE', 'settings.CATEGORIES_SETTINGS') - DEFAULT_SETTINGS["ALLOW_SLUG_CHANGE"] = getattr(settings, 'CATEGORIES_ALLOW_SLUG_CHANGE') - -if hasattr(settings, 'CATEGORIES_CACHE_VIEW_LENGTH'): - warn_deprecated('settings.CATEGORIES_CACHE_VIEW_LENGTH', 'settings.CATEGORIES_SETTINGS') - DEFAULT_SETTINGS["CACHE_VIEW_LENGTH"] = getattr(settings, 'CATEGORIES_CACHE_VIEW_LENGTH') - -if hasattr(settings, 'CATEGORIES_THUMBNAIL_UPLOAD_PATH'): - warn_deprecated('settings.CATEGORIES_THUMBNAIL_UPLOAD_PATH', 'settings.CATEGORIES_SETTINGS') - DEFAULT_SETTINGS["THUMBNAIL_UPLOAD_PATH"] = getattr(settings, 'CATEGORIES_THUMBNAIL_UPLOAD_PATH') - -if hasattr(settings, 'CATEGORIES_RELATION_MODELS'): - warn_deprecated('settings.CATEGORIES_RELATION_MODELS', 'settings.CATEGORIES_SETTINGS') - DEFAULT_SETTINGS["RELATION_MODELS"] = getattr(settings, 'CATEGORIES_RELATION_MODELS') # Add all the keys/values to the module's namespace globals().update(DEFAULT_SETTINGS) diff --git a/categories/views.py b/categories/views.py index 33fc1ca..a42f071 100644 --- a/categories/views.py +++ b/categories/views.py @@ -1,17 +1,22 @@ -import django from django.shortcuts import get_object_or_404 from django.core.exceptions import ObjectDoesNotExist from django.template import RequestContext from django.http import HttpResponse, Http404 -from django.views.decorators.cache import cache_page from django.template.loader import select_template from django.utils.translation import ugettext_lazy as _ +try: + from django.views.generic import DetailView, ListView +except ImportError: + try: + from cbv import DetailView, ListView + except ImportError: + from django.core.exceptions import ImproperlyConfigured + raise ImproperlyConfigured("For older versions of Django, you need django-cbv.") + from .models import Category -from .settings import CACHE_VIEW_LENGTH -@cache_page(CACHE_VIEW_LENGTH) def category_detail(request, path, template_name='categories/category_detail.html', extra_context={}): path_items = path.strip('/').split('/') @@ -51,59 +56,78 @@ def get_category_for_path(path, queryset=Category.objects.all()): level=len(path_items) - 1) return queryset.get() -try: - import cbv - HAS_CBV = True -except ImportError: - HAS_CBV = False -if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV): - if HAS_CBV: - from cbv import DetailView, ListView - else: - from django.views.generic import DetailView, ListView +class CategoryDetailView(DetailView): + model = Category + path_field = 'path' - class CategoryDetailView(DetailView): + def get_object(self, **kwargs): + if self.path_field not in self.kwargs: + raise AttributeError(u"Category detail view %s must be called with " + u"a %s." % self.__class__.__name__, self.path_field) + if self.queryset is None: + queryset = self.get_queryset() + try: + return get_category_for_path(self.kwargs[self.path_field]) + except ObjectDoesNotExist: + raise Http404(_(u"No %(verbose_name)s found matching the query") % + {'verbose_name': queryset.model._meta.verbose_name}) - model = Category - path_field = 'path' + def get_template_names(self): + names = [] + path_items = self.kwargs[self.path_field].strip('/').split('/') + while path_items: + names.append('categories/%s.html' % '_'.join(path_items)) + path_items.pop() + names.extend(super(CategoryDetailView, self).get_template_names()) + return names - def get_object(self, **kwargs): - if self.path_field not in self.kwargs: - raise AttributeError(_('Category detail view %(view) must be called with a %(path_field).') % - {'view' : self.__class__.__name__, 'path_field' : self.path_field}) - if self.queryset is None: - queryset = self.get_queryset() - try: - return get_category_for_path(self.kwargs[self.path_field]) - except ObjectDoesNotExist: - raise Http404(_('No %(verbose_name)s found matching the query') % - {'verbose_name': queryset.model._meta.verbose_name}) - def get_template_names(self): - names = [] +class CategoryRelatedDetail(DetailView): + path_field = 'category_path' + object_name_field = None + + def get_object(self, **kwargs): + queryset = super(CategoryRelatedDetail, self).get_queryset() + category = get_category_for_path(self.kwargs[self.path_field]) + return queryset.get(category=category, slug=self.kwargs[self.slug_field]) + + def get_template_names(self): + names = [] + opts = self.object._meta + path_items = self.kwargs[self.path_field].strip('/').split('/') + if self.object_name_field: + path_items.append(getattr(self.object, self.object_name_field)) + while path_items: + names.append('%s/category_%s_%s%s.html' % ( + opts.app_label, + '_'.join(path_items), + opts.object_name.lower(), + self.template_name_suffix) + ) + path_items.pop() + names.append('%s/category_%s%s.html' % ( + opts.app_label, + opts.object_name.lower(), + self.template_name_suffix) + ) + names.extend(super(CategoryRelatedDetail, self).get_template_names()) + return names + + +class CategoryRelatedList(ListView): + path_field = 'category_path' + + def get_queryset(self): + queryset = super(CategoryRelatedList, self).get_queryset() + category = get_category_for_path(self.kwargs['category_path']) + return queryset.filter(category=category) + + def get_template_names(self): + names = [] + if hasattr(self.object_list, 'model'): + opts = self.object_list.model._meta path_items = self.kwargs[self.path_field].strip('/').split('/') - while path_items: - names.append('categories/%s.html' % '_'.join(path_items)) - path_items.pop() - names.extend(super(CategoryDetailView, self).get_template_names()) - return names - - class CategoryRelatedDetail(DetailView): - path_field = 'category_path' - object_name_field = None - - def get_object(self, **kwargs): - queryset = super(CategoryRelatedDetail, self).get_queryset() - category = get_category_for_path(self.kwargs[self.path_field]) - return queryset.get(category=category, slug=self.kwargs[self.slug_field]) - - def get_template_names(self): - names = [] - opts = self.object._meta - path_items = self.kwargs[self.path_field].strip('/').split('/') - if self.object_name_field: - path_items.append(getattr(self.object, self.object_name_field)) while path_items: names.append('%s/category_%s_%s%s.html' % ( opts.app_label, @@ -117,34 +141,5 @@ if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV): opts.object_name.lower(), self.template_name_suffix) ) - names.extend(super(CategoryRelatedDetail, self).get_template_names()) - return names - - class CategoryRelatedList(ListView): - path_field = 'category_path' - - def get_queryset(self): - queryset = super(CategoryRelatedList, self).get_queryset() - category = get_category_for_path(self.kwargs['category_path']) - return queryset.filter(category=category) - - def get_template_names(self): - names = [] - if hasattr(self.object_list, 'model'): - opts = self.object_list.model._meta - path_items = self.kwargs[self.path_field].strip('/').split('/') - while path_items: - names.append('%s/category_%s_%s%s.html' % ( - opts.app_label, - '_'.join(path_items), - opts.object_name.lower(), - self.template_name_suffix) - ) - path_items.pop() - names.append('%s/category_%s%s.html' % ( - opts.app_label, - opts.object_name.lower(), - self.template_name_suffix) - ) - names.extend(super(CategoryRelatedList, self).get_template_names()) - return names + names.extend(super(CategoryRelatedList, self).get_template_names()) + return names