mirror of
https://github.com/jazzband/django-categories.git
synced 2026-03-16 22:30:24 +00:00
Merge branch '1.1'
This commit is contained in:
commit
213a208a23
53 changed files with 1477 additions and 945 deletions
17
README.rst
17
README.rst
|
|
@ -1,7 +1,24 @@
|
|||
=================
|
||||
Django Categories
|
||||
=================
|
||||
|
||||
Django Categories grew out of our need to provide a basic hierarchical taxonomy management system that multiple applications could use independently or in concert.
|
||||
|
||||
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.1
|
||||
==========
|
||||
|
||||
* Fixed a cosmetic bug in the Django 1.4 admin. Action checkboxes now only appear once.
|
||||
|
||||
* Template tags are refactored to allow easy use of any model derived from ``CategoryBase``.
|
||||
|
||||
* Improved test suite.
|
||||
|
||||
* Improved some of the documentation.
|
||||
|
||||
|
||||
Upgrade path from 1.0.2 to 1.0.3
|
||||
================================
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
__version_info__ = {
|
||||
'major': 1,
|
||||
'minor': 0,
|
||||
'micro': 5,
|
||||
'minor': 1,
|
||||
'micro': 0,
|
||||
'releaselevel': 'final',
|
||||
'serial': 1
|
||||
}
|
||||
|
||||
|
||||
def get_version(short=False):
|
||||
assert __version_info__['releaselevel'] in ('alpha', 'beta', 'final')
|
||||
vers = ["%(major)i.%(minor)i" % __version_info__, ]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ if RELATION_MODELS:
|
|||
class CategoryAdminForm(CategoryBaseAdminForm):
|
||||
class Meta:
|
||||
model = Category
|
||||
|
||||
|
||||
def clean_alternate_title(self):
|
||||
if self.instance is None or not self.cleaned_data['alternate_title']:
|
||||
return self.cleaned_data['name']
|
||||
|
|
@ -48,7 +48,7 @@ class CategoryAdmin(CategoryBaseAdmin):
|
|||
'fields': ('parent', 'name', 'thumbnail', 'active')
|
||||
}),
|
||||
('Meta Data', {
|
||||
'fields': ('alternate_title', 'alternate_url', 'description',
|
||||
'fields': ('alternate_title', 'alternate_url', 'description',
|
||||
'meta_keywords', 'meta_extra'),
|
||||
'classes': ('collapse',),
|
||||
}),
|
||||
|
|
@ -57,10 +57,10 @@ class CategoryAdmin(CategoryBaseAdmin):
|
|||
'classes': ('collapse',),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
if RELATION_MODELS:
|
||||
inlines = [InlineCategoryRelation,]
|
||||
|
||||
inlines = [InlineCategoryRelation, ]
|
||||
|
||||
class Media:
|
||||
js = (JAVASCRIPT_URL + 'genericcollections.js',)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from mptt.managers import TreeManager
|
|||
from .editor.tree_editor import TreeEditor
|
||||
from .settings import ALLOW_SLUG_CHANGE, SLUG_TRANSLITERATOR
|
||||
|
||||
|
||||
class CategoryManager(models.Manager):
|
||||
"""
|
||||
A manager that adds an "active()" method for all active categories
|
||||
|
|
@ -32,44 +33,44 @@ class CategoryBase(MPTTModel):
|
|||
This base model includes the absolute bare bones fields and methods. One
|
||||
could simply subclass this model and do nothing else and it should work.
|
||||
"""
|
||||
parent = TreeForeignKey('self',
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="children",
|
||||
parent = TreeForeignKey('self',
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="children",
|
||||
verbose_name='Parent')
|
||||
name = models.CharField(max_length=100)
|
||||
slug = models.SlugField()
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
|
||||
objects = CategoryManager()
|
||||
tree = TreeManager()
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
While you can activate an item without activating its descendants,
|
||||
It doesn't make sense that you can deactivate an item and have its
|
||||
It doesn't make sense that you can deactivate an item and have its
|
||||
decendants remain active.
|
||||
"""
|
||||
if not self.slug:
|
||||
self.slug = slugify(SLUG_TRANSLITERATOR(self.name))[:50]
|
||||
|
||||
|
||||
super(CategoryBase, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
if not self.active:
|
||||
for item in self.get_descendants():
|
||||
if item.active != self.active:
|
||||
item.active = self.active
|
||||
item.save()
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
ancestors = self.get_ancestors()
|
||||
return ' > '.join([force_unicode(i.name) for i in ancestors]+[self.name,])
|
||||
|
||||
return ' > '.join([force_unicode(i.name) for i in ancestors] + [self.name, ])
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
unique_together = ('parent', 'name')
|
||||
ordering = ('tree_id', 'lft')
|
||||
|
||||
|
||||
class MPTTMeta:
|
||||
order_insertion_by = 'name'
|
||||
|
||||
|
|
@ -79,11 +80,11 @@ class CategoryBaseAdminForm(forms.ModelForm):
|
|||
if self.instance is None or not ALLOW_SLUG_CHANGE:
|
||||
self.cleaned_data['slug'] = slugify(self.cleaned_data['name'])
|
||||
return self.cleaned_data['slug'][:50]
|
||||
|
||||
|
||||
def clean(self):
|
||||
super(CategoryBaseAdminForm, self).clean()
|
||||
opts = self._meta
|
||||
|
||||
|
||||
# Validate slug is valid in that level
|
||||
kwargs = {}
|
||||
if self.cleaned_data.get('parent', None) is None:
|
||||
|
|
@ -91,14 +92,14 @@ class CategoryBaseAdminForm(forms.ModelForm):
|
|||
else:
|
||||
kwargs['parent__pk'] = int(self.cleaned_data['parent'].id)
|
||||
this_level_slugs = [c['slug'] for c in opts.model.objects.filter(
|
||||
**kwargs).values('id','slug'
|
||||
**kwargs).values('id', 'slug'
|
||||
) if c['id'] != self.instance.id]
|
||||
if self.cleaned_data['slug'] in this_level_slugs:
|
||||
raise forms.ValidationError("The slug must be unique among "
|
||||
"the items at its level.")
|
||||
|
||||
|
||||
# Validate Category Parent
|
||||
# Make sure the category doesn't set itself or any of its children as
|
||||
# Make sure the category doesn't set itself or any of its children as
|
||||
# its parent.
|
||||
decendant_ids = self.instance.get_descendants().values_list('id', flat=True)
|
||||
if self.cleaned_data.get('parent', None) is None or self.instance.id is None:
|
||||
|
|
@ -117,35 +118,36 @@ class CategoryBaseAdmin(TreeEditor, admin.ModelAdmin):
|
|||
list_display = ('name', 'active')
|
||||
search_fields = ('name',)
|
||||
prepopulated_fields = {'slug': ('name',)}
|
||||
|
||||
|
||||
actions = ['activate', 'deactivate']
|
||||
|
||||
def get_actions(self, request):
|
||||
actions = super(CategoryBaseAdmin, self).get_actions(request)
|
||||
if 'delete_selected' in actions:
|
||||
del actions['delete_selected']
|
||||
return actions
|
||||
|
||||
|
||||
def deactivate(self, request, queryset):
|
||||
"""
|
||||
Set active to False for selected items
|
||||
"""
|
||||
selected_cats = self.model.objects.filter(
|
||||
pk__in=[int(x) for x in request.POST.getlist('_selected_action')])
|
||||
|
||||
|
||||
for item in selected_cats:
|
||||
if item.active:
|
||||
item.active = False
|
||||
item.save()
|
||||
item.children.all().update(active=False)
|
||||
deactivate.short_description = "Deactivate selected categories and their children"
|
||||
|
||||
|
||||
def activate(self, request, queryset):
|
||||
"""
|
||||
Set active to True for selected items
|
||||
"""
|
||||
selected_cats = self.model.objects.filter(
|
||||
pk__in=[int(x) for x in request.POST.getlist('_selected_action')])
|
||||
|
||||
|
||||
for item in selected_cats:
|
||||
item.active = True
|
||||
item.save()
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ if STATIC_URL == None:
|
|||
STATIC_URL = settings.MEDIA_URL
|
||||
MEDIA_PATH = getattr(settings, 'EDITOR_MEDIA_PATH', '%seditor/' % STATIC_URL)
|
||||
|
||||
TREE_INITIAL_STATE = getattr(settings, 'EDITOR_TREE_INITIAL_STATE', 'collapsed')
|
||||
TREE_INITIAL_STATE = getattr(settings, 'EDITOR_TREE_INITIAL_STATE', 'collapsed')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import django
|
||||
from django.db import models
|
||||
from django.template import Library
|
||||
from django.contrib.admin.templatetags.admin_list import result_headers
|
||||
from django.contrib.admin.templatetags.admin_list import result_headers, _boolean_icon
|
||||
try:
|
||||
from django.contrib.admin.util import lookup_field, display_for_field, label_for_field
|
||||
except ImportError:
|
||||
|
|
@ -13,6 +14,7 @@ from django.utils.safestring import mark_safe
|
|||
|
||||
register = Library()
|
||||
|
||||
|
||||
def items_for_tree_result(cl, result, form):
|
||||
"""
|
||||
Generates the actual list of data.
|
||||
|
|
@ -27,6 +29,9 @@ def items_for_tree_result(cl, result, form):
|
|||
result_repr = EMPTY_CHANGELIST_VALUE
|
||||
else:
|
||||
if f is None:
|
||||
if django.VERSION[1] == 4:
|
||||
if field_name == 'action_checkbox':
|
||||
row_class = ' class="action-checkbox disclosure"'
|
||||
allow_tags = getattr(attr, 'allow_tags', False)
|
||||
boolean = getattr(attr, 'boolean', False)
|
||||
if boolean:
|
||||
|
|
@ -50,21 +55,26 @@ def items_for_tree_result(cl, result, form):
|
|||
if isinstance(f, models.DateField) or isinstance(f, models.TimeField):
|
||||
row_class = ' class="nowrap"'
|
||||
if first:
|
||||
try:
|
||||
f, attr, checkbox_value = lookup_field('action_checkbox', result, cl.model_admin)
|
||||
#result_repr = mark_safe("%s%s" % (value, result_repr))
|
||||
if row_class:
|
||||
row_class = "%s%s" % (row_class[:-1],' disclosure"')
|
||||
else:
|
||||
row_class = ' class="disclosure"'
|
||||
except (AttributeError, ObjectDoesNotExist):
|
||||
pass
|
||||
|
||||
if django.VERSION[1] < 4:
|
||||
try:
|
||||
f, attr, checkbox_value = lookup_field('action_checkbox', result, cl.model_admin)
|
||||
#result_repr = mark_safe("%s%s" % (value, result_repr))
|
||||
if row_class:
|
||||
row_class = "%s%s" % (row_class[:-1], ' disclosure"')
|
||||
else:
|
||||
row_class = ' class="disclosure"'
|
||||
except (AttributeError, ObjectDoesNotExist):
|
||||
pass
|
||||
|
||||
if force_unicode(result_repr) == '':
|
||||
result_repr = mark_safe(' ')
|
||||
# If list_display_links not defined, add the link tag to the first field
|
||||
if (first and not cl.list_display_links) or field_name in cl.list_display_links:
|
||||
table_tag = 'td' #{True:'th', False:'td'}[first]
|
||||
if django.VERSION[1] < 4:
|
||||
table_tag = 'td' # {True:'th', False:'td'}[first]
|
||||
else:
|
||||
table_tag = {True:'th', False:'td'}[first]
|
||||
|
||||
url = cl.url_for_result(result)
|
||||
# Convert the pk to something that can be used in Javascript.
|
||||
# Problem cases are long ints (23L) and non-ASCII strings.
|
||||
|
|
@ -75,8 +85,13 @@ def items_for_tree_result(cl, result, form):
|
|||
value = result.serializable_value(attr)
|
||||
result_id = repr(force_unicode(value))[1:]
|
||||
first = False
|
||||
yield mark_safe(u'<%s%s>%s<a href="%s"%s>%s</a></%s>' % \
|
||||
(table_tag, row_class, checkbox_value, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
|
||||
if django.VERSION[1] < 4:
|
||||
yield mark_safe(u'<%s%s>%s<a href="%s"%s>%s</a></%s>' % \
|
||||
(table_tag, row_class, checkbox_value, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
|
||||
else:
|
||||
yield mark_safe(u'<%s%s><a href="%s"%s>%s</a></%s>' % \
|
||||
(table_tag, row_class, url, (cl.is_popup and ' onclick="opener.dismissRelatedLookupPopup(window, %s); return false;"' % result_id or ''), conditional_escape(result_repr), table_tag))
|
||||
|
||||
else:
|
||||
# By default the fields come from ModelAdmin.list_editable, but if we pull
|
||||
# the fields out of the form instead of list_editable custom admins
|
||||
|
|
@ -90,9 +105,11 @@ def items_for_tree_result(cl, result, form):
|
|||
if form and not form[cl.model._meta.pk.name].is_hidden:
|
||||
yield mark_safe(u'<td>%s</td>' % force_unicode(form[cl.model._meta.pk.name]))
|
||||
|
||||
|
||||
class TreeList(list):
|
||||
pass
|
||||
|
||||
|
||||
def tree_results(cl):
|
||||
if cl.formset:
|
||||
for res, form in zip(cl.result_list, cl.formset.forms):
|
||||
|
|
@ -115,6 +132,7 @@ def tree_results(cl):
|
|||
res.parent_pk = None
|
||||
yield result
|
||||
|
||||
|
||||
def result_tree_list(cl):
|
||||
"""
|
||||
Displays the headers and data list together
|
||||
|
|
|
|||
|
|
@ -11,15 +11,16 @@ import django
|
|||
|
||||
import settings
|
||||
|
||||
|
||||
class TreeEditorQuerySet(QuerySet):
|
||||
"""
|
||||
The TreeEditorQuerySet is a special query set used only in the TreeEditor
|
||||
ChangeList page. The only difference to a regular QuerySet is that it
|
||||
will enforce:
|
||||
|
||||
|
||||
(a) The result is ordered in correct tree order so that
|
||||
the TreeAdmin works all right.
|
||||
|
||||
|
||||
(b) It ensures that all ancestors of selected items are included
|
||||
in the result set, so the resulting tree display actually
|
||||
makes sense.
|
||||
|
|
@ -41,20 +42,20 @@ class TreeEditorQuerySet(QuerySet):
|
|||
p.id not in include_pages:
|
||||
ancestor_id_list = p.get_ancestors().values_list('id', flat=True)
|
||||
include_pages.update(ancestor_id_list)
|
||||
|
||||
|
||||
if include_pages:
|
||||
qs = qs | self.model._default_manager.filter(id__in=include_pages)
|
||||
|
||||
|
||||
qs = qs.distinct()
|
||||
|
||||
|
||||
for obj in super(TreeEditorQuerySet, qs).iterator():
|
||||
yield obj
|
||||
|
||||
|
||||
# Although slicing isn't nice in a tree, it is used in the deletion action
|
||||
# in the admin changelist. This causes github issue #25
|
||||
# def __getitem__(self, index):
|
||||
# return self # Don't even try to slice
|
||||
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
"""
|
||||
Quick and dirty hack to fix change_view and delete_view; they use
|
||||
|
|
@ -65,54 +66,56 @@ class TreeEditorQuerySet(QuerySet):
|
|||
"""
|
||||
return self.model._default_manager.get(*args, **kwargs)
|
||||
|
||||
|
||||
class TreeChangeList(ChangeList):
|
||||
def _get_default_ordering(self):
|
||||
if django.VERSION[1] < 4:
|
||||
return '', '' #('tree_id', 'lft')
|
||||
return '', '' # ('tree_id', 'lft')
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_ordering(self, request=None, queryset=None):
|
||||
if django.VERSION[1] < 4:
|
||||
return '', '' #('tree_id', 'lft')
|
||||
return '', '' # ('tree_id', 'lft')
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_query_set(self, *args, **kwargs):
|
||||
qs = super(TreeChangeList, self).get_query_set(*args, **kwargs).order_by('tree_id', 'lft')
|
||||
return qs
|
||||
|
||||
|
||||
class TreeEditor(admin.ModelAdmin):
|
||||
list_per_page = 999999999 # We can't have pagination
|
||||
list_max_show_all = 200 # new in django 1.4
|
||||
|
||||
list_per_page = 999999999 # We can't have pagination
|
||||
list_max_show_all = 200 # new in django 1.4
|
||||
|
||||
class Media:
|
||||
css = {'all':(settings.MEDIA_PATH + "jquery.treeTable.css",)}
|
||||
css = {'all': (settings.MEDIA_PATH + "jquery.treeTable.css", )}
|
||||
js = []
|
||||
|
||||
js.extend((settings.MEDIA_PATH + "jquery.treeTable.js",))
|
||||
|
||||
|
||||
js.extend((settings.MEDIA_PATH + "jquery.treeTable.js", ))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TreeEditor, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
self.list_display = list(self.list_display)
|
||||
|
||||
|
||||
if 'action_checkbox' in self.list_display:
|
||||
self.list_display.remove('action_checkbox')
|
||||
|
||||
|
||||
opts = self.model._meta
|
||||
self.change_list_template = [
|
||||
'admin/%s/%s/editor/tree_editor.html' % (opts.app_label, opts.object_name.lower()),
|
||||
'admin/%s/editor/tree_editor.html' % opts.app_label,
|
||||
'admin/editor/tree_editor.html',
|
||||
]
|
||||
|
||||
|
||||
def get_changelist(self, request, **kwargs):
|
||||
"""
|
||||
Returns the ChangeList class for use on the changelist page.
|
||||
"""
|
||||
return TreeChangeList
|
||||
|
||||
|
||||
def old_changelist_view(self, request, extra_context=None):
|
||||
"The 'change list' admin view for this model."
|
||||
from django.contrib.admin.views.main import ERROR_FLAG
|
||||
|
|
@ -137,15 +140,15 @@ class TreeEditor(admin.ModelAdmin):
|
|||
|
||||
try:
|
||||
if django.VERSION[1] < 4:
|
||||
params = (request, self.model, list_display,
|
||||
self.list_display_links, self.list_filter, self.date_hierarchy,
|
||||
self.search_fields, self.list_select_related,
|
||||
self.list_per_page,self.list_editable, self)
|
||||
params = (request, self.model, list_display,
|
||||
self.list_display_links, self.list_filter, self.date_hierarchy,
|
||||
self.search_fields, self.list_select_related,
|
||||
self.list_per_page, self.list_editable, self)
|
||||
else:
|
||||
params = (request, self.model, list_display,
|
||||
self.list_display_links, self.list_filter, self.date_hierarchy,
|
||||
self.search_fields, self.list_select_related,
|
||||
self.list_per_page, self.list_max_show_all,
|
||||
params = (request, self.model, list_display,
|
||||
self.list_display_links, self.list_filter, self.date_hierarchy,
|
||||
self.search_fields, self.list_select_related,
|
||||
self.list_per_page, self.list_max_show_all,
|
||||
self.list_editable, self)
|
||||
cl = TreeChangeList(*params)
|
||||
except IncorrectLookupParameters:
|
||||
|
|
@ -238,7 +241,7 @@ class TreeEditor(admin.ModelAdmin):
|
|||
else:
|
||||
selection_note_all = ungettext('%(total_count)s selected',
|
||||
'All %(total_count)s selected', cl.result_count)
|
||||
|
||||
|
||||
context.update({
|
||||
'module_name': force_unicode(opts.verbose_name_plural),
|
||||
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
|
||||
|
|
@ -253,7 +256,7 @@ class TreeEditor(admin.ModelAdmin):
|
|||
'admin/%s/change_list.html' % app_label,
|
||||
'admin/change_list.html'
|
||||
], context, context_instance=context_instance)
|
||||
|
||||
|
||||
def changelist_view(self, request, extra_context=None, *args, **kwargs):
|
||||
"""
|
||||
Handle the changelist view, the django view for the model instances
|
||||
|
|
@ -267,7 +270,7 @@ class TreeEditor(admin.ModelAdmin):
|
|||
request, extra_context, *args, **kwargs)
|
||||
else:
|
||||
return self.old_changelist_view(request, extra_context)
|
||||
|
||||
|
||||
def queryset(self, request):
|
||||
"""
|
||||
Returns a QuerySet of all model instances that can be edited by the
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@ Provides compatibility with Django 1.1
|
|||
|
||||
Copied from django.contrib.admin.util
|
||||
"""
|
||||
from django.forms.forms import pretty_name
|
||||
from django.db import models
|
||||
from django.db.models.related import RelatedObject
|
||||
from django.utils.encoding import force_unicode, smart_unicode, smart_str
|
||||
from django.utils import formats
|
||||
|
||||
|
||||
def lookup_field(name, obj, model_admin=None):
|
||||
opts = obj._meta
|
||||
|
|
@ -81,10 +85,11 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
|
|||
else:
|
||||
return label
|
||||
|
||||
|
||||
def display_for_field(value, field):
|
||||
from django.contrib.admin.templatetags.admin_list import _boolean_icon
|
||||
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
|
||||
|
||||
|
||||
if field.flatchoices:
|
||||
return dict(field.flatchoices).get(value, EMPTY_CHANGELIST_VALUE)
|
||||
# NullBooleanField needs special-case null-handling, so it comes
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from django.db.models import ForeignKey, ManyToManyField
|
|||
|
||||
from .models import Category
|
||||
|
||||
|
||||
class CategoryM2MField(ManyToManyField):
|
||||
def __init__(self, **kwargs):
|
||||
if 'to' in kwargs:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
|
|
@ -8,7 +9,7 @@ class Command(BaseCommand):
|
|||
args = "[appname ...]"
|
||||
can_import_settings = True
|
||||
requires_model_validation = False
|
||||
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""
|
||||
Alter the tables
|
||||
|
|
@ -17,7 +18,7 @@ class Command(BaseCommand):
|
|||
from south.db import db
|
||||
except ImportError:
|
||||
raise ImproperlyConfigured("South must be installed for this command to work")
|
||||
|
||||
|
||||
from categories.migration import migrate_app
|
||||
from categories import model_registry
|
||||
if args:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
|
|
@ -8,7 +9,7 @@ class Command(BaseCommand):
|
|||
args = "appname modelname fieldname"
|
||||
can_import_settings = True
|
||||
requires_model_validation = False
|
||||
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""
|
||||
Alter the tables
|
||||
|
|
@ -17,10 +18,9 @@ class Command(BaseCommand):
|
|||
from south.db import db
|
||||
except ImportError:
|
||||
raise ImproperlyConfigured("South must be installed for this command to work")
|
||||
|
||||
|
||||
from categories.migration import drop_field
|
||||
from categories import model_registry
|
||||
if len(args) != 3:
|
||||
print "You must specify an Application name, a Model name and a Field name"
|
||||
|
||||
|
||||
drop_field(*args)
|
||||
|
|
|
|||
|
|
@ -5,18 +5,19 @@ from django.db import transaction
|
|||
from categories.models import Category
|
||||
from categories.settings import SLUG_TRANSLITERATOR
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Import category trees from a file."""
|
||||
|
||||
|
||||
help = "Imports category tree(s) from a file. Sub categories must be indented by the same multiple of spaces or tabs."
|
||||
args = "file_path [file_path ...]"
|
||||
|
||||
|
||||
def get_indent(self, string):
|
||||
"""
|
||||
Look through the string and count the spaces
|
||||
"""
|
||||
indent_amt = 0
|
||||
|
||||
|
||||
if string[0] == '\t':
|
||||
return '\t'
|
||||
for char in string:
|
||||
|
|
@ -24,7 +25,7 @@ class Command(BaseCommand):
|
|||
indent_amt += 1
|
||||
else:
|
||||
return ' ' * indent_amt
|
||||
|
||||
|
||||
@transaction.commit_on_success
|
||||
def make_category(self, string, parent=None, order=1):
|
||||
"""
|
||||
|
|
@ -42,20 +43,20 @@ class Command(BaseCommand):
|
|||
parent.rght = cat.rght + 1
|
||||
parent.save()
|
||||
return cat
|
||||
|
||||
|
||||
def parse_lines(self, lines):
|
||||
"""
|
||||
Do the work of parsing each line
|
||||
"""
|
||||
indent = ''
|
||||
level = 0
|
||||
|
||||
|
||||
if lines[0][0] == ' ' or lines[0][0] == '\t':
|
||||
raise CommandError("The first line in the file cannot start with a space or tab.")
|
||||
|
||||
|
||||
# This keeps track of the current parents at a given level
|
||||
current_parents = {0: None}
|
||||
|
||||
|
||||
for line in lines:
|
||||
if len(line) == 0:
|
||||
continue
|
||||
|
|
@ -65,18 +66,18 @@ class Command(BaseCommand):
|
|||
elif not line[0] in indent:
|
||||
raise CommandError("You can't mix spaces and tabs for indents")
|
||||
level = line.count(indent)
|
||||
current_parents[level] = self.make_category(line, parent=current_parents[level-1])
|
||||
current_parents[level] = self.make_category(line, parent=current_parents[level - 1])
|
||||
else:
|
||||
# We are back to a zero level, so reset the whole thing
|
||||
current_parents = {0: self.make_category(line)}
|
||||
current_parents[0]._tree_manager.rebuild()
|
||||
|
||||
|
||||
def handle(self, *file_paths, **options):
|
||||
"""
|
||||
Handle the basic import
|
||||
"""
|
||||
import os
|
||||
|
||||
|
||||
for file_path in file_paths:
|
||||
if not os.path.isfile(file_path):
|
||||
print "File %s not found." % file_path
|
||||
|
|
@ -84,6 +85,5 @@ class Command(BaseCommand):
|
|||
f = file(file_path, 'r')
|
||||
data = f.readlines()
|
||||
f.close()
|
||||
|
||||
|
||||
self.parse_lines(data)
|
||||
|
||||
|
|
@ -7,16 +7,17 @@ from django.core.files.storage import get_storage_class
|
|||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .settings import (RELATION_MODELS, RELATIONS, THUMBNAIL_UPLOAD_PATH,
|
||||
from .settings import (RELATION_MODELS, RELATIONS, THUMBNAIL_UPLOAD_PATH,
|
||||
THUMBNAIL_STORAGE)
|
||||
|
||||
from .base import CategoryBase
|
||||
|
||||
STORAGE = get_storage_class(THUMBNAIL_STORAGE)
|
||||
|
||||
|
||||
class Category(CategoryBase):
|
||||
thumbnail = models.FileField(
|
||||
upload_to=THUMBNAIL_UPLOAD_PATH,
|
||||
upload_to=THUMBNAIL_UPLOAD_PATH,
|
||||
null=True, blank=True,
|
||||
storage=STORAGE(),)
|
||||
thumbnail_width = models.IntegerField(blank=True, null=True)
|
||||
|
|
@ -28,8 +29,8 @@ class Category(CategoryBase):
|
|||
max_length=100,
|
||||
help_text="An alternative title to use on pages with this category.")
|
||||
alternate_url = models.CharField(
|
||||
blank=True,
|
||||
max_length=200,
|
||||
blank=True,
|
||||
max_length=200,
|
||||
help_text="An alternative URL to use instead of the one derived from "
|
||||
"the category hierarchy.")
|
||||
description = models.TextField(blank=True, null=True)
|
||||
|
|
@ -43,20 +44,19 @@ class Category(CategoryBase):
|
|||
default="",
|
||||
help_text="(Advanced) Any additional HTML to be placed verbatim "
|
||||
"in the <head>")
|
||||
|
||||
|
||||
|
||||
@property
|
||||
def short_title(self):
|
||||
return self.name
|
||||
|
||||
|
||||
def get_absolute_url(self):
|
||||
"""Return a path"""
|
||||
if self.alternate_url:
|
||||
return self.alternate_url
|
||||
prefix = reverse('categories_tree_list')
|
||||
ancestors = list(self.get_ancestors()) + [self,]
|
||||
ancestors = list(self.get_ancestors()) + [self, ]
|
||||
return prefix + '/'.join([force_unicode(i.slug) for i in ancestors]) + '/'
|
||||
|
||||
|
||||
if RELATION_MODELS:
|
||||
def get_related_content_type(self, content_type):
|
||||
"""
|
||||
|
|
@ -64,13 +64,13 @@ class Category(CategoryBase):
|
|||
"""
|
||||
return self.categoryrelation_set.filter(
|
||||
content_type__name=content_type)
|
||||
|
||||
|
||||
def get_relation_type(self, relation_type):
|
||||
"""
|
||||
Get all relations of the specified relation type
|
||||
"""
|
||||
return self.categoryrelation_set.filter(relation_type=relation_type)
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.thumbnail:
|
||||
from django.core.files.images import get_image_dimensions
|
||||
|
|
@ -81,23 +81,25 @@ class Category(CategoryBase):
|
|||
width, height = get_image_dimensions(self.thumbnail.file, close=True)
|
||||
else:
|
||||
width, height = None, None
|
||||
|
||||
|
||||
self.thumbnail_width = width
|
||||
self.thumbnail_height = height
|
||||
|
||||
|
||||
super(Category, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Meta(CategoryBase.Meta):
|
||||
verbose_name_plural = 'categories'
|
||||
|
||||
|
||||
class MPTTMeta:
|
||||
order_insertion_by = ('order', 'name')
|
||||
|
||||
|
||||
if RELATIONS:
|
||||
CATEGORY_RELATION_LIMITS = reduce(lambda x,y: x|y, RELATIONS)
|
||||
CATEGORY_RELATION_LIMITS = reduce(lambda x, y: x | y, RELATIONS)
|
||||
else:
|
||||
CATEGORY_RELATION_LIMITS = []
|
||||
|
||||
|
||||
class CategoryRelationManager(models.Manager):
|
||||
def get_content_type(self, content_type):
|
||||
"""
|
||||
|
|
@ -105,7 +107,7 @@ class CategoryRelationManager(models.Manager):
|
|||
"""
|
||||
qs = self.get_query_set()
|
||||
return qs.filter(content_type__name=content_type)
|
||||
|
||||
|
||||
def get_relation_type(self, relation_type):
|
||||
"""
|
||||
Get all the items of the given relationship type related to this item.
|
||||
|
|
@ -113,6 +115,7 @@ class CategoryRelationManager(models.Manager):
|
|||
qs = self.get_query_set()
|
||||
return qs.filter(relation_type=relation_type)
|
||||
|
||||
|
||||
class CategoryRelation(models.Model):
|
||||
"""Related category item"""
|
||||
category = models.ForeignKey(Category)
|
||||
|
|
@ -120,13 +123,13 @@ class CategoryRelation(models.Model):
|
|||
ContentType, limit_choices_to=CATEGORY_RELATION_LIMITS)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
relation_type = models.CharField(_("Relation Type"),
|
||||
max_length="200",
|
||||
blank=True,
|
||||
relation_type = models.CharField(_("Relation Type"),
|
||||
max_length="200",
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text=_("A generic text field to tag a relation, like 'leadphoto'."))
|
||||
|
||||
|
||||
objects = CategoryRelationManager()
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return u"CategoryRelation"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
{% for item in category.get_ancestors %}
|
||||
<a href="{{ item.get_absolute_url }}">{{ item.name }}</a>
|
||||
{{ separator }}
|
||||
{% endfor %}
|
||||
{{ category.name }}
|
||||
{% spaceless %}{% for item in category.get_ancestors %}
|
||||
<a href="{{ item.get_absolute_url }}">{{ item.name }}</a>{{ separator }}{% endfor %}{{ category.name }}
|
||||
{% endspaceless %}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
{% load category_tags %}
|
||||
{% load category_tags %}{% spaceless %}
|
||||
<ul><li><a href="{% url categories_tree_list %}">Top</a>
|
||||
{% for node,structure in path|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>
|
||||
|
|
@ -8,4 +8,4 @@
|
|||
{% else %}<a href="{{ node.get_absolute_url }}">{{ node.name }}</a>
|
||||
{% endifequal %}
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}</li></ul>
|
||||
{% endfor %}</li></ul>{% endspaceless %}
|
||||
|
|
@ -1,35 +1,60 @@
|
|||
from django import template
|
||||
from django.template import Library, Node, TemplateSyntaxError, \
|
||||
Variable, resolve_variable, VariableDoesNotExist, Context
|
||||
from django.db.models import get_model
|
||||
from django.template import (Node, TemplateSyntaxError, VariableDoesNotExist,
|
||||
FilterExpression)
|
||||
from categories.base import CategoryBase
|
||||
from categories.models import Category
|
||||
from mptt.utils import drilldown_tree_for_node
|
||||
from mptt.templatetags.mptt_tags import tree_path, tree_info
|
||||
from mptt.templatetags.mptt_tags import (tree_path, tree_info, RecurseTreeNode,
|
||||
full_tree_for_model)
|
||||
|
||||
register = template.Library()
|
||||
|
||||
register.filter("category_path", tree_path)
|
||||
register.filter(tree_info)
|
||||
register.tag("full_tree_for_category", full_tree_for_model)
|
||||
|
||||
def get_category(category_string):
|
||||
|
||||
def resolve(var, context):
|
||||
try:
|
||||
return var.resolve(context)
|
||||
except VariableDoesNotExist:
|
||||
try:
|
||||
return var.var
|
||||
except AttributeError:
|
||||
return var
|
||||
|
||||
|
||||
def get_cat_model(model):
|
||||
"""
|
||||
Return a class from a string or class
|
||||
"""
|
||||
try:
|
||||
if isinstance(model, basestring):
|
||||
model_class = get_model(*model.split("."))
|
||||
elif issubclass(model, CategoryBase):
|
||||
model_class = model
|
||||
if model_class is None:
|
||||
raise TypeError
|
||||
except TypeError:
|
||||
raise TemplateSyntaxError("Unknown model submitted: %s" % model)
|
||||
return model_class
|
||||
|
||||
|
||||
def get_category(category_string, model=Category):
|
||||
"""
|
||||
Convert a string, including a path, and return the Category object
|
||||
"""
|
||||
if category_string.startswith('"') and category_string.endswith('"'):
|
||||
category = category_string[1:-1]
|
||||
else:
|
||||
category = category_string
|
||||
|
||||
if category.startswith('/'):
|
||||
category = category[1:]
|
||||
if category.endswith('/'):
|
||||
category = category[:-1]
|
||||
model_class = get_cat_model(model)
|
||||
category = category_string.strip("'\"")
|
||||
category = category.strip('/')
|
||||
|
||||
cat_list = category.split('/')
|
||||
if len(cat_list) == 0:
|
||||
return None
|
||||
try:
|
||||
categories = Category.objects.filter(name = cat_list[-1], level=len(cat_list)-1)
|
||||
categories = model_class.objects.filter(name=cat_list[-1],
|
||||
level=len(cat_list) - 1)
|
||||
if len(cat_list) == 1 and len(categories) > 1:
|
||||
return None
|
||||
# If there is only one, use it. If there is more than one, check
|
||||
|
|
@ -40,30 +65,32 @@ def get_category(category_string):
|
|||
for item in categories:
|
||||
if item.parent.name == cat_list[-2]:
|
||||
return item
|
||||
except Category.DoesNotExist:
|
||||
except model_class.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
class CategoryDrillDownNode(template.Node):
|
||||
|
||||
def __init__(self, category, varname):
|
||||
self.category = template.Variable(category)
|
||||
def __init__(self, category, varname, model):
|
||||
self.category = category
|
||||
self.varname = varname
|
||||
self.model = model
|
||||
|
||||
def render(self, context):
|
||||
category = resolve(self.category, context)
|
||||
if isinstance(category, CategoryBase):
|
||||
cat = category
|
||||
else:
|
||||
cat = get_category(category, self.model)
|
||||
try:
|
||||
category = self.category.resolve(context)
|
||||
except template.VariableDoesNotExist:
|
||||
category = self.category.var
|
||||
try:
|
||||
if category is not None:
|
||||
context[self.varname] = drilldown_tree_for_node(category)
|
||||
if cat is not None:
|
||||
context[self.varname] = drilldown_tree_for_node(cat)
|
||||
else:
|
||||
context[self.varname] = []
|
||||
except Category.DoesNotExist:
|
||||
except:
|
||||
context[self.varname] = []
|
||||
return ''
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_category_drilldown(parser, token):
|
||||
"""
|
||||
|
|
@ -72,11 +99,11 @@ def get_category_drilldown(parser, token):
|
|||
|
||||
Syntax::
|
||||
|
||||
{% get_category_drilldown "category name" as varname %}
|
||||
{% get_category_drilldown "category name" [using "app.Model"] as varname %}
|
||||
|
||||
Example::
|
||||
|
||||
{% get_category_drilldown "/Grandparent/Parent" as family %}
|
||||
{% get_category_drilldown "/Grandparent/Parent" [using "app.Model"] as family %}
|
||||
|
||||
or ::
|
||||
|
||||
|
|
@ -86,30 +113,44 @@ def get_category_drilldown(parser, token):
|
|||
|
||||
Grandparent, Parent, Child 1, Child 2, Child n
|
||||
"""
|
||||
bits = token.contents.split()
|
||||
bits = token.split_contents()
|
||||
error_str = '%(tagname)s tag should be in the format {%% %(tagname)s ' \
|
||||
'"category name" as varname %%}.'
|
||||
if len(bits) != 4 or bits[2] != 'as':
|
||||
raise template.TemplateSyntaxError, error_str % {'tagname': bits[0]}
|
||||
category = bits[1]
|
||||
varname = bits[3]
|
||||
return CategoryDrillDownNode(category, varname)
|
||||
'"category name" [using "app.Model"] as varname %%} or ' \
|
||||
'{%% %(tagname)s category_obj as varname %%}.'
|
||||
if len(bits) == 4:
|
||||
if bits[2] != 'as':
|
||||
raise template.TemplateSyntaxError, error_str % {'tagname': bits[0]}
|
||||
if bits[2] == 'as':
|
||||
varname = bits[3].strip("'\"")
|
||||
model = "categories.category"
|
||||
if len(bits) == 6:
|
||||
if bits[2] not in ('using', 'as') or bits[4] not in ('using', 'as'):
|
||||
raise template.TemplateSyntaxError, error_str % {'tagname': bits[0]}
|
||||
if bits[2] == 'as':
|
||||
varname = bits[3].strip("'\"")
|
||||
model = bits[5].strip("'\"")
|
||||
if bits[2] == 'using':
|
||||
varname = bits[5].strip("'\"")
|
||||
model = bits[3].strip("'\"")
|
||||
category = FilterExpression(bits[1], parser)
|
||||
return CategoryDrillDownNode(category, varname, model)
|
||||
|
||||
|
||||
@register.inclusion_tag('categories/breadcrumbs.html')
|
||||
def breadcrumbs(category,separator="/"):
|
||||
def breadcrumbs(category_string, separator=' > ', using='categories.category'):
|
||||
"""
|
||||
{% breadcrumbs category separator="::" using="categories.category" %}
|
||||
|
||||
Render breadcrumbs, using the ``categories/breadcrumbs.html`` template,
|
||||
using the optional ``separator`` argument.
|
||||
"""
|
||||
if isinstance(category, CategoryBase):
|
||||
cat = category
|
||||
else:
|
||||
cat = get_category(category)
|
||||
cat = get_category(category_string, using)
|
||||
|
||||
return {'category': cat, 'separator': separator}
|
||||
|
||||
|
||||
@register.inclusion_tag('categories/ul_tree.html')
|
||||
def display_drilldown_as_ul(category):
|
||||
def display_drilldown_as_ul(category, using='categories.Category'):
|
||||
"""
|
||||
Render the category with ancestors and children using the
|
||||
``categories/ul_tree.html`` template.
|
||||
|
|
@ -142,15 +183,12 @@ def display_drilldown_as_ul(category):
|
|||
</li>
|
||||
</ul>
|
||||
"""
|
||||
if isinstance(category, CategoryBase):
|
||||
cat = category
|
||||
else:
|
||||
cat = get_category(category)
|
||||
|
||||
cat = get_category(category, using)
|
||||
return {'category': cat, 'path': drilldown_tree_for_node(cat) or []}
|
||||
|
||||
|
||||
@register.inclusion_tag('categories/ul_tree.html')
|
||||
def display_path_as_ul(category):
|
||||
def display_path_as_ul(category, using='categories.Category'):
|
||||
"""
|
||||
Render the category with ancestors, but no children using the
|
||||
``categories/ul_tree.html`` template.
|
||||
|
|
@ -180,14 +218,18 @@ def display_path_as_ul(category):
|
|||
|
||||
return {'category': cat, 'path': cat.get_ancestors() or []}
|
||||
|
||||
|
||||
class TopLevelCategoriesNode(template.Node):
|
||||
def __init__(self, varname):
|
||||
def __init__(self, varname, model):
|
||||
self.varname = varname
|
||||
self.model = model
|
||||
|
||||
def render(self, context):
|
||||
context[self.varname] = Category.objects.filter(parent=None).order_by('name')
|
||||
model = get_cat_model(self.model)
|
||||
context[self.varname] = model.objects.filter(parent=None).order_by('name')
|
||||
return ''
|
||||
|
||||
|
||||
@register.tag
|
||||
def get_top_level_categories(parser, token):
|
||||
"""
|
||||
|
|
@ -195,31 +237,31 @@ def get_top_level_categories(parser, token):
|
|||
|
||||
Syntax::
|
||||
|
||||
{% get_top_level_categories as categories %}
|
||||
{% get_top_level_categories [using "app.Model"] as categories %}
|
||||
|
||||
Returns an list of categories [<category>, <category>, <category, ...]
|
||||
"""
|
||||
bits = token.contents.split()
|
||||
if len(bits) != 3:
|
||||
raise template.TemplateSyntaxError(
|
||||
"Usage: {%% %s as <variable> %%}" % bits[0]
|
||||
)
|
||||
if bits[1] != 'as':
|
||||
raise template.TemplateSyntaxError(
|
||||
"Usage: {%% %s as <variable> %%}" % bits[0]
|
||||
)
|
||||
return TopLevelCategoriesNode(bits[2])
|
||||
bits = token.split_contents()
|
||||
usage = 'Usage: {%% %s [using "app.Model"] as <variable> %%}' % bits[0]
|
||||
if len(bits) == 3:
|
||||
if bits[1] != 'as':
|
||||
raise template.TemplateSyntaxError(usage)
|
||||
varname = bits[2]
|
||||
model = "categories.category"
|
||||
elif len(bits) == 5:
|
||||
if bits[1] not in ('as', 'using') and bits[3] not in ('as', 'using'):
|
||||
raise template.TemplateSyntaxError(usage)
|
||||
if bits[1] == 'using':
|
||||
model = bits[2].strip("'\"")
|
||||
varname = bits[4].strip("'\"")
|
||||
else:
|
||||
model = bits[4].strip("'\"")
|
||||
varname = bits[2].strip("'\"")
|
||||
|
||||
def resolve(var, context):
|
||||
try:
|
||||
return var.resolve(context)
|
||||
except VariableDoesNotExist:
|
||||
try:
|
||||
return var.var
|
||||
except AttributeError:
|
||||
return var
|
||||
return TopLevelCategoriesNode(varname, model)
|
||||
|
||||
def get_latest_objects_by_category(category, app_label, model_name, set_name,
|
||||
|
||||
def get_latest_objects_by_category(category, app_label, model_name, set_name,
|
||||
date_field='pub_date', num=15):
|
||||
m = get_model(app_label, model_name)
|
||||
if not isinstance(category, CategoryBase):
|
||||
|
|
@ -229,79 +271,75 @@ def get_latest_objects_by_category(category, app_label, model_name, set_name,
|
|||
for cat in list(children) + [category]:
|
||||
if hasattr(cat, '%s_set' % set_name):
|
||||
ids.extend([x.pk for x in getattr(cat, '%s_set' % set_name).all()[:num]])
|
||||
|
||||
|
||||
return m.objects.filter(pk__in=ids).order_by('-%s' % date_field)[:num]
|
||||
|
||||
|
||||
class LatestObjectsNode(Node):
|
||||
def __init__(self, var_name, category, app_label, model_name, set_name,
|
||||
def __init__(self, var_name, category, app_label, model_name, set_name,
|
||||
date_field='pub_date', num=15):
|
||||
"""Get latest objects of app_label.model_name"""
|
||||
self.category = Variable(category)
|
||||
self.app_label = Variable(app_label)
|
||||
self.model_name = Variable(model_name)
|
||||
self.set_name = Variable(set_name)
|
||||
self.date_field = Variable(date_field)
|
||||
self.num = Variable(num)
|
||||
"""
|
||||
Get latest objects of app_label.model_name
|
||||
"""
|
||||
self.category = category
|
||||
self.app_label = app_label
|
||||
self.model_name = model_name
|
||||
self.set_name = set_name
|
||||
self.date_field = date_field
|
||||
self.num = num
|
||||
self.var_name = var_name
|
||||
|
||||
def get_cache_key(self, category, app_label, model_name, set_name,
|
||||
date_field, num):
|
||||
"""Get the cache key"""
|
||||
key = 'latest_objects.%s' % '.'.join([category, app_label, model_name,
|
||||
set_name, date_field, num])
|
||||
|
||||
|
||||
def render(self, context):
|
||||
"""Render this sucker"""
|
||||
"""
|
||||
Render this sucker
|
||||
"""
|
||||
category = resolve(self.category, context)
|
||||
app_label = resolve(self.app_label, context)
|
||||
model_name = resolve(self.model_name, context)
|
||||
set_name = resolve(self.set_name, context)
|
||||
date_field = resolve(self.date_field, context)
|
||||
num = resolve(self.num, context)
|
||||
|
||||
cache_key = self.get_cache_key(category, app_label, model_name, set_name,
|
||||
date_field, num)
|
||||
result = cache.get(cache_key)
|
||||
if not result:
|
||||
result = get_latest_objects_by_category(category, app_label, model_name,
|
||||
|
||||
result = get_latest_objects_by_category(category, app_label, model_name,
|
||||
set_name, date_field, num)
|
||||
|
||||
cache.set(key, result, 300)
|
||||
context[self.var_name] = result
|
||||
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def do_get_latest_objects_by_category(parser, token):
|
||||
"""
|
||||
Get the latest objects by category
|
||||
|
||||
|
||||
{% get_latest_objects_by_category category app_name model_name set_name [date_field] [number] as [var_name] %}
|
||||
"""
|
||||
proper_form = "{% get_latest_objects_by_category category app_name model_name set_name [date_field] [number] as [var_name] %}"
|
||||
bits = token.split_contents()
|
||||
|
||||
|
||||
if bits[-2] != 'as':
|
||||
raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
|
||||
if len(bits) < 7:
|
||||
raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
|
||||
if len(bits) > 9:
|
||||
raise TemplateSyntaxError("%s tag shoud be in the form: %s" % (bits[0], proper_form))
|
||||
category = bits[1]
|
||||
app_label = bits[2]
|
||||
model_name = bits[3]
|
||||
set_name = bits[4]
|
||||
category = FilterExpression(bits[1], parser)
|
||||
app_label = FilterExpression(bits[2], parser)
|
||||
model_name = FilterExpression(bits[3], parser)
|
||||
set_name = FilterExpression(bits[4], parser)
|
||||
var_name = bits[-1]
|
||||
if bits[5] != 'as':
|
||||
date_field = bits[5]
|
||||
date_field = FilterExpression(bits[5], parser)
|
||||
else:
|
||||
date_field = None
|
||||
date_field = FilterExpression(None, parser)
|
||||
if bits[6] != 'as':
|
||||
num = bits[6]
|
||||
num = FilterExpression(bits[6], parser)
|
||||
else:
|
||||
num = None
|
||||
return LatestObjectsNode(var_name, category, app_label, model_name, set_name,
|
||||
num = FilterExpression(None, parser)
|
||||
return LatestObjectsNode(var_name, category, app_label, model_name, set_name,
|
||||
date_field, num)
|
||||
|
||||
register.tag("get_latest_objects_by_category", do_get_latest_objects_by_category)
|
||||
|
||||
|
||||
@register.filter
|
||||
def tree_queryset(value):
|
||||
|
|
@ -313,7 +351,7 @@ def tree_queryset(value):
|
|||
from copy import deepcopy
|
||||
if not isinstance(value, QuerySet):
|
||||
return value
|
||||
|
||||
|
||||
qs = value
|
||||
qs2 = deepcopy(qs)
|
||||
# Reaching into the bowels of query sets to find out whether the qs is
|
||||
|
|
@ -331,9 +369,41 @@ def tree_queryset(value):
|
|||
p.id not in include_pages:
|
||||
ancestor_id_list = p.get_ancestors().values_list('id', flat=True)
|
||||
include_pages.update(ancestor_id_list)
|
||||
|
||||
|
||||
if include_pages:
|
||||
qs = qs | qs.model._default_manager.filter(id__in=include_pages)
|
||||
|
||||
|
||||
qs = qs.distinct()
|
||||
return qs
|
||||
return qs
|
||||
|
||||
|
||||
@register.tag
|
||||
def recursetree(parser, token):
|
||||
"""
|
||||
Iterates over the nodes in the tree, and renders the contained block for each node.
|
||||
This tag will recursively render children into the template variable {{ children }}.
|
||||
Only one database query is required (children are cached for the whole tree)
|
||||
|
||||
Usage:
|
||||
<ul>
|
||||
{% recursetree nodes %}
|
||||
<li>
|
||||
{{ node.name }}
|
||||
{% if not node.is_leaf_node %}
|
||||
<ul>
|
||||
{{ children }}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endrecursetree %}
|
||||
</ul>
|
||||
"""
|
||||
bits = token.contents.split()
|
||||
if len(bits) != 2:
|
||||
raise template.TemplateSyntaxError('%s tag requires a queryset' % bits[0])
|
||||
queryset_var = FilterExpression(bits[1], parser)
|
||||
|
||||
template_nodes = parser.parse(('endrecursetree',))
|
||||
parser.delete_first_token()
|
||||
|
||||
return RecurseTreeNode(template_nodes, queryset_var)
|
||||
|
|
|
|||
|
|
@ -1,64 +1,62 @@
|
|||
# test spaces in hierarchy
|
||||
# test tabs in hierarchy
|
||||
# test mixed
|
||||
import unittest, os
|
||||
import unittest
|
||||
import os
|
||||
from categories.models import Category
|
||||
from categories.management.commands.import_categories import Command
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
|
||||
class CategoryImportTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
|
||||
def _import_file(self, filename):
|
||||
root_cats = ['Category 1', 'Category 2', 'Category 3']
|
||||
testfile = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures', filename))
|
||||
cmd = Command()
|
||||
cmd.execute(testfile)
|
||||
roots = Category.tree.root_nodes()
|
||||
|
||||
|
||||
self.assertEqual(len(roots), 3)
|
||||
for item in roots:
|
||||
assert item.name in root_cats
|
||||
|
||||
|
||||
cat2 = Category.objects.get(name='Category 2')
|
||||
cat21 = cat2.children.all()[0]
|
||||
self.assertEqual(cat21.name, 'Category 2-1')
|
||||
cat211 = cat21.children.all()[0]
|
||||
self.assertEqual(cat211.name, 'Category 2-1-1')
|
||||
|
||||
|
||||
|
||||
def testImportSpaceDelimited(self):
|
||||
Category.objects.all().delete()
|
||||
self._import_file('test_category_spaces.txt')
|
||||
|
||||
|
||||
items = Category.objects.all()
|
||||
|
||||
|
||||
self.assertEqual(items[0].name, 'Category 1')
|
||||
self.assertEqual(items[1].name, 'Category 1-1')
|
||||
self.assertEqual(items[2].name, 'Category 1-2')
|
||||
|
||||
|
||||
|
||||
def testImportTabDelimited(self):
|
||||
Category.objects.all().delete()
|
||||
self._import_file('test_category_tabs.txt')
|
||||
|
||||
|
||||
items = Category.objects.all()
|
||||
|
||||
|
||||
self.assertEqual(items[0].name, 'Category 1')
|
||||
self.assertEqual(items[1].name, 'Category 1-1')
|
||||
self.assertEqual(items[2].name, 'Category 1-2')
|
||||
|
||||
|
||||
|
||||
def testMixingTabsSpaces(self):
|
||||
"""
|
||||
Should raise an exception.
|
||||
"""
|
||||
string1 = ["cat1"," cat1-1", "\tcat1-2-FAIL!",""]
|
||||
string2 = ["cat1","\tcat1-1"," cat1-2-FAIL!",""]
|
||||
string1 = ["cat1", " cat1-1", "\tcat1-2-FAIL!", ""]
|
||||
string2 = ["cat1", "\tcat1-1", " cat1-2-FAIL!", ""]
|
||||
cmd = Command()
|
||||
|
||||
|
||||
# raise Exception
|
||||
self.assertRaises(CommandError, cmd.parse_lines, string1)
|
||||
self.assertRaises(CommandError, cmd.parse_lines, string2)
|
||||
|
||||
|
|
@ -1,23 +1,22 @@
|
|||
# test active returns only active items
|
||||
import unittest, os
|
||||
import unittest
|
||||
from categories.models import Category
|
||||
from categories.management.commands.import_categories import Command
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
|
||||
class CategoryManagerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
|
||||
def testActive(self):
|
||||
"""
|
||||
Should raise an exception.
|
||||
"""
|
||||
all_count = Category.objects.all().count()
|
||||
self.assertEqual(Category.objects.active().count(), all_count)
|
||||
|
||||
|
||||
cat1 = Category.objects.get(name='Category 1')
|
||||
cat1.active = False
|
||||
cat1.save()
|
||||
|
||||
|
||||
active_count = all_count - cat1.get_descendants(True).count()
|
||||
self.assertEqual(Category.objects.active().count(), active_count)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
from django.test import TestCase
|
||||
from django import template
|
||||
|
||||
from categories.models import Category
|
||||
|
||||
|
||||
class CategoryTagsTest(TestCase):
|
||||
|
||||
class GetCategoryTest(TestCase):
|
||||
|
||||
fixtures = ['musicgenres.json']
|
||||
|
||||
|
||||
def render_template(self, template_string, context={}):
|
||||
"""
|
||||
Return the rendered string or raise an exception.
|
||||
|
|
@ -16,27 +18,50 @@ class GetCategoryTest(TestCase):
|
|||
|
||||
def testTooFewArguments(self):
|
||||
"""
|
||||
Ensure that get_cateogry raises an exception if there aren't enough arguments.
|
||||
Ensure that get_category raises an exception if there aren't enough arguments.
|
||||
"""
|
||||
self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category %}')
|
||||
|
||||
def testTooManyArguments(self):
|
||||
"""
|
||||
Ensure that get_category raises an exception if there are too many arguments.
|
||||
"""
|
||||
self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category "/Rock" as too many arguments %}')
|
||||
|
||||
def testAsIsSecondArgument(self):
|
||||
"""
|
||||
Test that the second argument to get_category is 'as'.
|
||||
"""
|
||||
self.assertRaises(template.TemplateSyntaxError, self.render_template, '{% load category_tags %}{% get_category "Rock" notas rock %}')
|
||||
|
||||
def testBasicUsage(self):
|
||||
"""
|
||||
Test that we can properly retrieve a category.
|
||||
"""
|
||||
rock_resp = u'\n<ul><li><a href="/categories/">Top</a>\n</li></ul>'
|
||||
# display_path_as_ul
|
||||
rock_resp = u'<ul><li><a href="/categories/">Top</a></li></ul>'
|
||||
resp = self.render_template('{% load category_tags %}{% display_path_as_ul "/Rock" %}')
|
||||
self.assertEqual(resp, rock_resp)
|
||||
|
||||
|
||||
# display_drilldown_as_ul
|
||||
expected_resp = u'<ul><li><a href="/categories/">Top</a><ul><li><a href="/categories/world/">World</a><ul><li><strong>Worldbeat</strong><ul><li><a href="/categories/world/worldbeat/afrobeat/">Afrobeat</a></li></ul></li></ul></li></ul></li></ul>'
|
||||
resp = self.render_template('{% load category_tags %}'
|
||||
'{% display_drilldown_as_ul "/World/Worldbeat" using="categories.category" %}')
|
||||
self.assertEqual(resp, expected_resp)
|
||||
|
||||
# breadcrumbs
|
||||
expected_resp = u'<a href="/categories/world/">World</a> > Worldbeat'
|
||||
resp = self.render_template('{% load category_tags %}'
|
||||
'{% breadcrumbs "/World/Worldbeat" using="categories.category" %}')
|
||||
self.assertEqual(resp, expected_resp)
|
||||
|
||||
# get_top_level_categories
|
||||
expected_resp = u'Avant-garde|Blues|Country|Easy listening|Electronic|Hip hop/Rap music|Jazz|Latin|Modern folk|Pop|Reggae|Rhythm and blues|Rock|World|'
|
||||
resp = self.render_template('{% load category_tags %}'
|
||||
'{% get_top_level_categories using "categories.category" as varname %}'
|
||||
'{% for item in varname %}{{ item }}|{% endfor %}')
|
||||
self.assertEqual(resp, expected_resp)
|
||||
|
||||
# get_category_drilldown
|
||||
expected_resp = u"World|World > Worldbeat|"
|
||||
resp = self.render_template('{% load category_tags %}'
|
||||
'{% get_category_drilldown "/World" using "categories.category" as var %}'
|
||||
'{% for item in var %}{{ item }}|{% endfor %}')
|
||||
self.assertEqual(resp, expected_resp)
|
||||
|
||||
# recursetree
|
||||
expected_resp = u'<ul><li>Country<ul><li>Country pop<ul><li>Urban Cowboy</li></ul></li></ul></li><li>World<ul><li>Worldbeat<ul></ul></li></ul></li></ul>'
|
||||
ctxt = {'nodes': Category.objects.filter(name__in=("Worldbeat", "Urban Cowboy"))}
|
||||
resp = self.render_template('{% load category_tags %}'
|
||||
'<ul>{% recursetree nodes|tree_queryset %}<li>{{ node.name }}'
|
||||
'{% if not node.is_leaf_node %}<ul>{{ children }}'
|
||||
'</ul>{% endif %}</li>{% endrecursetree %}</ul>', ctxt)
|
||||
self.assertEqual(resp, expected_resp)
|
||||
|
|
|
|||
|
|
@ -13,4 +13,4 @@ urlpatterns = patterns('django.views.generic.list_detail',
|
|||
|
||||
urlpatterns += patterns('categories.views',
|
||||
url(r'^(?P<path>.+)/$', 'category_detail', name='categories_category'),
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,21 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from .models import Category
|
||||
from .settings import CACHE_VIEW_LENGTH
|
||||
|
||||
|
||||
@cache_page(CACHE_VIEW_LENGTH)
|
||||
def category_detail(request, path,
|
||||
def category_detail(request, path,
|
||||
template_name='categories/category_detail.html', extra_context={}):
|
||||
path_items = path.strip('/').split('/')
|
||||
if len(path_items) >= 2:
|
||||
category = get_object_or_404(Category,
|
||||
slug__iexact = path_items[-1],
|
||||
level = len(path_items)-1,
|
||||
slug__iexact=path_items[-1],
|
||||
level=len(path_items) - 1,
|
||||
parent__slug__iexact=path_items[-2])
|
||||
else:
|
||||
category = get_object_or_404(Category,
|
||||
slug__iexact = path_items[-1],
|
||||
level = len(path_items)-1)
|
||||
|
||||
slug__iexact=path_items[-1],
|
||||
level=len(path_items) - 1)
|
||||
|
||||
templates = []
|
||||
while path_items:
|
||||
templates.append('categories/%s.html' % '_'.join(path_items))
|
||||
|
|
@ -31,7 +32,7 @@ def category_detail(request, path,
|
|||
templates.append(template_name)
|
||||
|
||||
context = RequestContext(request)
|
||||
context.update({'category':category})
|
||||
context.update({'category': category})
|
||||
if extra_context:
|
||||
context.update(extra_context)
|
||||
return HttpResponse(select_template(templates).render(context))
|
||||
|
|
@ -41,13 +42,13 @@ def get_category_for_path(path, queryset=Category.objects.all()):
|
|||
path_items = path.strip('/').split('/')
|
||||
if len(path_items) >= 2:
|
||||
queryset = queryset.filter(
|
||||
slug__iexact = path_items[-1],
|
||||
level = len(path_items)-1,
|
||||
slug__iexact=path_items[-1],
|
||||
level=len(path_items) - 1,
|
||||
parent__slug__iexact=path_items[-2])
|
||||
else:
|
||||
queryset = queryset.filter(
|
||||
slug__iexact = path_items[-1],
|
||||
level = len(path_items)-1)
|
||||
slug__iexact=path_items[-1],
|
||||
level=len(path_items) - 1)
|
||||
return queryset.get()
|
||||
|
||||
try:
|
||||
|
|
@ -72,13 +73,13 @@ if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV):
|
|||
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()
|
||||
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})
|
||||
|
||||
|
||||
def get_template_names(self):
|
||||
names = []
|
||||
path_items = self.kwargs[self.path_field].strip('/').split('/')
|
||||
|
|
@ -88,16 +89,14 @@ if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV):
|
|||
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])
|
||||
return queryset.get(category=category, slug=self.kwargs[self.slug_field])
|
||||
|
||||
def get_template_names(self):
|
||||
names = []
|
||||
|
|
@ -106,22 +105,22 @@ if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV):
|
|||
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)
|
||||
)
|
||||
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.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):
|
||||
|
|
@ -135,15 +134,17 @@ if ((django.VERSION[0] >= 1 and django.VERSION[1] >= 3) or HAS_CBV):
|
|||
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)
|
||||
)
|
||||
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.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
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ div.clearer {
|
|||
.headerButton a:hover {
|
||||
color: white;
|
||||
background-color: #787878;
|
||||
|
||||
|
||||
}
|
||||
|
||||
li#toc_button {
|
||||
|
|
@ -121,7 +121,7 @@ right:0;
|
|||
top: 84px;
|
||||
bottom: 19px;
|
||||
left: 0px;
|
||||
width: 229px;
|
||||
width: 229px;
|
||||
background-color: #E4EBF7;
|
||||
border-right: 1px solid #ACACAC;
|
||||
border-top: 1px solid #2B334F;
|
||||
|
|
@ -362,7 +362,7 @@ p.topic-title {
|
|||
border:1px solid #111111;
|
||||
margin:30px;
|
||||
}
|
||||
.admonition p {
|
||||
.admonition p {
|
||||
font: 12px 'Lucida Grande', Geneva, Helvetica, Arial, sans-serif;
|
||||
margin-top: 7px;
|
||||
margin-bottom: 0px;
|
||||
|
|
@ -411,7 +411,7 @@ table.docutils td, table.docutils th {
|
|||
table.docutils th {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* This alternates colors in up to six table rows (light blue for odd, white for even)*/
|
||||
/* This alternates colors in up to six table rows (light blue for odd, white for even)*/
|
||||
.docutils tr {
|
||||
background: #F0F5F9;
|
||||
}
|
||||
|
|
@ -453,6 +453,7 @@ th {
|
|||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
dd p {
|
||||
|
|
@ -544,7 +545,7 @@ td.linenos pre {
|
|||
}
|
||||
|
||||
td.code {
|
||||
|
||||
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
|
|
@ -562,7 +563,6 @@ table.highlighttable td.linenos {
|
|||
}
|
||||
tt {
|
||||
font-family:"Bitstream Vera Sans Mono",Monaco,"Lucida Console",Courier,Consolas,monospace;
|
||||
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
|
|
@ -643,7 +643,7 @@ dl.class dd dl.method dt {
|
|||
padding: 3px;
|
||||
background-color: #e9e9e9;
|
||||
border-top: none;
|
||||
|
||||
|
||||
}
|
||||
|
||||
dl.function dt {
|
||||
|
|
@ -659,7 +659,7 @@ margin:0 0 0 30px;
|
|||
padding:0 0 12px 6px;
|
||||
}
|
||||
#docstitle {
|
||||
height: 36px;
|
||||
height: 36px;
|
||||
background-image: url(header_sm_mid.png);
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ For many cases, you want a simple user-managed lookup table. You can do this wit
|
|||
|
||||
#. Create a subclass of CategoryBaseAdmin.
|
||||
|
||||
.. literalinclude:: code_examples/custom_categories1.py
|
||||
.. literalinclude:: code_examples/custom_categories2.py
|
||||
:linenos:
|
||||
|
||||
#. Register your model and custom model admin class.
|
||||
|
|
|
|||
|
|
@ -6,27 +6,17 @@ 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.0
|
||||
New in 1.1
|
||||
==========
|
||||
|
||||
**Abstract Base Class for generic hierarchical category models**
|
||||
When you want a multiple types of categories and don't want them all part of the same model, you can now easily create new models by subclassing ``CategoryBase``. You can also add additional metadata as necessary.
|
||||
|
||||
Your model's can subclass ``CategoryBaseAdminForm`` and ``CategoryBaseAdmin`` to get the hierarchical management in the admin.
|
||||
|
||||
See the docs for more information.
|
||||
* Fixed a cosmetic bug in the Django 1.4 admin. Action checkboxes now only appear once.
|
||||
|
||||
**Increased the default caching time on views**
|
||||
The default setting for ``CACHE_VIEW_LENGTH`` was ``0``, which means it would tell the browser to *never* cache the page. It is now ``600``, which is the default for `CACHE_MIDDLEWARE_SECONDS <https://docs.djangoproject.com/en/1.3/ref/settings/#cache-middleware-seconds>`_
|
||||
* Template tags are refactored to allow easy use of any model derived from ``CategoryBase``.
|
||||
|
||||
**Updated for use with Django-MPTT 0.5**
|
||||
Just a few tweaks.
|
||||
* Improved test suite.
|
||||
|
||||
**Initial compatibility with Django 1.4**
|
||||
More is coming, but at least it works.
|
||||
* Improved some of the documentation.
|
||||
|
||||
**Slug transliteration for non-ASCII characters**
|
||||
A new setting, ``SLUG_TRANSLITERATOR``, allows you to specify a function for converting the non-ASCII characters to ASCII characters before the slugification. Works great with `Unidecode <http://pypi.python.org/pypi/Unidecode>`_.
|
||||
|
||||
|
||||
Contents
|
||||
|
|
|
|||
|
|
@ -1,33 +1,146 @@
|
|||
=============
|
||||
Template Tags
|
||||
=============
|
||||
=========================
|
||||
Template tags and filters
|
||||
=========================
|
||||
|
||||
get_top_level_categories
|
||||
========================
|
||||
.. contents::
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: top
|
||||
|
||||
Retrieves an alphabetical list of all the categories that have no parents.
|
||||
|
||||
Syntax:
|
||||
Filters
|
||||
=======
|
||||
|
||||
|
||||
``category_path``
|
||||
-----------------
|
||||
|
||||
**Optional Parameter:** separator string. *Default:* ``" :: "``
|
||||
|
||||
Creates a path represented by a categories by joining the items with a separator.
|
||||
|
||||
Each path item will be coerced to unicode, so you can pass a list of category instances, if required.
|
||||
|
||||
**Example using a list of categories:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_top_level_categories as categories %}
|
||||
{{ some_list|category_path }}
|
||||
|
||||
Returns an list of categories ``[<category>, <category>, <category, ...]``
|
||||
If ``some_list`` is ``[ <Category: Country>, <Category: Country pop>, <Category: Urban Cowboy>]`` the result will be::
|
||||
|
||||
Country :: Country pop :: Urban Cowboy
|
||||
|
||||
**Example using a category node and optional separator parameter:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{{ some_node.get_ancestors|category_path:" > " }}
|
||||
|
||||
If ``some_node`` was category "Urban Cowboy", the result will be::
|
||||
|
||||
Country > Country pop > Urban Cowboy
|
||||
|
||||
.. _tree_info:
|
||||
|
||||
``tree_info``
|
||||
-------------
|
||||
|
||||
**Optional Parameter:** ``"ancestors"``
|
||||
|
||||
Given a list of categories, it iterates over the list, generating a tuple of the current category and a dict containing information about the tree structure around it, with the following keys:
|
||||
|
||||
``'new_level'``
|
||||
``True`` if the current item is the start of a new level in the tree, ``False`` otherwise.
|
||||
|
||||
``'closed_levels'``
|
||||
A list of levels which end after the current item. This will be an empty list if the next category's level is the same as or greater than the level of the current item.
|
||||
|
||||
Provide the optional argument, ``"ancestors"``, to add a list of unicode representations of the ancestors of the current category, in descending order (root node first, immediate parent last), under the key 'ancestors'.
|
||||
|
||||
For example: given the sample tree below, the contents of the list which would be available under the 'ancestors' key are given on the right::
|
||||
|
||||
Country -> []
|
||||
Country pop -> [u'Country pop']
|
||||
Urban Cowboy -> [u'Country', u'Country pop']
|
||||
|
||||
Using this filter with unpacking in a {% for %} tag, you should have enough information about the tree structure to create a hierarchical representation of the tree.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% for node,structure in objects|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
|
||||
{{ node.name }}
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
``tree_queryset``
|
||||
-----------------
|
||||
|
||||
Convert a regular category :py:class:`QuerySet` into a new, ordered :py:class:`QuerySet` that includes the categories selected and their ancestors.
|
||||
|
||||
This is especially helpful when you have a subset of categories and want to show the hierarchy for all the items.
|
||||
|
||||
For example, if we add it to the example for :ref:`tree_info`:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% for node,structure in objects|tree_queryset|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
|
||||
{{ node.name }}
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
A list of unrelated categories such as ``[<Category: Urban cowboy>, <Category: Urban comtemporary>]``, the above template example will output the two categories and their ancestors:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<ul><li>
|
||||
Country
|
||||
<ul><li>
|
||||
Country pop
|
||||
<ul><li>
|
||||
Urban cowboy
|
||||
</li></ul></li></ul></li></ul>
|
||||
<ul><li>
|
||||
Rhythm and blues
|
||||
<ul><li>
|
||||
Urban contemporary
|
||||
</li></ul></li></ul>
|
||||
|
||||
.. note::
|
||||
Categories that have similar ancestors are grouped accordingly. There is no duplication of the ancestor tree.
|
||||
|
||||
|
||||
display_path_as_ul
|
||||
==================
|
||||
Inclusion tags
|
||||
==============
|
||||
|
||||
Render the category with ancestors, but no children using the ``categories/ul_tree.html`` template.
|
||||
``display_path_as_ul``
|
||||
----------------------
|
||||
|
||||
Example:
|
||||
**Template Rendered:** ``categories/ul_tree.html``
|
||||
|
||||
**Syntax 1:** ``{% display_path_as_ul <category_obj> %}``
|
||||
|
||||
**Syntax 2:** ``{% display_path_as_ul <path_string>[ using="app.Model"] %}``
|
||||
|
||||
Render the category with ancestors, but no children.
|
||||
|
||||
Pass either an object that subclasses :py:class:`CategoryBase` or a path string for the category. Add ``using="app.Model"`` to specify which model when using a path string. The default model used is :py:class:`Category`.
|
||||
|
||||
**Example, using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_path_as_ul "/Grandparent/Parent" %}
|
||||
|
||||
or
|
||||
**Example, using custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_path_as_ul "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example, using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -37,51 +150,39 @@ Returns:
|
|||
|
||||
.. code-block:: html
|
||||
|
||||
<ul>
|
||||
<li><a href="/categories/">Top</a>
|
||||
<ul>
|
||||
<li><a href="/categories/grandparent/">Grandparent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="/categories/">Top</a>
|
||||
<ul>
|
||||
<li><a href="/categories/grandparent/">Grandparent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
get_category_drilldown
|
||||
======================
|
||||
``display_drilldown_as_ul``
|
||||
---------------------------
|
||||
|
||||
Retrieves the specified category, its ancestors and its immediate children
|
||||
as an iterable.
|
||||
**Template rendered:** ``categories/ul_tree.html``
|
||||
|
||||
Example:
|
||||
**Syntax 1:** ``{% display_drilldown_as_ul category_obj %}``
|
||||
|
||||
.. code-block:: django
|
||||
**Syntax 2:** ``{% display_drilldown_as_ul "/Grandparent/Parent" [using="app.Model"] %}``
|
||||
|
||||
{% get_category_drilldown "/Grandparent/Parent" as family %}
|
||||
Render the category with ancestors and children.
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown category_obj as family %}
|
||||
|
||||
Sets ``family`` to::
|
||||
|
||||
[Grandparent, Parent, Child 1, Child 2, Child n]
|
||||
|
||||
|
||||
display_drilldown_as_ul
|
||||
=======================
|
||||
|
||||
Render the category with ancestors and children using the
|
||||
``categories/ul_tree.html`` template.
|
||||
|
||||
Example:
|
||||
**Example, using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_drilldown_as_ul "/Grandparent/Parent" %}
|
||||
|
||||
or:
|
||||
**Example, using custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_drilldown_as_ul "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example, using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -110,18 +211,30 @@ Returns:
|
|||
</ul>
|
||||
|
||||
|
||||
breadcrumbs tag
|
||||
===============
|
||||
``breadcrumbs tag``
|
||||
-------------------
|
||||
|
||||
Render breadcrumbs, using the ``categories/breadcrumbs.html`` template, using the optional ``separator`` argument.
|
||||
**Template rendered:** ``categories/breadcrumbs.html``
|
||||
|
||||
Example:
|
||||
**Syntax 1:** ``{% breadcrumbs category_obj [separator=" :: "] %}``
|
||||
|
||||
**Syntax 2:** ``{% breadcrumbs "/Grandparent/Parent" [separator=" :: "] [using="app.Model"] %}``
|
||||
|
||||
Render breadcrumbs for the given path using ``::`` or the given separator.
|
||||
|
||||
**Example using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs "/Grandparent/Parent" %}
|
||||
|
||||
or:
|
||||
**Example using a custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -133,14 +246,103 @@ Returns:
|
|||
|
||||
<a href="/categories/grandparent/">Grandparent</a> / Parent
|
||||
|
||||
You can alter the separator used in the template by adding a string argument to be the separator:
|
||||
You can alter the separator used in the template by adding a separator argument:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs category_obj "::" %}
|
||||
{% breadcrumbs category_obj separator=" > " %}
|
||||
|
||||
Returns:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<a href="/categories/grandparent/">Grandparent</a> :: Parent
|
||||
<a href="/categories/grandparent/">Grandparent</a> > Parent
|
||||
|
||||
|
||||
Template Tags
|
||||
=============
|
||||
|
||||
``get_top_level_categories``
|
||||
----------------------------
|
||||
|
||||
Retrieves an alphabetical list of all the categories that have no parents.
|
||||
|
||||
Syntax:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_top_level_categories [using "app.Model"] as categories %}
|
||||
|
||||
Returns an list of categories ``[<category>, <category>, <category, ...]``
|
||||
|
||||
|
||||
``get_category_drilldown``
|
||||
--------------------------
|
||||
|
||||
**Syntax 1:** ``{% get_category_drilldown <path_string> [using "app.Model"] as <varname> %}``
|
||||
|
||||
**Syntax 2:** ``{% get_category_drilldown <object> as <varname> %}``
|
||||
|
||||
Retrieves the specified category, its ancestors and its immediate children as an iterable. Syntax 1 allows for the retrieval of the category object via a slash-delimited path. The optional ``using "app.Model"`` allows you to specify from which model to retrieve the object.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown "/Grandparent/Parent" using "family.Member" as family %}
|
||||
|
||||
The second syntax uses an instance of any object that subclasses :py:class:`CategoryBase`
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown category_obj as family %}
|
||||
|
||||
Both examples sets ``family`` to::
|
||||
|
||||
[Grandparent, Parent, Child 1, Child 2, Child n]
|
||||
|
||||
``recursetree``
|
||||
---------------
|
||||
|
||||
This tag renders a section of your template recursively for each node in your
|
||||
tree.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
<ul class="root">
|
||||
{% recursetree nodes %}
|
||||
<li>
|
||||
{{ node.name }}
|
||||
{% if not node.is_leaf_node %}
|
||||
<ul class="children">
|
||||
{{ children }}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endrecursetree %}
|
||||
</ul>
|
||||
|
||||
Note the special variables ``node`` and ``children``.
|
||||
These are magically inserted into your context while you're inside the
|
||||
``recursetree`` tag.
|
||||
|
||||
``node`` is an instance of your MPTT model.
|
||||
|
||||
``children`` : This variable holds the rendered HTML for the children of
|
||||
``node``.
|
||||
|
||||
.. note::
|
||||
If you already have variables called ``node`` or ``children`` in your
|
||||
template, and you need to access them inside the ``recursetree`` block,
|
||||
you'll need to alias them to some other name first:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% with node as friendly_node %}
|
||||
{% recursetree nodes %}
|
||||
{{ node.name }} is friends with {{ friendly_node.name }}
|
||||
{{ children }}
|
||||
{% endrecursetree %}
|
||||
{% endwith %}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ For many cases, you want a simple user-managed lookup table. You can do this wit
|
|||
|
||||
#. Create a subclass of CategoryBaseAdmin.
|
||||
|
||||
.. literalinclude:: code_examples/custom_categories1.py
|
||||
.. literalinclude:: code_examples/custom_categories2.py
|
||||
:linenos:
|
||||
|
||||
#. Register your model and custom model admin class.
|
||||
|
|
|
|||
|
|
@ -6,27 +6,17 @@ 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.0
|
||||
New in 1.1
|
||||
==========
|
||||
|
||||
**Abstract Base Class for generic hierarchical category models**
|
||||
When you want a multiple types of categories and don't want them all part of the same model, you can now easily create new models by subclassing ``CategoryBase``. You can also add additional metadata as necessary.
|
||||
|
||||
Your model's can subclass ``CategoryBaseAdminForm`` and ``CategoryBaseAdmin`` to get the hierarchical management in the admin.
|
||||
|
||||
See the docs for more information.
|
||||
* Fixed a cosmetic bug in the Django 1.4 admin. Action checkboxes now only appear once.
|
||||
|
||||
**Increased the default caching time on views**
|
||||
The default setting for ``CACHE_VIEW_LENGTH`` was ``0``, which means it would tell the browser to *never* cache the page. It is now ``600``, which is the default for `CACHE_MIDDLEWARE_SECONDS <https://docs.djangoproject.com/en/1.3/ref/settings/#cache-middleware-seconds>`_
|
||||
* Template tags are refactored to allow easy use of any model derived from ``CategoryBase``.
|
||||
|
||||
**Updated for use with Django-MPTT 0.5**
|
||||
Just a few tweaks.
|
||||
* Improved test suite.
|
||||
|
||||
**Initial compatibility with Django 1.4**
|
||||
More is coming, but at least it works.
|
||||
* Improved some of the documentation.
|
||||
|
||||
**Slug transliteration for non-ASCII characters**
|
||||
A new setting, ``SLUG_TRANSLITERATOR``, allows you to specify a function for converting the non-ASCII characters to ASCII characters before the slugification. Works great with `Unidecode <http://pypi.python.org/pypi/Unidecode>`_.
|
||||
|
||||
|
||||
Contents
|
||||
|
|
|
|||
|
|
@ -1,33 +1,146 @@
|
|||
=============
|
||||
Template Tags
|
||||
=============
|
||||
=========================
|
||||
Template tags and filters
|
||||
=========================
|
||||
|
||||
get_top_level_categories
|
||||
========================
|
||||
.. contents::
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: top
|
||||
|
||||
Retrieves an alphabetical list of all the categories that have no parents.
|
||||
|
||||
Syntax:
|
||||
Filters
|
||||
=======
|
||||
|
||||
|
||||
``category_path``
|
||||
-----------------
|
||||
|
||||
**Optional Parameter:** separator string. *Default:* ``" :: "``
|
||||
|
||||
Creates a path represented by a categories by joining the items with a separator.
|
||||
|
||||
Each path item will be coerced to unicode, so you can pass a list of category instances, if required.
|
||||
|
||||
**Example using a list of categories:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_top_level_categories as categories %}
|
||||
{{ some_list|category_path }}
|
||||
|
||||
Returns an list of categories ``[<category>, <category>, <category, ...]``
|
||||
If ``some_list`` is ``[ <Category: Country>, <Category: Country pop>, <Category: Urban Cowboy>]`` the result will be::
|
||||
|
||||
Country :: Country pop :: Urban Cowboy
|
||||
|
||||
**Example using a category node and optional separator parameter:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{{ some_node.get_ancestors|category_path:" > " }}
|
||||
|
||||
If ``some_node`` was category "Urban Cowboy", the result will be::
|
||||
|
||||
Country > Country pop > Urban Cowboy
|
||||
|
||||
.. _tree_info:
|
||||
|
||||
``tree_info``
|
||||
-------------
|
||||
|
||||
**Optional Parameter:** ``"ancestors"``
|
||||
|
||||
Given a list of categories, it iterates over the list, generating a tuple of the current category and a dict containing information about the tree structure around it, with the following keys:
|
||||
|
||||
``'new_level'``
|
||||
``True`` if the current item is the start of a new level in the tree, ``False`` otherwise.
|
||||
|
||||
``'closed_levels'``
|
||||
A list of levels which end after the current item. This will be an empty list if the next category's level is the same as or greater than the level of the current item.
|
||||
|
||||
Provide the optional argument, ``"ancestors"``, to add a list of unicode representations of the ancestors of the current category, in descending order (root node first, immediate parent last), under the key 'ancestors'.
|
||||
|
||||
For example: given the sample tree below, the contents of the list which would be available under the 'ancestors' key are given on the right::
|
||||
|
||||
Country -> []
|
||||
Country pop -> [u'Country pop']
|
||||
Urban Cowboy -> [u'Country', u'Country pop']
|
||||
|
||||
Using this filter with unpacking in a {% for %} tag, you should have enough information about the tree structure to create a hierarchical representation of the tree.
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% for node,structure in objects|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
|
||||
{{ node.name }}
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
``tree_queryset``
|
||||
-----------------
|
||||
|
||||
Convert a regular category :py:class:`QuerySet` into a new, ordered :py:class:`QuerySet` that includes the categories selected and their ancestors.
|
||||
|
||||
This is especially helpful when you have a subset of categories and want to show the hierarchy for all the items.
|
||||
|
||||
For example, if we add it to the example for :ref:`tree_info`:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% for node,structure in objects|tree_queryset|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
|
||||
{{ node.name }}
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
A list of unrelated categories such as ``[<Category: Urban cowboy>, <Category: Urban comtemporary>]``, the above template example will output the two categories and their ancestors:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<ul><li>
|
||||
Country
|
||||
<ul><li>
|
||||
Country pop
|
||||
<ul><li>
|
||||
Urban cowboy
|
||||
</li></ul></li></ul></li></ul>
|
||||
<ul><li>
|
||||
Rhythm and blues
|
||||
<ul><li>
|
||||
Urban contemporary
|
||||
</li></ul></li></ul>
|
||||
|
||||
.. note::
|
||||
Categories that have similar ancestors are grouped accordingly. There is no duplication of the ancestor tree.
|
||||
|
||||
|
||||
display_path_as_ul
|
||||
==================
|
||||
Inclusion tags
|
||||
==============
|
||||
|
||||
Render the category with ancestors, but no children using the ``categories/ul_tree.html`` template.
|
||||
``display_path_as_ul``
|
||||
----------------------
|
||||
|
||||
Example:
|
||||
**Template Rendered:** ``categories/ul_tree.html``
|
||||
|
||||
**Syntax 1:** ``{% display_path_as_ul <category_obj> %}``
|
||||
|
||||
**Syntax 2:** ``{% display_path_as_ul <path_string>[ using="app.Model"] %}``
|
||||
|
||||
Render the category with ancestors, but no children.
|
||||
|
||||
Pass either an object that subclasses :py:class:`CategoryBase` or a path string for the category. Add ``using="app.Model"`` to specify which model when using a path string. The default model used is :py:class:`Category`.
|
||||
|
||||
**Example, using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_path_as_ul "/Grandparent/Parent" %}
|
||||
|
||||
or
|
||||
**Example, using custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_path_as_ul "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example, using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -37,51 +150,39 @@ Returns:
|
|||
|
||||
.. code-block:: html
|
||||
|
||||
<ul>
|
||||
<li><a href="/categories/">Top</a>
|
||||
<ul>
|
||||
<li><a href="/categories/grandparent/">Grandparent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="/categories/">Top</a>
|
||||
<ul>
|
||||
<li><a href="/categories/grandparent/">Grandparent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
get_category_drilldown
|
||||
======================
|
||||
``display_drilldown_as_ul``
|
||||
---------------------------
|
||||
|
||||
Retrieves the specified category, its ancestors and its immediate children
|
||||
as an iterable.
|
||||
**Template rendered:** ``categories/ul_tree.html``
|
||||
|
||||
Example:
|
||||
**Syntax 1:** ``{% display_drilldown_as_ul category_obj %}``
|
||||
|
||||
.. code-block:: django
|
||||
**Syntax 2:** ``{% display_drilldown_as_ul "/Grandparent/Parent" [using="app.Model"] %}``
|
||||
|
||||
{% get_category_drilldown "/Grandparent/Parent" as family %}
|
||||
Render the category with ancestors and children.
|
||||
|
||||
or
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown category_obj as family %}
|
||||
|
||||
Sets ``family`` to::
|
||||
|
||||
[Grandparent, Parent, Child 1, Child 2, Child n]
|
||||
|
||||
|
||||
display_drilldown_as_ul
|
||||
=======================
|
||||
|
||||
Render the category with ancestors and children using the
|
||||
``categories/ul_tree.html`` template.
|
||||
|
||||
Example:
|
||||
**Example, using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_drilldown_as_ul "/Grandparent/Parent" %}
|
||||
|
||||
or:
|
||||
**Example, using custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% display_drilldown_as_ul "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example, using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -110,18 +211,30 @@ Returns:
|
|||
</ul>
|
||||
|
||||
|
||||
breadcrumbs tag
|
||||
===============
|
||||
``breadcrumbs tag``
|
||||
-------------------
|
||||
|
||||
Render breadcrumbs, using the ``categories/breadcrumbs.html`` template, using the optional ``separator`` argument.
|
||||
**Template rendered:** ``categories/breadcrumbs.html``
|
||||
|
||||
Example:
|
||||
**Syntax 1:** ``{% breadcrumbs category_obj [separator=" :: "] %}``
|
||||
|
||||
**Syntax 2:** ``{% breadcrumbs "/Grandparent/Parent" [separator=" :: "] [using="app.Model"] %}``
|
||||
|
||||
Render breadcrumbs for the given path using ``::`` or the given separator.
|
||||
|
||||
**Example using Category model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs "/Grandparent/Parent" %}
|
||||
|
||||
or:
|
||||
**Example using a custom model:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs "/Grandparent/Parent" using="coolapp.MusicGenre" %}
|
||||
|
||||
**Example using an object:**
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
|
|
@ -133,14 +246,103 @@ Returns:
|
|||
|
||||
<a href="/categories/grandparent/">Grandparent</a> / Parent
|
||||
|
||||
You can alter the separator used in the template by adding a string argument to be the separator:
|
||||
You can alter the separator used in the template by adding a separator argument:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% breadcrumbs category_obj "::" %}
|
||||
{% breadcrumbs category_obj separator=" > " %}
|
||||
|
||||
Returns:
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<a href="/categories/grandparent/">Grandparent</a> :: Parent
|
||||
<a href="/categories/grandparent/">Grandparent</a> > Parent
|
||||
|
||||
|
||||
Template Tags
|
||||
=============
|
||||
|
||||
``get_top_level_categories``
|
||||
----------------------------
|
||||
|
||||
Retrieves an alphabetical list of all the categories that have no parents.
|
||||
|
||||
Syntax:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_top_level_categories [using "app.Model"] as categories %}
|
||||
|
||||
Returns an list of categories ``[<category>, <category>, <category, ...]``
|
||||
|
||||
|
||||
``get_category_drilldown``
|
||||
--------------------------
|
||||
|
||||
**Syntax 1:** ``{% get_category_drilldown <path_string> [using "app.Model"] as <varname> %}``
|
||||
|
||||
**Syntax 2:** ``{% get_category_drilldown <object> as <varname> %}``
|
||||
|
||||
Retrieves the specified category, its ancestors and its immediate children as an iterable. Syntax 1 allows for the retrieval of the category object via a slash-delimited path. The optional ``using "app.Model"`` allows you to specify from which model to retrieve the object.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown "/Grandparent/Parent" using "family.Member" as family %}
|
||||
|
||||
The second syntax uses an instance of any object that subclasses :py:class:`CategoryBase`
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% get_category_drilldown category_obj as family %}
|
||||
|
||||
Both examples sets ``family`` to::
|
||||
|
||||
[Grandparent, Parent, Child 1, Child 2, Child n]
|
||||
|
||||
``recursetree``
|
||||
---------------
|
||||
|
||||
This tag renders a section of your template recursively for each node in your
|
||||
tree.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
<ul class="root">
|
||||
{% recursetree nodes %}
|
||||
<li>
|
||||
{{ node.name }}
|
||||
{% if not node.is_leaf_node %}
|
||||
<ul class="children">
|
||||
{{ children }}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endrecursetree %}
|
||||
</ul>
|
||||
|
||||
Note the special variables ``node`` and ``children``.
|
||||
These are magically inserted into your context while you're inside the
|
||||
``recursetree`` tag.
|
||||
|
||||
``node`` is an instance of your MPTT model.
|
||||
|
||||
``children`` : This variable holds the rendered HTML for the children of
|
||||
``node``.
|
||||
|
||||
.. note::
|
||||
If you already have variables called ``node`` or ``children`` in your
|
||||
template, and you need to access them inside the ``recursetree`` block,
|
||||
you'll need to alias them to some other name first:
|
||||
|
||||
.. code-block:: django
|
||||
|
||||
{% with node as friendly_node %}
|
||||
{% recursetree nodes %}
|
||||
{{ node.name }} is friends with {{ friendly_node.name }}
|
||||
{{ children }}
|
||||
{% endrecursetree %}
|
||||
{% endwith %}
|
||||
|
|
|
|||
16
docs/_static/basic.css
vendored
16
docs/_static/basic.css
vendored
|
|
@ -79,14 +79,6 @@ div.sphinxsidebar input {
|
|||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input[type="text"] {
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input[type="submit"] {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
|
@ -244,6 +236,7 @@ img.align-center, .figure.align-center, object.align-center {
|
|||
}
|
||||
|
||||
.align-center {
|
||||
clear: both;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
@ -447,11 +440,6 @@ dl.glossary dt {
|
|||
font-style: oblique;
|
||||
}
|
||||
|
||||
abbr, acronym {
|
||||
border-bottom: dotted 1px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
|
|
@ -537,4 +525,4 @@ span.eqno {
|
|||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
docs/_static/default.css
vendored
16
docs/_static/default.css
vendored
|
|
@ -62,7 +62,7 @@ div.clearer {
|
|||
.headerButton a:hover {
|
||||
color: white;
|
||||
background-color: #787878;
|
||||
|
||||
|
||||
}
|
||||
|
||||
li#toc_button {
|
||||
|
|
@ -121,7 +121,7 @@ right:0;
|
|||
top: 84px;
|
||||
bottom: 19px;
|
||||
left: 0px;
|
||||
width: 229px;
|
||||
width: 229px;
|
||||
background-color: #E4EBF7;
|
||||
border-right: 1px solid #ACACAC;
|
||||
border-top: 1px solid #2B334F;
|
||||
|
|
@ -362,7 +362,7 @@ p.topic-title {
|
|||
border:1px solid #111111;
|
||||
margin:30px;
|
||||
}
|
||||
.admonition p {
|
||||
.admonition p {
|
||||
font: 12px 'Lucida Grande', Geneva, Helvetica, Arial, sans-serif;
|
||||
margin-top: 7px;
|
||||
margin-bottom: 0px;
|
||||
|
|
@ -411,7 +411,7 @@ table.docutils td, table.docutils th {
|
|||
table.docutils th {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* This alternates colors in up to six table rows (light blue for odd, white for even)*/
|
||||
/* This alternates colors in up to six table rows (light blue for odd, white for even)*/
|
||||
.docutils tr {
|
||||
background: #F0F5F9;
|
||||
}
|
||||
|
|
@ -453,6 +453,7 @@ th {
|
|||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
dd p {
|
||||
|
|
@ -544,7 +545,7 @@ td.linenos pre {
|
|||
}
|
||||
|
||||
td.code {
|
||||
|
||||
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
|
|
@ -562,7 +563,6 @@ table.highlighttable td.linenos {
|
|||
}
|
||||
tt {
|
||||
font-family:"Bitstream Vera Sans Mono",Monaco,"Lucida Console",Courier,Consolas,monospace;
|
||||
|
||||
}
|
||||
|
||||
tt.descname {
|
||||
|
|
@ -643,7 +643,7 @@ dl.class dd dl.method dt {
|
|||
padding: 3px;
|
||||
background-color: #e9e9e9;
|
||||
border-top: none;
|
||||
|
||||
|
||||
}
|
||||
|
||||
dl.function dt {
|
||||
|
|
@ -659,7 +659,7 @@ margin:0 0 0 30px;
|
|||
padding:0 0 12px 6px;
|
||||
}
|
||||
#docstitle {
|
||||
height: 36px;
|
||||
height: 36px;
|
||||
background-image: url(header_sm_mid.png);
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
|
|
|||
10
docs/_static/doctools.js
vendored
10
docs/_static/doctools.js
vendored
|
|
@ -2,7 +2,7 @@
|
|||
* doctools.js
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx JavaScript utilities for all documentation.
|
||||
* Sphinx JavaScript utilties for all documentation.
|
||||
*
|
||||
* :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
|
|
@ -185,9 +185,9 @@ var Documentation = {
|
|||
body.highlightText(this.toLowerCase(), 'highlighted');
|
||||
});
|
||||
}, 10);
|
||||
$('<p class="highlight-link"><a href="javascript:Documentation.' +
|
||||
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
|
||||
.appendTo($('#searchbox'));
|
||||
$('<li class="highlight-link"><a href="javascript:Documentation.' +
|
||||
'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
|
||||
.appendTo($('.sidebar .this-page-menu'));
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -213,7 +213,7 @@ var Documentation = {
|
|||
* helper function to hide the search marks again
|
||||
*/
|
||||
hideSearchWords : function() {
|
||||
$('#searchbox .highlight-link').fadeOut(300);
|
||||
$('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
|
||||
$('span.highlighted').removeClass('highlighted');
|
||||
},
|
||||
|
||||
|
|
|
|||
138
docs/_static/searchtools.js
vendored
138
docs/_static/searchtools.js
vendored
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* searchtools.js_t
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
* searchtools.js
|
||||
* ~~~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx JavaScript utilties for the full-text search.
|
||||
*
|
||||
|
|
@ -36,11 +36,10 @@ jQuery.makeSearchSummary = function(text, keywords, hlwords) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Porter Stemmer
|
||||
*/
|
||||
var Stemmer = function() {
|
||||
var PorterStemmer = function() {
|
||||
|
||||
var step2list = {
|
||||
ational: 'ate',
|
||||
|
|
@ -301,20 +300,20 @@ var Search = {
|
|||
},
|
||||
|
||||
query : function(query) {
|
||||
var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
|
||||
var stopwords = ['and', 'then', 'into', 'it', 'as', 'are', 'in',
|
||||
'if', 'for', 'no', 'there', 'their', 'was', 'is',
|
||||
'be', 'to', 'that', 'but', 'they', 'not', 'such',
|
||||
'with', 'by', 'a', 'on', 'these', 'of', 'will',
|
||||
'this', 'near', 'the', 'or', 'at'];
|
||||
|
||||
// Stem the searchterms and add them to the correct list
|
||||
var stemmer = new Stemmer();
|
||||
// stem the searchterms and add them to the correct list
|
||||
var stemmer = new PorterStemmer();
|
||||
var searchterms = [];
|
||||
var excluded = [];
|
||||
var hlterms = [];
|
||||
var tmp = query.split(/\s+/);
|
||||
var objectterms = [];
|
||||
var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
|
||||
for (var i = 0; i < tmp.length; i++) {
|
||||
if (tmp[i] != "") {
|
||||
objectterms.push(tmp[i].toLowerCase());
|
||||
}
|
||||
|
||||
if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
|
||||
tmp[i] == "") {
|
||||
// skip this "word"
|
||||
|
|
@ -345,6 +344,9 @@ var Search = {
|
|||
var filenames = this._index.filenames;
|
||||
var titles = this._index.titles;
|
||||
var terms = this._index.terms;
|
||||
var objects = this._index.objects;
|
||||
var objtypes = this._index.objtypes;
|
||||
var objnames = this._index.objnames;
|
||||
var fileMap = {};
|
||||
var files = null;
|
||||
// different result priorities
|
||||
|
|
@ -355,19 +357,40 @@ var Search = {
|
|||
$('#search-progress').empty();
|
||||
|
||||
// lookup as object
|
||||
for (var i = 0; i < objectterms.length; i++) {
|
||||
var others = [].concat(objectterms.slice(0,i),
|
||||
objectterms.slice(i+1, objectterms.length))
|
||||
var results = this.performObjectSearch(objectterms[i], others);
|
||||
// Assume first word is most likely to be the object,
|
||||
// other words more likely to be in description.
|
||||
// Therefore put matches for earlier words first.
|
||||
// (Results are eventually used in reverse order).
|
||||
objectResults = results[0].concat(objectResults);
|
||||
importantResults = results[1].concat(importantResults);
|
||||
unimportantResults = results[2].concat(unimportantResults);
|
||||
if (object != null) {
|
||||
for (var prefix in objects) {
|
||||
for (var name in objects[prefix]) {
|
||||
var fullname = (prefix ? prefix + '.' : '') + name;
|
||||
if (fullname.toLowerCase().indexOf(object) > -1) {
|
||||
match = objects[prefix][name];
|
||||
descr = objnames[match[1]] + _(', in ') + titles[match[0]];
|
||||
// XXX the generated anchors are not generally correct
|
||||
// XXX there may be custom prefixes
|
||||
result = [filenames[match[0]], fullname, '#'+fullname, descr];
|
||||
switch (match[2]) {
|
||||
case 1: objectResults.push(result); break;
|
||||
case 0: importantResults.push(result); break;
|
||||
case 2: unimportantResults.push(result); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort results descending
|
||||
objectResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
importantResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
unimportantResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
|
||||
// perform the search on the required terms
|
||||
for (var i = 0; i < searchterms.length; i++) {
|
||||
var word = searchterms[i];
|
||||
|
|
@ -466,7 +489,7 @@ var Search = {
|
|||
listItem.slideDown(5, function() {
|
||||
displayNextItem();
|
||||
});
|
||||
}, "text");
|
||||
});
|
||||
} else {
|
||||
// no source available, just display title
|
||||
Search.output.append(listItem);
|
||||
|
|
@ -487,74 +510,9 @@ var Search = {
|
|||
}
|
||||
}
|
||||
displayNextItem();
|
||||
},
|
||||
|
||||
performObjectSearch : function(object, otherterms) {
|
||||
var filenames = this._index.filenames;
|
||||
var objects = this._index.objects;
|
||||
var objnames = this._index.objnames;
|
||||
var titles = this._index.titles;
|
||||
|
||||
var importantResults = [];
|
||||
var objectResults = [];
|
||||
var unimportantResults = [];
|
||||
|
||||
for (var prefix in objects) {
|
||||
for (var name in objects[prefix]) {
|
||||
var fullname = (prefix ? prefix + '.' : '') + name;
|
||||
if (fullname.toLowerCase().indexOf(object) > -1) {
|
||||
var match = objects[prefix][name];
|
||||
var objname = objnames[match[1]][2];
|
||||
var title = titles[match[0]];
|
||||
// If more than one term searched for, we require other words to be
|
||||
// found in the name/title/description
|
||||
if (otherterms.length > 0) {
|
||||
var haystack = (prefix + ' ' + name + ' ' +
|
||||
objname + ' ' + title).toLowerCase();
|
||||
var allfound = true;
|
||||
for (var i = 0; i < otherterms.length; i++) {
|
||||
if (haystack.indexOf(otherterms[i]) == -1) {
|
||||
allfound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!allfound) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
var descr = objname + _(', in ') + title;
|
||||
anchor = match[3];
|
||||
if (anchor == '')
|
||||
anchor = fullname;
|
||||
else if (anchor == '-')
|
||||
anchor = objnames[match[1]][1] + '-' + fullname;
|
||||
result = [filenames[match[0]], fullname, '#'+anchor, descr];
|
||||
switch (match[2]) {
|
||||
case 1: objectResults.push(result); break;
|
||||
case 0: importantResults.push(result); break;
|
||||
case 2: unimportantResults.push(result); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort results descending
|
||||
objectResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
importantResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
unimportantResults.sort(function(a, b) {
|
||||
return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
|
||||
});
|
||||
|
||||
return [importantResults, objectResults, unimportantResults]
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
Search.init();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
3
docs/_static/sidebar.js
vendored
3
docs/_static/sidebar.js
vendored
|
|
@ -29,9 +29,6 @@ $(function() {
|
|||
var sidebar = $('.sphinxsidebar');
|
||||
var sidebarwrapper = $('.sphinxsidebarwrapper');
|
||||
|
||||
// for some reason, the document has no sidebar; do not run into errors
|
||||
if (!sidebar.length) return;
|
||||
|
||||
// original margin-left of the bodywrapper and width of the sidebar
|
||||
// with the sidebar expanded
|
||||
var bw_margin_expanded = bodywrapper.css('margin-left');
|
||||
|
|
|
|||
7
docs/_static/underscore.js
vendored
7
docs/_static/underscore.js
vendored
|
|
@ -1,10 +1,3 @@
|
|||
// Underscore.js 0.5.5
|
||||
// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
|
||||
// Underscore is freely distributable under the terms of the MIT license.
|
||||
// Portions of Underscore are inspired by or borrowed from Prototype.js,
|
||||
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
||||
// For all details and documentation:
|
||||
// http://documentcloud.github.com/underscore/
|
||||
(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
|
||||
a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
|
||||
var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Adding the fields to the database — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Adding the fields to the database — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Creating Custom Categories" href="custom_categories.html" />
|
||||
<link rel="prev" title="Registering Models" href="registering_models.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Adding the fields to the database</h1></div>
|
||||
|
|
@ -116,7 +113,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Creating Custom Categories — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Creating Custom Categories — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Reference" href="reference/index.html" />
|
||||
<link rel="prev" title="Adding the fields to the database" href="adding_the_fields.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Creating Custom Categories</h1></div>
|
||||
|
|
@ -122,23 +119,25 @@
|
|||
</td></tr></table></div>
|
||||
</li>
|
||||
<li><p class="first">Create a subclass of CategoryBaseAdmin.</p>
|
||||
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">categories.models</span> <span class="kn">import</span> <span class="n">CategoryBase</span>
|
||||
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.contrib</span> <span class="kn">import</span> <span class="n">admin</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SimpleCategory</span><span class="p">(</span><span class="n">CategoryBase</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> A simple of catgorizing example</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">Meta</span><span class="p">:</span>
|
||||
<span class="n">verbose_name_plural</span> <span class="o">=</span> <span class="s">'simple categories'</span>
|
||||
<span class="kn">from</span> <span class="nn">categories.admin</span> <span class="kn">import</span> <span class="n">CategoryBaseAdmin</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.models</span> <span class="kn">import</span> <span class="n">SimpleCategory</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SimpleCategoryAdmin</span><span class="p">(</span><span class="n">CategoryBaseAdmin</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">SimpleCategory</span><span class="p">,</span> <span class="n">SimpleCategoryAdmin</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</td></tr></table></div>
|
||||
</li>
|
||||
|
|
@ -328,7 +327,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,18 @@
|
|||
|
||||
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Index — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Index — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -26,11 +21,11 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Index</h1></div>
|
||||
|
|
@ -86,167 +81,100 @@
|
|||
<div class="body">
|
||||
|
||||
|
||||
<h1 id="index">Index</h1>
|
||||
<h1 id="index">Index</h1>
|
||||
|
||||
<div class="genindex-jumpbox">
|
||||
<a href="#A"><strong>A</strong></a>
|
||||
| <a href="#C"><strong>C</strong></a>
|
||||
| <a href="#D"><strong>D</strong></a>
|
||||
| <a href="#M"><strong>M</strong></a>
|
||||
| <a href="#N"><strong>N</strong></a>
|
||||
| <a href="#O"><strong>O</strong></a>
|
||||
| <a href="#P"><strong>P</strong></a>
|
||||
| <a href="#R"><strong>R</strong></a>
|
||||
| <a href="#S"><strong>S</strong></a>
|
||||
| <a href="#T"><strong>T</strong></a>
|
||||
|
||||
</div>
|
||||
<div class="genindex-jumpbox">
|
||||
<a href="#A"><strong>A</strong></a> | <a href="#C"><strong>C</strong></a> | <a href="#D"><strong>D</strong></a> | <a href="#M"><strong>M</strong></a> | <a href="#N"><strong>N</strong></a> | <a href="#O"><strong>O</strong></a> | <a href="#P"><strong>P</strong></a> | <a href="#R"><strong>R</strong></a> | <a href="#S"><strong>S</strong></a> | <a href="#T"><strong>T</strong></a>
|
||||
</div>
|
||||
<h2 id="A">A</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.active">active (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
|
||||
<dt><a href="reference/models.html#Category.alternate_title">alternate_title (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase.active">active (CategoryBase attribute)</a></dt>
|
||||
<dt><a href="reference/models.html#Category.alternate_title">alternate_title (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.alternate_url">alternate_url (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.alternate_url">alternate_url (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="C">C</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category">Category (built-in class)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category">Category (built-in class)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase">CategoryBase (built-in class)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase">CategoryBase (built-in class)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="D">D</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.description">description (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.description">description (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="M">M</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.meta_extra">meta_extra (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.meta_extra">meta_extra (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.meta_keywords">meta_keywords (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.meta_keywords">meta_keywords (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="N">N</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.name">name (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase.name">name (CategoryBase attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="O">O</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.objects">objects (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase.objects">objects (CategoryBase attribute)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.order">order (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.order">order (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="P">P</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.parent">parent (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase.parent">parent (CategoryBase attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="R">R</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="registering_models.html#register_fk">register_fk() (built-in function)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="registering_models.html#register_fk">register_fk() (built-in function)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="registering_models.html#register_m2m">register_m2m() (built-in function)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="registering_models.html#register_m2m">register_m2m() (built-in function)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="S">S</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.slug">slug (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#CategoryBase.slug">slug (CategoryBase attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
<h2 id="T">T</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.thumbnail">thumbnail (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
|
||||
<dt><a href="reference/models.html#Category.thumbnail_height">thumbnail_height (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.thumbnail">thumbnail (Category attribute)</a></dt>
|
||||
<dt><a href="reference/models.html#Category.thumbnail_height">thumbnail_height (Category attribute)</a></dt>
|
||||
</dl></td>
|
||||
<td style="width: 33%" valign="top"><dl>
|
||||
|
||||
<dt><a href="reference/models.html#Category.thumbnail_width">thumbnail_width (Category attribute)</a>
|
||||
</dt>
|
||||
|
||||
|
||||
<dt><a href="reference/models.html#CategoryBase.tree">tree (CategoryBase attribute)</a>
|
||||
</dt>
|
||||
|
||||
</dl></td>
|
||||
<dt><a href="reference/models.html#Category.thumbnail_width">thumbnail_width (Category attribute)</a></dt>
|
||||
<dt><a href="reference/models.html#CategoryBase.tree">tree (CategoryBase attribute)</a></dt>
|
||||
</dl></td>
|
||||
</tr></table>
|
||||
|
||||
|
||||
|
|
@ -257,7 +185,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Getting Started — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Getting Started — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Using categories in templates" href="usage.html" />
|
||||
<link rel="prev" title="Installation" href="installation.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Getting Started</h1></div>
|
||||
|
|
@ -155,7 +152,7 @@ Subject 2
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Django Categories v 1.0 — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Django Categories v 1.1 — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,15 +21,15 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="#" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="#" />
|
||||
<link rel="next" title="Installation" href="installation.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Django Categories v 1.0</h1></div>
|
||||
<div id="title"><h1>Django Categories v 1.1</h1></div>
|
||||
<ul id="headerButtons">
|
||||
<li id="toc_button"><div class="headerButton"><a href="#">Table of Contents</a></div></li>
|
||||
<li id="page_buttons">
|
||||
|
|
@ -88,26 +85,17 @@
|
|||
<div class="body">
|
||||
|
||||
<div class="section" id="django-categories-v-version">
|
||||
<h1>Django Categories v 1.0<a class="headerlink" href="#django-categories-v-version" title="Permalink to this headline">¶</a></h1>
|
||||
<h1>Django Categories v 1.1<a class="headerlink" href="#django-categories-v-version" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Django Categories grew out of our need to provide a basic hierarchical taxonomy management system that multiple applications could use independently or in concert.</p>
|
||||
<p>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.</p>
|
||||
<div class="section" id="new-in-1-0">
|
||||
<h2>New in 1.0<a class="headerlink" href="#new-in-1-0" title="Permalink to this headline">¶</a></h2>
|
||||
<dl class="docutils">
|
||||
<dt><strong>Abstract Base Class for generic hierarchical category models</strong></dt>
|
||||
<dd><p class="first">When you want a multiple types of categories and don’t want them all part of the same model, you can now easily create new models by subclassing <tt class="docutils literal"><span class="pre">CategoryBase</span></tt>. You can also add additional metadata as necessary.</p>
|
||||
<p>Your model’s can subclass <tt class="docutils literal"><span class="pre">CategoryBaseAdminForm</span></tt> and <tt class="docutils literal"><span class="pre">CategoryBaseAdmin</span></tt> to get the hierarchical management in the admin.</p>
|
||||
<p class="last">See the docs for more information.</p>
|
||||
</dd>
|
||||
<dt><strong>Increased the default caching time on views</strong></dt>
|
||||
<dd>The default setting for <tt class="docutils literal"><span class="pre">CACHE_VIEW_LENGTH</span></tt> was <tt class="docutils literal"><span class="pre">0</span></tt>, which means it would tell the browser to <em>never</em> cache the page. It is now <tt class="docutils literal"><span class="pre">600</span></tt>, which is the default for <a class="reference external" href="https://docs.djangoproject.com/en/1.3/ref/settings/#cache-middleware-seconds">CACHE_MIDDLEWARE_SECONDS</a></dd>
|
||||
<dt><strong>Updated for use with Django-MPTT 0.5</strong></dt>
|
||||
<dd>Just a few tweaks.</dd>
|
||||
<dt><strong>Initial compatibility with Django 1.4</strong></dt>
|
||||
<dd>More is coming, but at least it works.</dd>
|
||||
<dt><strong>Slug transliteration for non-ASCII characters</strong></dt>
|
||||
<dd>A new setting, <tt class="docutils literal"><span class="pre">SLUG_TRANSLITERATOR</span></tt>, allows you to specify a function for converting the non-ASCII characters to ASCII characters before the slugification. Works great with <a class="reference external" href="http://pypi.python.org/pypi/Unidecode">Unidecode</a>.</dd>
|
||||
</dl>
|
||||
<div class="section" id="new-in-1-1">
|
||||
<h2>New in 1.1<a class="headerlink" href="#new-in-1-1" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li>Fixed a cosmetic bug in the Django 1.4 admin. Action checkboxes now only appear once.</li>
|
||||
<li>Template tags are refactored to allow easy use of any model derived from <tt class="docutils literal"><span class="pre">CategoryBase</span></tt>.</li>
|
||||
<li>Improved test suite.</li>
|
||||
<li>Improved some of the documentation.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contents">
|
||||
<h2>Contents<a class="headerlink" href="#contents" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -147,7 +135,7 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="reference/management_commands.html">Management Commands</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference/models.html">Models</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference/settings.html">Settings</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference/templatetags.html">Template Tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="reference/templatetags.html">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -170,13 +158,13 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div id="breadcrumbs">
|
||||
Django Categories v 1.0
|
||||
Django Categories v 1.1
|
||||
</ul>
|
||||
</div>
|
||||
<script type="text/javascript" charset="utf-8" src="_static/toc.js"></script>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Installation — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Installation — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Getting Started" href="getting_started.html" />
|
||||
<link rel="prev" title="Django Categories v 1.0" href="index.html" />
|
||||
<link rel="prev" title="Django Categories v 1.1" href="index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Installation</h1></div>
|
||||
|
|
@ -39,7 +36,7 @@
|
|||
<li id="page_buttons">
|
||||
<div class="headerButton"><a href="genindex.html" title="General Index" accesskey="I">index</a></div>
|
||||
<div class="headerButton"><a href="getting_started.html" title="Getting Started" accesskey="N">next</a></div>
|
||||
<div class="headerButton"><a href="index.html" title="Django Categories v 1.0" accesskey="P">previous</a></div>
|
||||
<div class="headerButton"><a href="index.html" title="Django Categories v 1.1" accesskey="P">previous</a></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -144,7 +141,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Reference — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Reference — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="../index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="../index.html" />
|
||||
<link rel="next" title="Management Commands" href="management_commands.html" />
|
||||
<link rel="prev" title="Creating Custom Categories" href="../custom_categories.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Reference</h1></div>
|
||||
|
|
@ -58,7 +55,7 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="management_commands.html">Management Commands</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="models.html">Models</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="settings.html">Settings</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template Tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -123,12 +120,10 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="settings.html#javascript-url">JAVASCRIPT_URL</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="templatetags.html">Template Tags</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#get-top-level-categories">get_top_level_categories</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#display-path-as-ul">display_path_as_ul</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#get-category-drilldown">get_category_drilldown</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#display-drilldown-as-ul">display_drilldown_as_ul</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#breadcrumbs-tag">breadcrumbs tag</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="templatetags.html">Template tags and filters</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#filters">Filters</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#inclusion-tags">Inclusion tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html#template-tags">Template Tags</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -142,7 +137,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Management Commands — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Management Commands — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,14 +21,14 @@
|
|||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="../index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="../index.html" />
|
||||
<link rel="up" title="Reference" href="index.html" />
|
||||
<link rel="next" title="Models" href="models.html" />
|
||||
<link rel="prev" title="Reference" href="index.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Management Commands</h1></div>
|
||||
|
|
@ -59,7 +56,7 @@
|
|||
<li class="toctree-l2 current"><a class="current reference internal" href="">Management Commands</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="models.html">Models</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="settings.html">Settings</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template Tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -124,7 +121,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Models — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Models — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,14 +21,14 @@
|
|||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="../index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="../index.html" />
|
||||
<link rel="up" title="Reference" href="index.html" />
|
||||
<link rel="next" title="Settings" href="settings.html" />
|
||||
<link rel="prev" title="Management Commands" href="management_commands.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Models</h1></div>
|
||||
|
|
@ -59,7 +56,7 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="management_commands.html">Management Commands</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="">Models</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="settings.html">Settings</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template Tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -127,7 +124,7 @@
|
|||
<dl class="attribute">
|
||||
<dt id="CategoryBase.active">
|
||||
<tt class="descname">active</tt><a class="headerlink" href="#CategoryBase.active" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p><strong>Required</strong> <tt class="docutils literal"><span class="pre">BooleanField</span></tt> <em>default:</em> <tt class="docutils literal"><span class="pre">True</span></tt></p>
|
||||
<dd><p><strong>Required</strong> <tt class="docutils literal"><span class="pre">BooleanField</span></tt> <em>default:</em> <tt class="xref docutils literal"><span class="pre">True</span></tt></p>
|
||||
<p>Is this item active. If it is inactive, all children are set to inactive as well.</p>
|
||||
</dd></dl>
|
||||
|
||||
|
|
@ -135,7 +132,7 @@
|
|||
<dt id="CategoryBase.objects">
|
||||
<tt class="descname">objects</tt><a class="headerlink" href="#CategoryBase.objects" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p><tt class="docutils literal"><span class="pre">CategoryManager</span></tt></p>
|
||||
<p>An object manager that adds an <tt class="docutils literal"><span class="pre">active</span></tt> method for only selecting items whose <tt class="docutils literal"><span class="pre">active</span></tt> attribute is <tt class="docutils literal"><span class="pre">True</span></tt>.</p>
|
||||
<p>An object manager that adds an <tt class="docutils literal"><span class="pre">active</span></tt> method for only selecting items whose <tt class="docutils literal"><span class="pre">active</span></tt> attribute is <tt class="xref docutils literal"><span class="pre">True</span></tt>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="attribute">
|
||||
|
|
@ -240,7 +237,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Settings — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Settings — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,14 +21,14 @@
|
|||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="../index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="../index.html" />
|
||||
<link rel="up" title="Reference" href="index.html" />
|
||||
<link rel="next" title="Template Tags" href="templatetags.html" />
|
||||
<link rel="next" title="Template tags and filters" href="templatetags.html" />
|
||||
<link rel="prev" title="Models" href="models.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Settings</h1></div>
|
||||
|
|
@ -39,7 +36,7 @@
|
|||
<li id="toc_button"><div class="headerButton"><a href="#">Table of Contents</a></div></li>
|
||||
<li id="page_buttons">
|
||||
<div class="headerButton"><a href="../genindex.html" title="General Index" accesskey="I">index</a></div>
|
||||
<div class="headerButton"><a href="templatetags.html" title="Template Tags" accesskey="N">next</a></div>
|
||||
<div class="headerButton"><a href="templatetags.html" title="Template tags and filters" accesskey="N">next</a></div>
|
||||
<div class="headerButton"><a href="models.html" title="Models" accesskey="P">previous</a></div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -59,7 +56,7 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="management_commands.html">Management Commands</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="models.html">Models</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="">Settings</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template Tags</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="templatetags.html">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -128,8 +125,8 @@
|
|||
</div>
|
||||
<div class="section" id="allow-slug-change">
|
||||
<span id="id1"></span><h2><a class="toc-backref" href="#id11">ALLOW_SLUG_CHANGE</a><a class="headerlink" href="#allow-slug-change" title="Permalink to this headline">¶</a></h2>
|
||||
<p><strong>Default:</strong> <tt class="docutils literal"><span class="pre">False</span></tt></p>
|
||||
<p><strong>Description:</strong> Changing the slug for a category can have serious consequences if it is used as part of a URL. Setting this to <tt class="docutils literal"><span class="pre">True</span></tt> will allow users to change the slug of a category.</p>
|
||||
<p><strong>Default:</strong> <tt class="xref docutils literal"><span class="pre">False</span></tt></p>
|
||||
<p><strong>Description:</strong> Changing the slug for a category can have serious consequences if it is used as part of a URL. Setting this to <tt class="xref docutils literal"><span class="pre">True</span></tt> will allow users to change the slug of a category.</p>
|
||||
</div>
|
||||
<div class="section" id="slug-transliterator">
|
||||
<span id="id2"></span><h2><a class="toc-backref" href="#id12">SLUG_TRANSLITERATOR</a><a class="headerlink" href="#slug-transliterator" title="Permalink to this headline">¶</a></h2>
|
||||
|
|
@ -159,7 +156,7 @@
|
|||
</div>
|
||||
<div class="section" id="register-admin">
|
||||
<span id="thumbnail-upload-path"></span><span id="id7"></span><h2><a class="toc-backref" href="#id17">REGISTER_ADMIN</a><a class="headerlink" href="#register-admin" title="Permalink to this headline">¶</a></h2>
|
||||
<p><strong>Default:</strong> <tt class="docutils literal"><span class="pre">True</span></tt></p>
|
||||
<p><strong>Default:</strong> <tt class="xref docutils literal"><span class="pre">True</span></tt></p>
|
||||
<p><strong>Description:</strong> If you write your own category class by subclassing <tt class="docutils literal"><span class="pre">CategoryBase</span></tt> then you probably have no use for registering the default <tt class="docutils literal"><span class="pre">Category</span></tt> class in the admin.</p>
|
||||
</div>
|
||||
<div class="section" id="id8">
|
||||
|
|
@ -186,7 +183,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Template Tags — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Template tags and filters — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '../',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,16 +21,16 @@
|
|||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="../index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="../index.html" />
|
||||
<link rel="up" title="Reference" href="index.html" />
|
||||
<link rel="prev" title="Settings" href="settings.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Template Tags</h1></div>
|
||||
<div id="title"><h1>Template tags and filters</h1></div>
|
||||
<ul id="headerButtons">
|
||||
<li id="toc_button"><div class="headerButton"><a href="#">Table of Contents</a></div></li>
|
||||
<li id="page_buttons">
|
||||
|
|
@ -57,7 +54,7 @@
|
|||
<li class="toctree-l2"><a class="reference internal" href="management_commands.html">Management Commands</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="models.html">Models</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="settings.html">Settings</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="">Template Tags</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="">Template tags and filters</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -94,25 +91,128 @@
|
|||
<div class="bodywrapper">
|
||||
<div class="body">
|
||||
|
||||
<div class="section" id="template-tags">
|
||||
<h1>Template Tags<a class="headerlink" href="#template-tags" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="get-top-level-categories">
|
||||
<h2>get_top_level_categories<a class="headerlink" href="#get-top-level-categories" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Retrieves an alphabetical list of all the categories that have no parents.</p>
|
||||
<p>Syntax:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_top_level_categories</span> <span class="k">as</span> <span class="nv">categories</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<div class="section" id="template-tags-and-filters">
|
||||
<h1>Template tags and filters<a class="headerlink" href="#template-tags-and-filters" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#filters" id="id2">Filters</a><ul>
|
||||
<li><a class="reference internal" href="#category-path" id="id3"><tt class="docutils literal"><span class="pre">category_path</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#tree-info" id="id4"><tt class="docutils literal"><span class="pre">tree_info</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#tree-queryset" id="id5"><tt class="docutils literal"><span class="pre">tree_queryset</span></tt></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#inclusion-tags" id="id6">Inclusion tags</a><ul>
|
||||
<li><a class="reference internal" href="#display-path-as-ul" id="id7"><tt class="docutils literal"><span class="pre">display_path_as_ul</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#display-drilldown-as-ul" id="id8"><tt class="docutils literal"><span class="pre">display_drilldown_as_ul</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#breadcrumbs-tag" id="id9"><tt class="docutils literal"><span class="pre">breadcrumbs</span> <span class="pre">tag</span></tt></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#template-tags" id="id10">Template Tags</a><ul>
|
||||
<li><a class="reference internal" href="#get-top-level-categories" id="id11"><tt class="docutils literal"><span class="pre">get_top_level_categories</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#get-category-drilldown" id="id12"><tt class="docutils literal"><span class="pre">get_category_drilldown</span></tt></a></li>
|
||||
<li><a class="reference internal" href="#recursetree" id="id13"><tt class="docutils literal"><span class="pre">recursetree</span></tt></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="filters">
|
||||
<h2><a class="toc-backref" href="#contents">Filters</a><a class="headerlink" href="#filters" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="category-path">
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">category_path</span></tt></a><a class="headerlink" href="#category-path" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Optional Parameter:</strong> separator string. <em>Default:</em> <tt class="docutils literal"><span class="pre">"</span> <span class="pre">::</span> <span class="pre">"</span></tt></p>
|
||||
<p>Creates a path represented by a categories by joining the items with a separator.</p>
|
||||
<p>Each path item will be coerced to unicode, so you can pass a list of category instances, if required.</p>
|
||||
<p><strong>Example using a list of categories:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{{</span> <span class="nv">some_list</span><span class="o">|</span><span class="nf">category_path</span> <span class="cp">}}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Returns an list of categories <tt class="docutils literal"><span class="pre">[<category>,</span> <span class="pre"><category>,</span> <span class="pre"><category,</span> <span class="pre">...]</span></tt></p>
|
||||
<p>If <tt class="docutils literal"><span class="pre">some_list</span></tt> is <tt class="docutils literal"><span class="pre">[</span> <span class="pre"><Category:</span> <span class="pre">Country>,</span> <span class="pre"><Category:</span> <span class="pre">Country</span> <span class="pre">pop>,</span> <span class="pre"><Category:</span> <span class="pre">Urban</span> <span class="pre">Cowboy>]</span></tt> the result will be:</p>
|
||||
<div class="highlight-python"><pre>Country :: Country pop :: Urban Cowboy</pre>
|
||||
</div>
|
||||
<p><strong>Example using a category node and optional separator parameter:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{{</span> <span class="nv">some_node.get_ancestors</span><span class="o">|</span><span class="nf">category_path</span><span class="s2">:" > "</span> <span class="cp">}}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If <tt class="docutils literal"><span class="pre">some_node</span></tt> was category “Urban Cowboy”, the result will be:</p>
|
||||
<div class="highlight-python"><pre>Country > Country pop > Urban Cowboy</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="tree-info">
|
||||
<span id="id1"></span><h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">tree_info</span></tt></a><a class="headerlink" href="#tree-info" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Optional Parameter:</strong> <tt class="docutils literal"><span class="pre">"ancestors"</span></tt></p>
|
||||
<p>Given a list of categories, it iterates over the list, generating a tuple of the current category and a dict containing information about the tree structure around it, with the following keys:</p>
|
||||
<dl class="docutils">
|
||||
<dt><tt class="docutils literal"><span class="pre">'new_level'</span></tt></dt>
|
||||
<dd><tt class="xref docutils literal"><span class="pre">True</span></tt> if the current item is the start of a new level in the tree, <tt class="xref docutils literal"><span class="pre">False</span></tt> otherwise.</dd>
|
||||
<dt><tt class="docutils literal"><span class="pre">'closed_levels'</span></tt></dt>
|
||||
<dd>A list of levels which end after the current item. This will be an empty list if the next category’s level is the same as or greater than the level of the current item.</dd>
|
||||
</dl>
|
||||
<p>Provide the optional argument, <tt class="docutils literal"><span class="pre">"ancestors"</span></tt>, to add a list of unicode representations of the ancestors of the current category, in descending order (root node first, immediate parent last), under the key ‘ancestors’.</p>
|
||||
<p>For example: given the sample tree below, the contents of the list which would be available under the ‘ancestors’ key are given on the right:</p>
|
||||
<div class="highlight-python"><pre>Country -> []
|
||||
Country pop -> [u'Country pop']
|
||||
Urban Cowboy -> [u'Country', u'Country pop']</pre>
|
||||
</div>
|
||||
<p>Using this filter with unpacking in a {% for %} tag, you should have enough information about the tree structure to create a hierarchical representation of the tree.</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">for</span> <span class="nv">node</span><span class="o">,</span><span class="nv">structure</span> <span class="k">in</span> <span class="nv">objects</span><span class="o">|</span><span class="nf">tree_info</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">structure.new_level</span> <span class="cp">%}</span><span class="x"><ul><li></span><span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span><span class="x"></li><li></span><span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">node.name</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">level</span> <span class="k">in</span> <span class="nv">structure.closed_levels</span> <span class="cp">%}</span><span class="x"></li></ul></span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="tree-queryset">
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">tree_queryset</span></tt></a><a class="headerlink" href="#tree-queryset" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Convert a regular category <tt class="xref py py-class docutils literal"><span class="pre">QuerySet</span></tt> into a new, ordered <tt class="xref py py-class docutils literal"><span class="pre">QuerySet</span></tt> that includes the categories selected and their ancestors.</p>
|
||||
<p>This is especially helpful when you have a subset of categories and want to show the hierarchy for all the items.</p>
|
||||
<p>For example, if we add it to the example for <a class="reference internal" href="#tree-info"><em>tree_info</em></a>:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">for</span> <span class="nv">node</span><span class="o">,</span><span class="nv">structure</span> <span class="k">in</span> <span class="nv">objects</span><span class="o">|</span><span class="nf">tree_queryset</span><span class="o">|</span><span class="nf">tree_info</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">if</span> <span class="nv">structure.new_level</span> <span class="cp">%}</span><span class="x"><ul><li></span><span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span><span class="x"></li><li></span><span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">node.name</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">for</span> <span class="nv">level</span> <span class="k">in</span> <span class="nv">structure.closed_levels</span> <span class="cp">%}</span><span class="x"></li></ul></span><span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>A list of unrelated categories such as <tt class="docutils literal"><span class="pre">[<Category:</span> <span class="pre">Urban</span> <span class="pre">cowboy>,</span> <span class="pre"><Category:</span> <span class="pre">Urban</span> <span class="pre">comtemporary>]</span></tt>, the above template example will output the two categories and their ancestors:</p>
|
||||
<div class="highlight-html"><div class="highlight"><pre><span class="nt"><ul><li></span>
|
||||
Country
|
||||
<span class="nt"><ul><li></span>
|
||||
Country pop
|
||||
<span class="nt"><ul><li></span>
|
||||
Urban cowboy
|
||||
<span class="nt"></li></ul></li></ul></li></ul></span>
|
||||
<span class="nt"><ul><li></span>
|
||||
Rhythm and blues
|
||||
<span class="nt"><ul><li></span>
|
||||
Urban contemporary
|
||||
<span class="nt"></li></ul></li></ul></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p class="last">Categories that have similar ancestors are grouped accordingly. There is no duplication of the ancestor tree.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="inclusion-tags">
|
||||
<h2><a class="toc-backref" href="#contents">Inclusion tags</a><a class="headerlink" href="#inclusion-tags" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="display-path-as-ul">
|
||||
<h2>display_path_as_ul<a class="headerlink" href="#display-path-as-ul" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Render the category with ancestors, but no children using the <tt class="docutils literal"><span class="pre">categories/ul_tree.html</span></tt> template.</p>
|
||||
<p>Example:</p>
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">display_path_as_ul</span></tt></a><a class="headerlink" href="#display-path-as-ul" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Template Rendered:</strong> <tt class="docutils literal"><span class="pre">categories/ul_tree.html</span></tt></p>
|
||||
<p><strong>Syntax 1:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">display_path_as_ul</span> <span class="pre"><category_obj></span> <span class="pre">%}</span></tt></p>
|
||||
<p><strong>Syntax 2:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">display_path_as_ul</span> <span class="pre"><path_string>[</span> <span class="pre">using="app.Model"]</span> <span class="pre">%}</span></tt></p>
|
||||
<p>Render the category with ancestors, but no children.</p>
|
||||
<p>Pass either an object that subclasses <a class="reference internal" href="models.html#CategoryBase" title="CategoryBase"><tt class="xref py py-class docutils literal"><span class="pre">CategoryBase</span></tt></a> or a path string for the category. Add <tt class="docutils literal"><span class="pre">using="app.Model"</span></tt> to specify which model when using a path string. The default model used is <a class="reference internal" href="models.html#Category" title="Category"><tt class="xref py py-class docutils literal"><span class="pre">Category</span></tt></a>.</p>
|
||||
<p><strong>Example, using Category model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_path_as_ul</span> <span class="s2">"/Grandparent/Parent"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<p><strong>Example, using custom model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_path_as_ul</span> <span class="s2">"/Grandparent/Parent"</span> <span class="nv">using</span><span class="o">=</span><span class="s2">"coolapp.MusicGenre"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><strong>Example, using an object:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_path_as_ul</span> <span class="nv">category_obj</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -127,31 +227,21 @@
|
|||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="get-category-drilldown">
|
||||
<h2>get_category_drilldown<a class="headerlink" href="#get-category-drilldown" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Retrieves the specified category, its ancestors and its immediate children
|
||||
as an iterable.</p>
|
||||
<p>Example:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_category_drilldown</span> <span class="s2">"/Grandparent/Parent"</span> <span class="k">as</span> <span class="nv">family</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_category_drilldown</span> <span class="nv">category_obj</span> <span class="k">as</span> <span class="nv">family</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Sets <tt class="docutils literal"><span class="pre">family</span></tt> to:</p>
|
||||
<div class="highlight-python"><pre>[Grandparent, Parent, Child 1, Child 2, Child n]</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="display-drilldown-as-ul">
|
||||
<h2>display_drilldown_as_ul<a class="headerlink" href="#display-drilldown-as-ul" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Render the category with ancestors and children using the
|
||||
<tt class="docutils literal"><span class="pre">categories/ul_tree.html</span></tt> template.</p>
|
||||
<p>Example:</p>
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">display_drilldown_as_ul</span></tt></a><a class="headerlink" href="#display-drilldown-as-ul" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Template rendered:</strong> <tt class="docutils literal"><span class="pre">categories/ul_tree.html</span></tt></p>
|
||||
<p><strong>Syntax 1:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">display_drilldown_as_ul</span> <span class="pre">category_obj</span> <span class="pre">%}</span></tt></p>
|
||||
<p><strong>Syntax 2:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">display_drilldown_as_ul</span> <span class="pre">"/Grandparent/Parent"</span> <span class="pre">[using="app.Model"]</span> <span class="pre">%}</span></tt></p>
|
||||
<p>Render the category with ancestors and children.</p>
|
||||
<p><strong>Example, using Category model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_drilldown_as_ul</span> <span class="s2">"/Grandparent/Parent"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or:</p>
|
||||
<p><strong>Example, using custom model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_drilldown_as_ul</span> <span class="s2">"/Grandparent/Parent"</span> <span class="nv">using</span><span class="o">=</span><span class="s2">"coolapp.MusicGenre"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><strong>Example, using an object:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">display_drilldown_as_ul</span> <span class="nv">category_obj</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -177,13 +267,20 @@ as an iterable.</p>
|
|||
</div>
|
||||
</div>
|
||||
<div class="section" id="breadcrumbs-tag">
|
||||
<h2>breadcrumbs tag<a class="headerlink" href="#breadcrumbs-tag" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Render breadcrumbs, using the <tt class="docutils literal"><span class="pre">categories/breadcrumbs.html</span></tt> template, using the optional <tt class="docutils literal"><span class="pre">separator</span></tt> argument.</p>
|
||||
<p>Example:</p>
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">breadcrumbs</span> <span class="pre">tag</span></tt></a><a class="headerlink" href="#breadcrumbs-tag" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Template rendered:</strong> <tt class="docutils literal"><span class="pre">categories/breadcrumbs.html</span></tt></p>
|
||||
<p><strong>Syntax 1:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">breadcrumbs</span> <span class="pre">category_obj</span> <span class="pre">[separator="</span> <span class="pre">::</span> <span class="pre">"]</span> <span class="pre">%}</span></tt></p>
|
||||
<p><strong>Syntax 2:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">breadcrumbs</span> <span class="pre">"/Grandparent/Parent"</span> <span class="pre">[separator="</span> <span class="pre">::</span> <span class="pre">"]</span> <span class="pre">[using="app.Model"]</span> <span class="pre">%}</span></tt></p>
|
||||
<p>Render breadcrumbs for the given path using <tt class="docutils literal"><span class="pre">::</span></tt> or the given separator.</p>
|
||||
<p><strong>Example using Category model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">breadcrumbs</span> <span class="s2">"/Grandparent/Parent"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>or:</p>
|
||||
<p><strong>Example using a custom model:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">breadcrumbs</span> <span class="s2">"/Grandparent/Parent"</span> <span class="nv">using</span><span class="o">=</span><span class="s2">"coolapp.MusicGenre"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><strong>Example using an object:</strong></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">breadcrumbs</span> <span class="nv">category_obj</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -191,15 +288,87 @@ as an iterable.</p>
|
|||
<div class="highlight-html"><div class="highlight"><pre><span class="nt"><a</span> <span class="na">href=</span><span class="s">"/categories/grandparent/"</span><span class="nt">></span>Grandparent<span class="nt"></a></span> / Parent
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can alter the separator used in the template by adding a string argument to be the separator:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">breadcrumbs</span> <span class="nv">category_obj</span> <span class="s2">"::"</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<p>You can alter the separator used in the template by adding a separator argument:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">breadcrumbs</span> <span class="nv">category_obj</span> <span class="nv">separator</span><span class="o">=</span><span class="s2">" &gt; "</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Returns:</p>
|
||||
<div class="highlight-html"><div class="highlight"><pre><span class="nt"><a</span> <span class="na">href=</span><span class="s">"/categories/grandparent/"</span><span class="nt">></span>Grandparent<span class="nt"></a></span> :: Parent
|
||||
<div class="highlight-html"><div class="highlight"><pre><span class="nt"><a</span> <span class="na">href=</span><span class="s">"/categories/grandparent/"</span><span class="nt">></span>Grandparent<span class="nt"></a></span> <span class="ni">&gt;</span> Parent
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="template-tags">
|
||||
<h2><a class="toc-backref" href="#contents">Template Tags</a><a class="headerlink" href="#template-tags" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="get-top-level-categories">
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">get_top_level_categories</span></tt></a><a class="headerlink" href="#get-top-level-categories" title="Permalink to this headline">¶</a></h3>
|
||||
<p>Retrieves an alphabetical list of all the categories that have no parents.</p>
|
||||
<p>Syntax:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_top_level_categories</span> <span class="o">[</span><span class="nv">using</span> <span class="s2">"app.Model"</span><span class="o">]</span> <span class="k">as</span> <span class="nv">categories</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Returns an list of categories <tt class="docutils literal"><span class="pre">[<category>,</span> <span class="pre"><category>,</span> <span class="pre"><category,</span> <span class="pre">...]</span></tt></p>
|
||||
</div>
|
||||
<div class="section" id="get-category-drilldown">
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">get_category_drilldown</span></tt></a><a class="headerlink" href="#get-category-drilldown" title="Permalink to this headline">¶</a></h3>
|
||||
<p><strong>Syntax 1:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">get_category_drilldown</span> <span class="pre"><path_string></span> <span class="pre">[using</span> <span class="pre">"app.Model"]</span> <span class="pre">as</span> <span class="pre"><varname></span> <span class="pre">%}</span></tt></p>
|
||||
<p><strong>Syntax 2:</strong> <tt class="docutils literal"><span class="pre">{%</span> <span class="pre">get_category_drilldown</span> <span class="pre"><object></span> <span class="pre">as</span> <span class="pre"><varname></span> <span class="pre">%}</span></tt></p>
|
||||
<p>Retrieves the specified category, its ancestors and its immediate children as an iterable. Syntax 1 allows for the retrieval of the category object via a slash-delimited path. The optional <tt class="docutils literal"><span class="pre">using</span> <span class="pre">"app.Model"</span></tt> allows you to specify from which model to retrieve the object.</p>
|
||||
<p>Example:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_category_drilldown</span> <span class="s2">"/Grandparent/Parent"</span> <span class="nv">using</span> <span class="s2">"family.Member"</span> <span class="k">as</span> <span class="nv">family</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>The second syntax uses an instance of any object that subclasses <a class="reference internal" href="models.html#CategoryBase" title="CategoryBase"><tt class="xref py py-class docutils literal"><span class="pre">CategoryBase</span></tt></a></p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">get_category_drilldown</span> <span class="nv">category_obj</span> <span class="k">as</span> <span class="nv">family</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Both examples sets <tt class="docutils literal"><span class="pre">family</span></tt> to:</p>
|
||||
<div class="highlight-python"><pre>[Grandparent, Parent, Child 1, Child 2, Child n]</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="recursetree">
|
||||
<h3><a class="toc-backref" href="#contents"><tt class="docutils literal"><span class="pre">recursetree</span></tt></a><a class="headerlink" href="#recursetree" title="Permalink to this headline">¶</a></h3>
|
||||
<p>This tag renders a section of your template recursively for each node in your
|
||||
tree.</p>
|
||||
<p>For example:</p>
|
||||
<div class="highlight-django"><div class="highlight"><pre><span class="x"><ul class="root"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">recursetree</span> <span class="nv">nodes</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> <li></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">node.name</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">if</span> <span class="k">not</span> <span class="nv">node.is_leaf_node</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> <ul class="children"></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">children</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </ul></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </li></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">endrecursetree</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"></ul></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Note the special variables <tt class="docutils literal"><span class="pre">node</span></tt> and <tt class="docutils literal"><span class="pre">children</span></tt>.
|
||||
These are magically inserted into your context while you’re inside the
|
||||
<tt class="docutils literal"><span class="pre">recursetree</span></tt> tag.</p>
|
||||
<blockquote>
|
||||
<div><p><tt class="docutils literal"><span class="pre">node</span></tt> is an instance of your MPTT model.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">children</span></tt> : This variable holds the rendered HTML for the children of
|
||||
<tt class="docutils literal"><span class="pre">node</span></tt>.</p>
|
||||
</div></blockquote>
|
||||
<div class="admonition note">
|
||||
<p class="first admonition-title">Note</p>
|
||||
<p>If you already have variables called <tt class="docutils literal"><span class="pre">node</span></tt> or <tt class="docutils literal"><span class="pre">children</span></tt> in your
|
||||
template, and you need to access them inside the <tt class="docutils literal"><span class="pre">recursetree</span></tt> block,
|
||||
you’ll need to alias them to some other name first:</p>
|
||||
<div class="last highlight-django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">with</span> <span class="nv">node</span> <span class="k">as</span> <span class="nv">friendly_node</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">recursetree</span> <span class="nv">nodes</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">node.name</span> <span class="cp">}}</span><span class="x"> is friends with </span><span class="cp">{{</span> <span class="nv">friendly_node.name</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{{</span> <span class="nv">children</span> <span class="cp">}}</span><span class="x"></span>
|
||||
<span class="x"> </span><span class="cp">{%</span> <span class="k">endrecursetree</span> <span class="cp">%}</span><span class="x"></span>
|
||||
<span class="cp">{%</span> <span class="k">endwith</span> <span class="cp">%}</span><span class="x"></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -209,14 +378,14 @@ as an iterable.</p>
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div id="breadcrumbs">
|
||||
<a href="index.html" accesskey="U">Reference</a><img src="../_static/triangle_closed.png" height="9" width="9" alt=">">
|
||||
Template Tags
|
||||
Template tags and filters
|
||||
</ul>
|
||||
</div>
|
||||
<script type="text/javascript" charset="utf-8" src="../_static/toc.js"></script>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Registering Models — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Registering Models — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Adding the fields to the database" href="adding_the_fields.html" />
|
||||
<link rel="prev" title="Using categories in templates" href="usage.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Registering Models</h1></div>
|
||||
|
|
@ -178,7 +175,7 @@
|
|||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
|
||||
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
|
||||
<li><strong>model</strong> – The Django Model to link to Django Categories</li>
|
||||
<li><strong>field_name</strong> – Optional name for the field <strong>default:</strong> category</li>
|
||||
<li><strong>extra_params</strong> – Optional dictionary of extra parameters passed to the <tt class="docutils literal"><span class="pre">ForeignKey</span></tt> class.</li>
|
||||
|
|
@ -212,7 +209,7 @@
|
|||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
|
||||
<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
|
||||
<li><strong>model</strong> – The Django Model to link to Django Categories</li>
|
||||
<li><strong>field_name</strong> – Optional name for the field <strong>default:</strong> categories</li>
|
||||
<li><strong>extra_params</strong> – Optional dictionary of extra parameters passed to the <tt class="docutils literal"><span class="pre">ManyToManyField</span></tt> class.</li>
|
||||
|
|
@ -238,7 +235,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Search — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Search — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -25,7 +22,7 @@
|
|||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="_static/searchtools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<script type="text/javascript">
|
||||
jQuery(function() { Search.loadIndex("searchindex.js"); });
|
||||
</script>
|
||||
|
|
@ -34,7 +31,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Search</h1></div>
|
||||
|
|
@ -99,7 +96,7 @@
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -2,20 +2,17 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>Using categories in templates — Django Categories 1.0.5 documentation</title>
|
||||
|
||||
<title>Using categories in templates — Django Categories v1.1 documentation</title>
|
||||
<link rel="stylesheet" href="_static/default.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '',
|
||||
VERSION: '1.0.5',
|
||||
VERSION: '1.1',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '.html',
|
||||
HAS_SOURCE: true
|
||||
|
|
@ -24,13 +21,13 @@
|
|||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||
<link rel="top" title="Django Categories 1.0.5 documentation" href="index.html" />
|
||||
<link rel="top" title="Django Categories v1.1 documentation" href="index.html" />
|
||||
<link rel="next" title="Registering Models" href="registering_models.html" />
|
||||
<link rel="prev" title="Getting Started" href="getting_started.html" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="docstitle">
|
||||
<p>Django Categories 1.0.5 documentation</p>
|
||||
<p>Django Categories v1.1 documentation</p>
|
||||
</div>
|
||||
<div id="header">
|
||||
<div id="title"><h1>Using categories in templates</h1></div>
|
||||
|
|
@ -172,8 +169,8 @@ keys:</p>
|
|||
<blockquote>
|
||||
<div><dl class="docutils">
|
||||
<dt><tt class="docutils literal"><span class="pre">'new_level'</span></tt></dt>
|
||||
<dd><tt class="docutils literal"><span class="pre">True</span></tt> if the current item is the start of a new level in
|
||||
the tree, <tt class="docutils literal"><span class="pre">False</span></tt> otherwise.</dd>
|
||||
<dd><tt class="xref docutils literal"><span class="pre">True</span></tt> if the current item is the start of a new level in
|
||||
the tree, <tt class="xref docutils literal"><span class="pre">False</span></tt> otherwise.</dd>
|
||||
<dt><tt class="docutils literal"><span class="pre">'closed_levels'</span></tt></dt>
|
||||
<dd>A list of levels which end after the current item. This will
|
||||
be an empty list if the next item’s level is the same as or
|
||||
|
|
@ -210,7 +207,7 @@ on the right:</p>
|
|||
<div class="footer">
|
||||
<p>
|
||||
© Copyright 2010-2012, Corey Oordt.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.2.
|
||||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
|
||||
</p>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# Django settings for sample project.
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
APP = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
PROJ_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
|
@ -75,11 +77,6 @@ STATICFILES_FINDERS = (
|
|||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# URL prefix for admin static files -- CSS, JavaScript and images.
|
||||
# Make sure to use a trailing slash.
|
||||
# Examples: "http://foo.com/static/admin/", "/static/admin/".
|
||||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 'bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d'
|
||||
|
||||
|
|
@ -106,37 +103,27 @@ TEMPLATE_DIRS = (
|
|||
os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates')),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.flatpages',
|
||||
'categories',
|
||||
'categories.editor',
|
||||
'mptt',
|
||||
'simpletext',
|
||||
'south',
|
||||
)
|
||||
|
||||
CATEGORIES_SETTINGS = {
|
||||
'ALLOW_SLUG_CHANGE': True,
|
||||
'RELATION_MODELS': ['simpletext.simpletext','flatpages.flatpage'],
|
||||
'RELATION_MODELS': ['simpletext.simpletext', 'flatpages.flatpage'],
|
||||
'FK_REGISTRY': {
|
||||
'flatpages.flatpage': 'category',
|
||||
'simpletext.simpletext': (
|
||||
'primary_category',
|
||||
'primary_category',
|
||||
{'name': 'secondary_category', 'related_name': 'simpletext_sec_cat'},
|
||||
),
|
||||
},
|
||||
'M2M_REGISTRY': {
|
||||
'simpletext.simpletext': {'name': 'categories', 'related_name': 'm2mcats'},
|
||||
'flatpages.flatpage': (
|
||||
{'name': 'other_categories', 'related_name': 'other_cats'},
|
||||
{'name': 'more_categories', 'related_name': 'more_cats'},
|
||||
{'name': 'other_categories', 'related_name': 'other_cats'},
|
||||
{'name': 'more_categories', 'related_name': 'more_cats'},
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
if django.VERSION[1] == 4:
|
||||
from settings14 import *
|
||||
if django.VERSION[1] == 3:
|
||||
from settings13 import *
|
||||
|
|
|
|||
16
example/settings13.py
Normal file
16
example/settings13.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.flatpages',
|
||||
'categories',
|
||||
'categories.editor',
|
||||
'mptt',
|
||||
'simpletext',
|
||||
# 'south',
|
||||
)
|
||||
15
example/settings14.py
Normal file
15
example/settings14.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
INSTALLED_APPS = (
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.flatpages',
|
||||
'categories',
|
||||
'categories.editor',
|
||||
'mptt',
|
||||
'simpletext',
|
||||
# 'south',
|
||||
)
|
||||
Loading…
Reference in a new issue