diff --git a/LICENSE.txt b/LICENSE.txt
index 57bc88a..261eeb9 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -199,4 +199,3 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
diff --git a/categories/__init__.py b/categories/__init__.py
index 7808fc0..0dad974 100644
--- a/categories/__init__.py
+++ b/categories/__init__.py
@@ -1,23 +1,19 @@
-__version_info__ = {
- 'major': 1,
- 'minor': 8,
- 'micro': 0,
- 'releaselevel': 'final',
- 'serial': 1
-}
+__version_info__ = {"major": 1, "minor": 8, "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__, ]
- if __version_info__['micro'] and not short:
+ assert __version_info__["releaselevel"] in ("alpha", "beta", "final")
+ vers = [
+ "%(major)i.%(minor)i" % __version_info__,
+ ]
+ if __version_info__["micro"] and not short:
vers.append(".%(micro)i" % __version_info__)
- if __version_info__['releaselevel'] != 'final' and not short:
- vers.append('%s%i' % (__version_info__['releaselevel'][0], __version_info__['serial']))
- return ''.join(vers)
+ if __version_info__["releaselevel"] != "final" and not short:
+ vers.append("%s%i" % (__version_info__["releaselevel"][0], __version_info__["serial"]))
+ return "".join(vers)
__version__ = get_version()
-default_app_config = 'categories.apps.CategoriesConfig'
+default_app_config = "categories.apps.CategoriesConfig"
diff --git a/categories/admin.py b/categories/admin.py
index 5c0eaba..5c11755 100644
--- a/categories/admin.py
+++ b/categories/admin.py
@@ -1,17 +1,17 @@
-from django.contrib import admin
from django import forms
+from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
+from .base import CategoryBaseAdmin, CategoryBaseAdminForm
from .genericcollection import GenericCollectionTabularInline
-from .settings import RELATION_MODELS, JAVASCRIPT_URL, REGISTER_ADMIN
from .models import Category
-from .base import CategoryBaseAdminForm, CategoryBaseAdmin
-from .settings import MODEL_REGISTRY
+from .settings import JAVASCRIPT_URL, MODEL_REGISTRY, REGISTER_ADMIN, RELATION_MODELS
class NullTreeNodeChoiceField(forms.ModelChoiceField):
"""A ModelChoiceField for tree nodes."""
- def __init__(self, level_indicator='---', *args, **kwargs):
+
+ def __init__(self, level_indicator="---", *args, **kwargs):
self.level_indicator = level_indicator
super(NullTreeNodeChoiceField, self).__init__(*args, **kwargs)
@@ -20,7 +20,7 @@ class NullTreeNodeChoiceField(forms.ModelChoiceField):
Creates labels which represent the tree level of each node when
generating option labels.
"""
- return '%s %s' % (self.level_indicator * getattr(obj, obj._mptt_meta.level_attr), obj)
+ return "%s %s" % (self.level_indicator * getattr(obj, obj._mptt_meta.level_attr), obj)
if RELATION_MODELS:
@@ -33,38 +33,43 @@ if RELATION_MODELS:
class CategoryAdminForm(CategoryBaseAdminForm):
class Meta:
model = Category
- fields = '__all__'
+ fields = "__all__"
def clean_alternate_title(self):
- if self.instance is None or not self.cleaned_data['alternate_title']:
- return self.cleaned_data['name']
+ if self.instance is None or not self.cleaned_data["alternate_title"]:
+ return self.cleaned_data["name"]
else:
- return self.cleaned_data['alternate_title']
+ return self.cleaned_data["alternate_title"]
class CategoryAdmin(CategoryBaseAdmin):
form = CategoryAdminForm
- list_display = ('name', 'alternate_title', 'active')
+ list_display = ("name", "alternate_title", "active")
fieldsets = (
- (None, {
- 'fields': ('parent', 'name', 'thumbnail', 'active')
- }),
- (_('Meta Data'), {
- 'fields': ('alternate_title', 'alternate_url', 'description',
- 'meta_keywords', 'meta_extra'),
- 'classes': ('collapse',),
- }),
- (_('Advanced'), {
- 'fields': ('order', 'slug'),
- 'classes': ('collapse',),
- }),
+ (None, {"fields": ("parent", "name", "thumbnail", "active")}),
+ (
+ _("Meta Data"),
+ {
+ "fields": ("alternate_title", "alternate_url", "description", "meta_keywords", "meta_extra"),
+ "classes": ("collapse",),
+ },
+ ),
+ (
+ _("Advanced"),
+ {
+ "fields": ("order", "slug"),
+ "classes": ("collapse",),
+ },
+ ),
)
if RELATION_MODELS:
- inlines = [InlineCategoryRelation, ]
+ inlines = [
+ InlineCategoryRelation,
+ ]
class Media:
- js = (JAVASCRIPT_URL + 'genericcollections.js',)
+ js = (JAVASCRIPT_URL + "genericcollections.js",)
if REGISTER_ADMIN:
@@ -72,18 +77,21 @@ if REGISTER_ADMIN:
for model, modeladmin in list(admin.site._registry.items()):
if model in list(MODEL_REGISTRY.values()) and modeladmin.fieldsets:
- fieldsets = getattr(modeladmin, 'fieldsets', ())
- fields = [cat.split('.')[2] for cat in MODEL_REGISTRY if MODEL_REGISTRY[cat] == model]
+ fieldsets = getattr(modeladmin, "fieldsets", ())
+ fields = [cat.split(".")[2] for cat in MODEL_REGISTRY if MODEL_REGISTRY[cat] == model]
# check each field to see if already defined
for cat in fields:
for k, v in fieldsets:
- if cat in v['fields']:
+ if cat in v["fields"]:
fields.remove(cat)
# if there are any fields left, add them under the categories fieldset
if len(fields) > 0:
admin.site.unregister(model)
- admin.site.register(model, type('newadmin', (modeladmin.__class__,), {
- 'fieldsets': fieldsets + (('Categories', {
- 'fields': fields
- }),)
- }))
+ admin.site.register(
+ model,
+ type(
+ "newadmin",
+ (modeladmin.__class__,),
+ {"fieldsets": fieldsets + (("Categories", {"fields": fields}),)},
+ ),
+ )
diff --git a/categories/apps.py b/categories/apps.py
index 02e70e0..1bc058e 100644
--- a/categories/apps.py
+++ b/categories/apps.py
@@ -2,16 +2,18 @@ from django.apps import AppConfig
class CategoriesConfig(AppConfig):
- name = 'categories'
+ name = "categories"
verbose_name = "Categories"
def __init__(self, *args, **kwargs):
super(CategoriesConfig, self).__init__(*args, **kwargs)
from django.db.models.signals import class_prepared
+
class_prepared.connect(handle_class_prepared)
def ready(self):
from django.db.models.signals import post_migrate
+
from .migration import migrate_app
post_migrate.connect(migrate_app)
@@ -21,17 +23,18 @@ def handle_class_prepared(sender, **kwargs):
"""
See if this class needs registering of fields
"""
- from .settings import M2M_REGISTRY, FK_REGISTRY
from .registration import registry
+ from .settings import FK_REGISTRY, M2M_REGISTRY
+
sender_app = sender._meta.app_label
sender_name = sender._meta.model_name
for key, val in list(FK_REGISTRY.items()):
- app_name, model_name = key.split('.')
+ app_name, model_name = key.split(".")
if app_name == sender_app and sender_name == model_name:
- registry.register_model(app_name, sender, 'ForeignKey', val)
+ registry.register_model(app_name, sender, "ForeignKey", val)
for key, val in list(M2M_REGISTRY.items()):
- app_name, model_name = key.split('.')
+ app_name, model_name = key.split(".")
if app_name == sender_app and sender_name == model_name:
- registry.register_model(app_name, sender, 'ManyToManyField', val)
+ registry.register_model(app_name, sender, "ManyToManyField", val)
diff --git a/categories/base.py b/categories/base.py
index 29319f4..9517565 100644
--- a/categories/base.py
+++ b/categories/base.py
@@ -4,25 +4,23 @@ with customizable metadata and its own name space.
"""
import sys
+from django import forms
from django.contrib import admin
from django.db import models
-from django import forms
from django.utils.encoding import force_text
-
-from mptt.models import MPTTModel
+from django.utils.translation import ugettext_lazy as _
from mptt.fields import TreeForeignKey
from mptt.managers import TreeManager
+from mptt.models import MPTTModel
from slugify import slugify
from .editor.tree_editor import TreeEditor
from .settings import ALLOW_SLUG_CHANGE, SLUG_TRANSLITERATOR
-from django.utils.translation import ugettext_lazy as _
-
-
if sys.version_info[0] < 3: # Remove this after dropping support of Python 2
from django.utils.encoding import python_2_unicode_compatible
else:
+
def python_2_unicode_compatible(x):
return x
@@ -31,6 +29,7 @@ class CategoryManager(models.Manager):
"""
A manager that adds an "active()" method for all active categories
"""
+
def active(self):
"""
Only categories that are active
@@ -44,17 +43,18 @@ 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',
+ "self",
on_delete=models.CASCADE,
blank=True,
null=True,
- related_name='children',
- verbose_name=_('parent'),
+ related_name="children",
+ verbose_name=_("parent"),
)
- name = models.CharField(max_length=100, verbose_name=_('name'))
- slug = models.SlugField(verbose_name=_('slug'))
- active = models.BooleanField(default=True, verbose_name=_('active'))
+ name = models.CharField(max_length=100, verbose_name=_("name"))
+ slug = models.SlugField(verbose_name=_("slug"))
+ active = models.BooleanField(default=True, verbose_name=_("active"))
objects = CategoryManager()
tree = TreeManager()
@@ -78,23 +78,28 @@ class CategoryBase(MPTTModel):
def __str__(self):
ancestors = self.get_ancestors()
- return ' > '.join([force_text(i.name) for i in ancestors] + [self.name, ])
+ return " > ".join(
+ [force_text(i.name) for i in ancestors]
+ + [
+ self.name,
+ ]
+ )
class Meta:
abstract = True
- unique_together = ('parent', 'name')
- ordering = ('tree_id', 'lft')
+ unique_together = ("parent", "name")
+ ordering = ("tree_id", "lft")
class MPTTMeta:
- order_insertion_by = 'name'
+ order_insertion_by = "name"
class CategoryBaseAdminForm(forms.ModelForm):
def clean_slug(self):
- if not self.cleaned_data.get('slug', None):
+ if not self.cleaned_data.get("slug", None):
if self.instance is None or not ALLOW_SLUG_CHANGE:
- self.cleaned_data['slug'] = slugify(SLUG_TRANSLITERATOR(self.cleaned_data['name']))
- return self.cleaned_data['slug'][:50]
+ self.cleaned_data["slug"] = slugify(SLUG_TRANSLITERATOR(self.cleaned_data["name"]))
+ return self.cleaned_data["slug"][:50]
def clean(self):
@@ -107,72 +112,71 @@ class CategoryBaseAdminForm(forms.ModelForm):
# Validate slug is valid in that level
kwargs = {}
- if self.cleaned_data.get('parent', None) is None:
- kwargs['parent__isnull'] = True
+ if self.cleaned_data.get("parent", None) is None:
+ kwargs["parent__isnull"] = True
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') 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.'))
+ 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") 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
# its parent.
- if self.cleaned_data.get('parent', None) is None or self.instance.id is None:
+ if self.cleaned_data.get("parent", None) is None or self.instance.id is None:
return self.cleaned_data
if self.instance.pk:
- decendant_ids = self.instance.get_descendants().values_list('id', flat=True)
+ decendant_ids = self.instance.get_descendants().values_list("id", flat=True)
else:
decendant_ids = []
- if self.cleaned_data['parent'].id == self.instance.id:
- raise forms.ValidationError(_("You can't set the parent of the "
- "item to itself."))
- elif self.cleaned_data['parent'].id in decendant_ids:
- raise forms.ValidationError(_("You can't set the parent of the "
- "item to a descendant."))
+ if self.cleaned_data["parent"].id == self.instance.id:
+ raise forms.ValidationError(_("You can't set the parent of the " "item to itself."))
+ elif self.cleaned_data["parent"].id in decendant_ids:
+ raise forms.ValidationError(_("You can't set the parent of the " "item to a descendant."))
return self.cleaned_data
class CategoryBaseAdmin(TreeEditor, admin.ModelAdmin):
form = CategoryBaseAdminForm
- list_display = ('name', 'active')
- search_fields = ('name',)
- prepopulated_fields = {'slug': ('name',)}
+ list_display = ("name", "active")
+ search_fields = ("name",)
+ prepopulated_fields = {"slug": ("name",)}
- actions = ['activate', 'deactivate']
+ actions = ["activate", "deactivate"]
def get_actions(self, request):
actions = super(CategoryBaseAdmin, self).get_actions(request)
- if 'delete_selected' in actions:
- del actions['delete_selected']
+ 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')])
+ 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')
+
+ 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')])
+ 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()
item.children.all().update(active=True)
- activate.short_description = _('Activate selected categories and their children')
+
+ activate.short_description = _("Activate selected categories and their children")
diff --git a/categories/editor/settings.py b/categories/editor/settings.py
index af293e5..5ea2e61 100644
--- a/categories/editor/settings.py
+++ b/categories/editor/settings.py
@@ -1,13 +1,13 @@
-from django.conf import settings
import django
+from django.conf import settings
DJANGO10_COMPAT = django.VERSION[0] < 1 or (django.VERSION[0] == 1 and django.VERSION[1] < 1)
-STATIC_URL = getattr(settings, 'STATIC_URL', settings.MEDIA_URL)
+STATIC_URL = getattr(settings, "STATIC_URL", settings.MEDIA_URL)
if STATIC_URL is None:
STATIC_URL = settings.MEDIA_URL
-MEDIA_PATH = getattr(settings, 'EDITOR_MEDIA_PATH', '%seditor/' % STATIC_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")
-IS_GRAPPELLI_INSTALLED = 'grappelli' in settings.INSTALLED_APPS
+IS_GRAPPELLI_INSTALLED = "grappelli" in settings.INSTALLED_APPS
diff --git a/categories/editor/static/editor/jquery.treeTable.css b/categories/editor/static/editor/jquery.treeTable.css
index 9d9a263..07421f1 100644
--- a/categories/editor/static/editor/jquery.treeTable.css
+++ b/categories/editor/static/editor/jquery.treeTable.css
@@ -66,4 +66,4 @@
.treeTable .ui-draggable-dragging {
color: #000;
z-index: 1;
-}
\ No newline at end of file
+}
diff --git a/categories/editor/static/editor/jquery.treeTable.js b/categories/editor/static/editor/jquery.treeTable.js
index 38f7bcb..ea2a88b 100644
--- a/categories/editor/static/editor/jquery.treeTable.js
+++ b/categories/editor/static/editor/jquery.treeTable.js
@@ -460,4 +460,4 @@
function parentOf(node) {
return $(node).parentOf();
}
-})(django.jQuery);
\ No newline at end of file
+})(django.jQuery);
diff --git a/categories/editor/templates/admin/editor/grappelli_tree_list_results.html b/categories/editor/templates/admin/editor/grappelli_tree_list_results.html
index 379471e..f5b5e5b 100644
--- a/categories/editor/templates/admin/editor/grappelli_tree_list_results.html
+++ b/categories/editor/templates/admin/editor/grappelli_tree_list_results.html
@@ -25,4 +25,4 @@
-{% endif %}
\ No newline at end of file
+{% endif %}
diff --git a/categories/editor/templates/admin/editor/tree_editor.html b/categories/editor/templates/admin/editor/tree_editor.html
index 9179640..337da05 100644
--- a/categories/editor/templates/admin/editor/tree_editor.html
+++ b/categories/editor/templates/admin/editor/tree_editor.html
@@ -36,4 +36,4 @@
{% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
{% result_tree_list cl %}
{% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/categories/editor/templatetags/admin_tree_list_tags.py b/categories/editor/templatetags/admin_tree_list_tags.py
index 6ef6e95..160752b 100644
--- a/categories/editor/templatetags/admin_tree_list_tags.py
+++ b/categories/editor/templatetags/admin_tree_list_tags.py
@@ -1,29 +1,30 @@
import django
+from django.contrib.admin.templatetags.admin_list import _boolean_icon, result_headers
+from django.contrib.admin.utils import lookup_field
+from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.template import Library
-from django.contrib.admin.templatetags.admin_list import result_headers, _boolean_icon
-from django.contrib.admin.utils import lookup_field
-from categories.editor.utils import display_for_field
-from django.core.exceptions import ObjectDoesNotExist
-from django.utils.encoding import smart_text, force_text
-from django.utils.html import escape, conditional_escape, escapejs, format_html
+from django.utils.encoding import force_text, smart_text
+from django.utils.html import conditional_escape, escape, escapejs, format_html
from django.utils.safestring import mark_safe
from categories.editor import settings
+from categories.editor.utils import display_for_field
register = Library()
-TREE_LIST_RESULTS_TEMPLATE = 'admin/editor/tree_list_results.html'
+TREE_LIST_RESULTS_TEMPLATE = "admin/editor/tree_list_results.html"
if settings.IS_GRAPPELLI_INSTALLED:
- TREE_LIST_RESULTS_TEMPLATE = 'admin/editor/grappelli_tree_list_results.html'
+ TREE_LIST_RESULTS_TEMPLATE = "admin/editor/grappelli_tree_list_results.html"
def get_empty_value_display(cl):
- if hasattr(cl.model_admin, 'get_empty_value_display'):
+ if hasattr(cl.model_admin, "get_empty_value_display"):
return cl.model_admin.get_empty_value_display()
else:
# Django < 1.9
from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
+
return EMPTY_CHANGELIST_VALUE
@@ -34,7 +35,7 @@ def items_for_tree_result(cl, result, form):
first = True
pk = cl.lookup_opts.pk.attname
for field_name in cl.list_display:
- row_class = ''
+ row_class = ""
try:
f, attr, value = lookup_field(field_name, result, cl.model_admin)
except (AttributeError, ObjectDoesNotExist):
@@ -42,10 +43,10 @@ def items_for_tree_result(cl, result, form):
else:
if f is None:
if django.VERSION[0] == 1 and django.VERSION[1] == 4:
- if field_name == 'action_checkbox':
+ if field_name == "action_checkbox":
row_class = ' class="action-checkbox disclosure"'
- allow_tags = getattr(attr, 'allow_tags', False)
- boolean = getattr(attr, 'boolean', False)
+ allow_tags = getattr(attr, "allow_tags", False)
+ boolean = getattr(attr, "boolean", False)
if boolean:
allow_tags = True
result_repr = _boolean_icon(value)
@@ -60,16 +61,16 @@ def items_for_tree_result(cl, result, form):
else:
if value is None:
result_repr = get_empty_value_display(cl)
- if hasattr(f, 'rel') and isinstance(f.rel, models.ManyToOneRel):
+ if hasattr(f, "rel") and isinstance(f.rel, models.ManyToOneRel):
result_repr = escape(getattr(result, f.name))
else:
- result_repr = display_for_field(value, f, '')
+ result_repr = display_for_field(value, f, "")
if isinstance(f, models.DateField) or isinstance(f, models.TimeField):
row_class = ' class="nowrap"'
if first:
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
try:
- f, attr, checkbox_value = lookup_field('action_checkbox', result, cl.model_admin)
+ f, attr, checkbox_value = lookup_field("action_checkbox", result, cl.model_admin)
if row_class:
row_class = "%s%s" % (row_class[:-1], ' disclosure"')
else:
@@ -77,14 +78,14 @@ def items_for_tree_result(cl, result, form):
except (AttributeError, ObjectDoesNotExist):
pass
- if force_text(result_repr) == '':
- result_repr = mark_safe(' ')
+ if force_text(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:
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
- table_tag = 'td' # {True:'th', False:'td'}[first]
+ table_tag = "td" # {True:'th', False:'td'}[first]
else:
- table_tag = {True: 'th', False: 'td'}[first]
+ table_tag = {True: "th", False: "td"}[first]
url = cl.url_for_result(result)
# Convert the pk to something that can be used in Javascript.
@@ -104,9 +105,14 @@ def items_for_tree_result(cl, result, form):
row_class,
url,
format_html(
- ' onclick="opener.dismissRelatedLookupPopup(window, '
- ''{}'); return false;"', result_id
- ) if cl.is_popup else '', result_repr, table_tag)
+ ' onclick="opener.dismissRelatedLookupPopup(window, ' ''{}'); return false;"',
+ result_id,
+ )
+ if cl.is_popup
+ else "",
+ result_repr,
+ table_tag,
+ )
)
else:
@@ -118,9 +124,9 @@ def items_for_tree_result(cl, result, form):
result_repr = mark_safe(force_text(bf.errors) + force_text(bf))
else:
result_repr = conditional_escape(result_repr)
- yield mark_safe(smart_text('
%s | ' % (row_class, result_repr)))
+ yield mark_safe(smart_text("%s | " % (row_class, result_repr)))
if form and not form[cl.model._meta.pk.name].is_hidden:
- yield mark_safe(smart_text('%s | ' % force_text(form[cl.model._meta.pk.name])))
+ yield mark_safe(smart_text("%s | " % force_text(form[cl.model._meta.pk.name])))
class TreeList(list):
@@ -131,7 +137,7 @@ def tree_results(cl):
if cl.formset:
for res, form in zip(cl.result_list, cl.formset.forms):
result = TreeList(items_for_tree_result(cl, res, form))
- if hasattr(res, 'pk'):
+ if hasattr(res, "pk"):
result.pk = res.pk
if res.parent:
result.parent_pk = res.parent.pk
@@ -141,7 +147,7 @@ def tree_results(cl):
else:
for res in cl.result_list:
result = TreeList(items_for_tree_result(cl, res, None))
- if hasattr(res, 'pk'):
+ if hasattr(res, "pk"):
result.pk = res.pk
if res.parent:
result.parent_pk = res.parent.pk
@@ -155,14 +161,12 @@ def result_tree_list(cl):
Displays the headers and data list together
"""
import django
- result = {
- 'cl': cl,
- 'result_headers': list(result_headers(cl)),
- 'results': list(tree_results(cl))
- }
+
+ result = {"cl": cl, "result_headers": list(result_headers(cl)), "results": list(tree_results(cl))}
if django.VERSION[0] == 1 and django.VERSION[1] > 2:
from django.contrib.admin.templatetags.admin_list import result_hidden_fields
- result['result_hidden_fields'] = list(result_hidden_fields(cl))
+
+ result["result_hidden_fields"] = list(result_hidden_fields(cl))
return result
diff --git a/categories/editor/tree_editor.py b/categories/editor/tree_editor.py
index f832df5..45c70d1 100644
--- a/categories/editor/tree_editor.py
+++ b/categories/editor/tree_editor.py
@@ -1,12 +1,11 @@
-from django.contrib import admin
-from django.db.models.query import QuerySet
-from django.contrib.admin.views.main import ChangeList
-from django.http import HttpResponseRedirect
-from django.utils.translation import ugettext_lazy as _
-from django.contrib.admin.options import IncorrectLookupParameters
-from django.shortcuts import render
-
import django
+from django.contrib import admin
+from django.contrib.admin.options import IncorrectLookupParameters
+from django.contrib.admin.views.main import ChangeList
+from django.db.models.query import QuerySet
+from django.http import HttpResponseRedirect
+from django.shortcuts import render
+from django.utils.translation import ugettext_lazy as _
from . import settings
@@ -24,6 +23,7 @@ class TreeEditorQuerySet(QuerySet):
in the result set, so the resulting tree display actually
makes sense.
"""
+
def iterator(self):
qs = self
# Reaching into the bowels of query sets to find out whether the qs is
@@ -36,9 +36,9 @@ class TreeEditorQuerySet(QuerySet):
# this cuts down the number of queries considerably since all ancestors
# will already be in include_pages when they are checked, thus not
# trigger additional queries.
- for p in super(TreeEditorQuerySet, self.order_by('rght')).iterator():
+ for p in super(TreeEditorQuerySet, self.order_by("rght")).iterator():
if p.parent_id and p.parent_id not in include_pages and p.id not in include_pages:
- ancestor_id_list = p.get_ancestors().values_list('id', flat=True)
+ ancestor_id_list = p.get_ancestors().values_list("id", flat=True)
include_pages.update(ancestor_id_list)
if include_pages:
@@ -68,18 +68,18 @@ class TreeEditorQuerySet(QuerySet):
class TreeChangeList(ChangeList):
def _get_default_ordering(self):
if django.VERSION[0] == 1 and 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[0] == 1 and django.VERSION[1] < 4:
- return '', '' # ('tree_id', 'lft')
+ return "", "" # ('tree_id', 'lft')
else:
return []
def get_queryset(self, *args, **kwargs):
- qs = super(TreeChangeList, self).get_queryset(*args, **kwargs).order_by('tree_id', 'lft')
+ qs = super(TreeChangeList, self).get_queryset(*args, **kwargs).order_by("tree_id", "lft")
return qs
@@ -88,18 +88,18 @@ class TreeEditor(admin.ModelAdmin):
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')
+ if "action_checkbox" in self.list_display:
+ self.list_display.remove("action_checkbox")
opts = self.model._meta
@@ -108,9 +108,9 @@ class TreeEditor(admin.ModelAdmin):
grappelli_prefix = "grappelli_"
self.change_list_template = [
- 'admin/%s/%s/editor/%stree_editor.html' % (opts.app_label, opts.object_name.lower(), grappelli_prefix),
- 'admin/%s/editor/%stree_editor.html' % (opts.app_label, grappelli_prefix),
- 'admin/editor/%stree_editor.html' % grappelli_prefix,
+ "admin/%s/%s/editor/%stree_editor.html" % (opts.app_label, opts.object_name.lower(), grappelli_prefix),
+ "admin/%s/editor/%stree_editor.html" % (opts.app_label, grappelli_prefix),
+ "admin/editor/%stree_editor.html" % grappelli_prefix,
]
def get_changelist(self, request, **kwargs):
@@ -125,6 +125,7 @@ class TreeEditor(admin.ModelAdmin):
from django.core.exceptions import PermissionDenied
from django.utils.encoding import force_text
from django.utils.translation import ungettext
+
opts = self.model._meta
app_label = opts.app_label
if not self.has_change_permission(request, None):
@@ -137,31 +138,56 @@ class TreeEditor(admin.ModelAdmin):
list_display = list(self.list_display)
if not actions:
try:
- list_display.remove('action_checkbox')
+ list_display.remove("action_checkbox")
except ValueError:
pass
try:
if django.VERSION[0] == 1 and 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)
+ 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,
+ )
elif django.VERSION[0] == 1 or (django.VERSION[0] == 2 and django.VERSION[1] < 1):
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)
+ 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,
+ )
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,
- self.list_editable, self, self.sortable_by)
+ 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,
+ self.sortable_by,
+ )
cl = TreeChangeList(*params)
except IncorrectLookupParameters:
# Wacky lookup parameters were given, so redirect to the main
@@ -170,15 +196,13 @@ class TreeEditor(admin.ModelAdmin):
# the 'invalid=1' parameter was already in the query string, something
# is screwed up with the database, so display an error page.
if ERROR_FLAG in list(request.GET.keys()):
- return render(
- request,
- 'admin/invalid_setup.html', {'title': _('Database error')})
- return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
+ return render(request, "admin/invalid_setup.html", {"title": _("Database error")})
+ return HttpResponseRedirect(request.path + "?" + ERROR_FLAG + "=1")
# If the request was POSTed, this might be a bulk action or a bulk edit.
# Try to look up an action first, but if this isn't an action the POST
# will fall through to the bulk edit check, below.
- if actions and request.method == 'POST':
+ if actions and request.method == "POST":
response = self.response_action(request, queryset=cl.get_queryset())
if response:
return response
@@ -191,9 +215,7 @@ class TreeEditor(admin.ModelAdmin):
# Handle POSTed bulk-edit data.
if request.method == "POST" and self.list_editable:
FormSet = self.get_changelist_formset(request)
- formset = cl.formset = FormSet(
- request.POST, request.FILES, queryset=cl.result_list
- )
+ formset = cl.formset = FormSet(request.POST, request.FILES, queryset=cl.result_list)
if formset.is_valid():
changecount = 0
for form in formset.forms:
@@ -213,9 +235,8 @@ class TreeEditor(admin.ModelAdmin):
msg = ungettext(
"%(count)s %(name)s was changed successfully.",
"%(count)s %(name)s were changed successfully.",
- changecount) % {'count': changecount,
- 'name': name,
- 'obj': force_text(obj)}
+ changecount,
+ ) % {"count": changecount, "name": name, "obj": force_text(obj)}
self.message_user(request, msg)
return HttpResponseRedirect(request.get_full_path())
@@ -234,40 +255,47 @@ class TreeEditor(admin.ModelAdmin):
# Build the action form and populate it with available actions.
if actions:
action_form = self.action_form(auto_id=None)
- action_form.fields['action'].choices = self.get_action_choices(request)
+ action_form.fields["action"].choices = self.get_action_choices(request)
else:
action_form = None
context = {
- 'title': cl.title,
- 'is_popup': cl.is_popup,
- 'cl': cl,
- 'media': media,
- 'has_add_permission': self.has_add_permission(request),
- 'app_label': app_label,
- 'action_form': action_form,
- 'actions_on_top': self.actions_on_top,
- 'actions_on_bottom': self.actions_on_bottom,
+ "title": cl.title,
+ "is_popup": cl.is_popup,
+ "cl": cl,
+ "media": media,
+ "has_add_permission": self.has_add_permission(request),
+ "app_label": app_label,
+ "action_form": action_form,
+ "actions_on_top": self.actions_on_top,
+ "actions_on_bottom": self.actions_on_bottom,
}
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
- context['root_path'] = self.admin_site.root_path
+ context["root_path"] = self.admin_site.root_path
elif django.VERSION[0] == 1 or (django.VERSION[0] == 2 and django.VERSION[1] < 1):
- selection_note_all = ungettext('%(total_count)s selected', 'All %(total_count)s selected', cl.result_count)
+ selection_note_all = ungettext("%(total_count)s selected", "All %(total_count)s selected", cl.result_count)
- context.update({
- 'module_name': force_text(opts.verbose_name_plural),
- 'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
- 'selection_note_all': selection_note_all % {'total_count': cl.result_count},
- })
+ context.update(
+ {
+ "module_name": force_text(opts.verbose_name_plural),
+ "selection_note": _("0 of %(cnt)s selected") % {"cnt": len(cl.result_list)},
+ "selection_note_all": selection_note_all % {"total_count": cl.result_count},
+ }
+ )
else:
- context['opts'] = self.model._meta
+ context["opts"] = self.model._meta
context.update(extra_context or {})
- return render(request, self.change_list_template or [
- 'admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()),
- 'admin/%s/change_list.html' % app_label,
- 'admin/change_list.html'
- ], context=context)
+ return render(
+ request,
+ self.change_list_template
+ or [
+ "admin/%s/%s/change_list.html" % (app_label, opts.object_name.lower()),
+ "admin/%s/change_list.html" % app_label,
+ "admin/change_list.html",
+ ],
+ context=context,
+ )
def changelist_view(self, request, extra_context=None, *args, **kwargs):
"""
@@ -275,8 +303,8 @@ class TreeEditor(admin.ModelAdmin):
change list/actions page.
"""
extra_context = extra_context or {}
- extra_context['EDITOR_MEDIA_PATH'] = settings.MEDIA_PATH
- extra_context['EDITOR_TREE_INITIAL_STATE'] = settings.TREE_INITIAL_STATE
+ extra_context["EDITOR_MEDIA_PATH"] = settings.MEDIA_PATH
+ extra_context["EDITOR_TREE_INITIAL_STATE"] = settings.TREE_INITIAL_STATE
# FIXME
return self.old_changelist_view(request, extra_context)
diff --git a/categories/fields.py b/categories/fields.py
index 1926de9..719b72e 100644
--- a/categories/fields.py
+++ b/categories/fields.py
@@ -4,21 +4,24 @@ from django.db.models import ForeignKey, ManyToManyField
class CategoryM2MField(ManyToManyField):
def __init__(self, **kwargs):
from .models import Category
- if 'to' in kwargs:
- kwargs.pop('to')
+
+ if "to" in kwargs:
+ kwargs.pop("to")
super(CategoryM2MField, self).__init__(to=Category, **kwargs)
class CategoryFKField(ForeignKey):
def __init__(self, **kwargs):
from .models import Category
- if 'to' in kwargs:
- kwargs.pop('to')
+
+ if "to" in kwargs:
+ kwargs.pop("to")
super(CategoryFKField, self).__init__(to=Category, **kwargs)
try:
from south.modelsinspector import add_introspection_rules
+
add_introspection_rules([], [r"^categories\.fields\.CategoryFKField"])
add_introspection_rules([], [r"^categories\.fields\.CategoryM2MField"])
except ImportError:
diff --git a/categories/fixtures/musicgenres.json b/categories/fixtures/musicgenres.json
index b832884..3817510 100644
--- a/categories/fixtures/musicgenres.json
+++ b/categories/fixtures/musicgenres.json
@@ -4414,4 +4414,4 @@
}
}
-]
\ No newline at end of file
+]
diff --git a/categories/fixtures/test_category_spaces.txt b/categories/fixtures/test_category_spaces.txt
index 025edbe..85852b5 100644
--- a/categories/fixtures/test_category_spaces.txt
+++ b/categories/fixtures/test_category_spaces.txt
@@ -5,4 +5,4 @@ Category 2
Category 2-1
Category 2-1-1
Category 3
- Category 3-1
\ No newline at end of file
+ Category 3-1
diff --git a/categories/fixtures/test_category_tabs.txt b/categories/fixtures/test_category_tabs.txt
index 207a634..8ded421 100644
--- a/categories/fixtures/test_category_tabs.txt
+++ b/categories/fixtures/test_category_tabs.txt
@@ -5,4 +5,4 @@ Category 2
Category 2-1
Category 2-1-1
Category 3
- Category 3-1
\ No newline at end of file
+ Category 3-1
diff --git a/categories/genericcollection.py b/categories/genericcollection.py
index ffa01a0..1745914 100644
--- a/categories/genericcollection.py
+++ b/categories/genericcollection.py
@@ -1,7 +1,8 @@
+import json
+
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
-from django.urls import reverse, NoReverseMatch
-import json
+from django.urls import NoReverseMatch, reverse
class GenericCollectionInlineModelAdmin(admin.options.InlineModelAdmin):
@@ -9,7 +10,7 @@ class GenericCollectionInlineModelAdmin(admin.options.InlineModelAdmin):
ct_fk_field = "object_id"
def get_content_types(self):
- ctypes = ContentType.objects.all().order_by('id').values_list('id', 'app_label', 'model')
+ ctypes = ContentType.objects.all().order_by("id").values_list("id", "app_label", "model")
elements = {}
for x, y, z in ctypes:
try:
@@ -25,12 +26,12 @@ class GenericCollectionInlineModelAdmin(admin.options.InlineModelAdmin):
return result
class Media:
- js = ('contentrelations/js/genericlookup.js', )
+ js = ("contentrelations/js/genericlookup.js",)
class GenericCollectionTabularInline(GenericCollectionInlineModelAdmin):
- template = 'admin/edit_inline/gen_coll_tabular.html'
+ template = "admin/edit_inline/gen_coll_tabular.html"
class GenericCollectionStackedInline(GenericCollectionInlineModelAdmin):
- template = 'admin/edit_inline/gen_coll_stacked.html'
+ template = "admin/edit_inline/gen_coll_stacked.html"
diff --git a/categories/locale/it/LC_MESSAGES/django.po b/categories/locale/it/LC_MESSAGES/django.po
index 1186eef..32f3f2d 100644
--- a/categories/locale/it/LC_MESSAGES/django.po
+++ b/categories/locale/it/LC_MESSAGES/django.po
@@ -181,4 +181,3 @@ msgstr "Cancella?"
#: templates/admin/edit_inline/gen_coll_tabular.html:24
msgid "View on site"
msgstr "Vedi sul sito"
-
diff --git a/categories/management/commands/add_category_fields.py b/categories/management/commands/add_category_fields.py
index 4d44c4d..377f5e5 100644
--- a/categories/management/commands/add_category_fields.py
+++ b/categories/management/commands/add_category_fields.py
@@ -5,13 +5,14 @@ class Command(BaseCommand):
"""
Alter one or more models' tables with the registered attributes
"""
+
help = "Alter the tables for all registered models, or just specified models"
args = "[appname ...]"
can_import_settings = True
requires_system_checks = False
def add_arguments(self, parser):
- parser.add_argument('app_names', nargs='*')
+ parser.add_argument("app_names", nargs="*")
def handle(self, *args, **options):
"""
@@ -20,8 +21,9 @@ class Command(BaseCommand):
from categories.migration import migrate_app
from categories.settings import MODEL_REGISTRY
- if options['app_names']:
- for app in options['app_names']:
+
+ if options["app_names"]:
+ for app in options["app_names"]:
migrate_app(None, app)
else:
for app in MODEL_REGISTRY:
diff --git a/categories/management/commands/drop_category_field.py b/categories/management/commands/drop_category_field.py
index cc4850e..f10a220 100644
--- a/categories/management/commands/drop_category_field.py
+++ b/categories/management/commands/drop_category_field.py
@@ -1,27 +1,28 @@
-from django.core.management.base import BaseCommand
-from django.core.management.base import CommandError
+from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
"""
Alter one or more models' tables with the registered attributes
"""
+
help = "Drop the given field from the given model's table"
args = "appname modelname fieldname"
can_import_settings = True
requires_system_checks = False
def add_arguments(self, parser):
- parser.add_argument('app_name')
- parser.add_argument('model_name')
- parser.add_argument('field_name')
+ parser.add_argument("app_name")
+ parser.add_argument("model_name")
+ parser.add_argument("field_name")
def handle(self, *args, **options):
"""
Alter the tables
"""
from categories.migration import drop_field
- if 'app_name' not in options or 'model_name' not in options or 'field_name' not in options:
+
+ if "app_name" not in options or "model_name" not in options or "field_name" not in options:
raise CommandError("You must specify an Application name, a Model name and a Field name")
- drop_field(options['app_name'], options['model_name'], options['field_name'])
+ drop_field(options["app_name"], options["model_name"], options["field_name"])
diff --git a/categories/management/commands/import_categories.py b/categories/management/commands/import_categories.py
index a899e50..6009afb 100644
--- a/categories/management/commands/import_categories.py
+++ b/categories/management/commands/import_categories.py
@@ -1,6 +1,5 @@
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
-
from slugify import slugify
from categories.models import Category
@@ -10,7 +9,9 @@ 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."
+ 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):
@@ -19,13 +20,13 @@ class Command(BaseCommand):
"""
indent_amt = 0
- if string[0] == '\t':
- return '\t'
+ if string[0] == "\t":
+ return "\t"
for char in string:
- if char == ' ':
+ if char == " ":
indent_amt += 1
else:
- return ' ' * indent_amt
+ return " " * indent_amt
@transaction.atomic
def make_category(self, string, parent=None, order=1):
@@ -36,9 +37,9 @@ class Command(BaseCommand):
name=string.strip(),
slug=slugify(SLUG_TRANSLITERATOR(string.strip()))[:49],
# arent=parent,
- order=order
+ order=order,
)
- cat._tree_manager.insert_node(cat, parent, 'last-child', True)
+ cat._tree_manager.insert_node(cat, parent, "last-child", True)
cat.save()
if parent:
parent.rght = cat.rght + 1
@@ -49,10 +50,10 @@ class Command(BaseCommand):
"""
Do the work of parsing each line
"""
- indent = ''
+ indent = ""
level = 0
- if lines[0][0] == ' ' or lines[0][0] == '\t':
+ 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
@@ -61,8 +62,8 @@ class Command(BaseCommand):
for line in lines:
if len(line) == 0:
continue
- if line[0] == ' ' or line[0] == '\t':
- if indent == '':
+ if line[0] == " " or line[0] == "\t":
+ if indent == "":
indent = self.get_indent(line)
elif not line[0] in indent:
raise CommandError("You can't mix spaces and tabs for indents")
@@ -83,7 +84,7 @@ class Command(BaseCommand):
if not os.path.isfile(file_path):
print("File %s not found." % file_path)
continue
- f = open(file_path, 'r')
+ f = open(file_path, "r")
data = f.readlines()
f.close()
diff --git a/categories/migration.py b/categories/migration.py
index 407a796..77358a5 100644
--- a/categories/migration.py
+++ b/categories/migration.py
@@ -1,8 +1,7 @@
-# -*- coding: utf-8 -*-
-from django.db import connection, transaction
from django.apps import apps
+from django.db import connection, transaction
from django.db.utils import ProgrammingError
@@ -25,7 +24,7 @@ def field_exists(app_name, model_name, field_name):
# Return True if the many to many table exists
field = model._meta.get_field(field_name)
- if hasattr(field, 'm2m_db_table'):
+ if hasattr(field, "m2m_db_table"):
m2m_table_name = field.m2m_db_table()
m2m_field_info = connection.introspection.get_table_description(cursor, m2m_table_name)
if m2m_field_info:
@@ -50,9 +49,10 @@ def migrate_app(sender, *args, **kwargs):
Migrate all models of this app registered
"""
from .registration import registry
- if 'app_config' not in kwargs:
+
+ if "app_config" not in kwargs:
return
- app_config = kwargs['app_config']
+ app_config = kwargs["app_config"]
app_name = app_config.label
@@ -60,7 +60,7 @@ def migrate_app(sender, *args, **kwargs):
sid = transaction.savepoint()
for fld in fields:
- model_name, field_name = fld.split('.')[1:]
+ model_name, field_name = fld.split(".")[1:]
if field_exists(app_name, model_name, field_name):
continue
model = app_config.get_model(model_name)
diff --git a/categories/migrations/0001_initial.py b/categories/migrations/0001_initial.py
index b58fabc..883fd62 100644
--- a/categories/migrations/0001_initial.py
+++ b/categories/migrations/0001_initial.py
@@ -1,59 +1,123 @@
-# -*- coding: utf-8 -*-
-from django.db import models, migrations
import django.core.files.storage
import mptt.fields
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('contenttypes', '0001_initial'),
+ ("contenttypes", "0001_initial"),
]
operations = [
migrations.CreateModel(
- name='Category',
+ name="Category",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(max_length=100, verbose_name='name')),
- ('slug', models.SlugField(verbose_name='slug')),
- ('active', models.BooleanField(default=True, verbose_name='active')),
- ('thumbnail', models.FileField(storage=django.core.files.storage.FileSystemStorage(), null=True, upload_to='uploads/categories/thumbnails', blank=True)),
- ('thumbnail_width', models.IntegerField(null=True, blank=True)),
- ('thumbnail_height', models.IntegerField(null=True, blank=True)),
- ('order', models.IntegerField(default=0)),
- ('alternate_title', models.CharField(default='', help_text='An alternative title to use on pages with this category.', max_length=100, blank=True)),
- ('alternate_url', models.CharField(help_text='An alternative URL to use instead of the one derived from the category hierarchy.', max_length=200, blank=True)),
- ('description', models.TextField(null=True, blank=True)),
- ('meta_keywords', models.CharField(default='', help_text='Comma-separated keywords for search engines.', max_length=255, blank=True)),
- ('meta_extra', models.TextField(default='', help_text='(Advanced) Any additional HTML to be placed verbatim in the <head>', blank=True)),
- ('lft', models.PositiveIntegerField(editable=False, db_index=True)),
- ('rght', models.PositiveIntegerField(editable=False, db_index=True)),
- ('tree_id', models.PositiveIntegerField(editable=False, db_index=True)),
- ('level', models.PositiveIntegerField(editable=False, db_index=True)),
- ('parent', mptt.fields.TreeForeignKey(related_name='children', verbose_name='parent', blank=True, to='categories.Category', on_delete=models.CASCADE, null=True)),
+ ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
+ ("name", models.CharField(max_length=100, verbose_name="name")),
+ ("slug", models.SlugField(verbose_name="slug")),
+ ("active", models.BooleanField(default=True, verbose_name="active")),
+ (
+ "thumbnail",
+ models.FileField(
+ storage=django.core.files.storage.FileSystemStorage(),
+ null=True,
+ upload_to="uploads/categories/thumbnails",
+ blank=True,
+ ),
+ ),
+ ("thumbnail_width", models.IntegerField(null=True, blank=True)),
+ ("thumbnail_height", models.IntegerField(null=True, blank=True)),
+ ("order", models.IntegerField(default=0)),
+ (
+ "alternate_title",
+ models.CharField(
+ default="",
+ help_text="An alternative title to use on pages with this category.",
+ max_length=100,
+ blank=True,
+ ),
+ ),
+ (
+ "alternate_url",
+ models.CharField(
+ help_text="An alternative URL to use instead of the one derived from the category hierarchy.",
+ max_length=200,
+ blank=True,
+ ),
+ ),
+ ("description", models.TextField(null=True, blank=True)),
+ (
+ "meta_keywords",
+ models.CharField(
+ default="",
+ help_text="Comma-separated keywords for search engines.",
+ max_length=255,
+ blank=True,
+ ),
+ ),
+ (
+ "meta_extra",
+ models.TextField(
+ default="",
+ help_text="(Advanced) Any additional HTML to be placed verbatim in the <head>",
+ blank=True,
+ ),
+ ),
+ ("lft", models.PositiveIntegerField(editable=False, db_index=True)),
+ ("rght", models.PositiveIntegerField(editable=False, db_index=True)),
+ ("tree_id", models.PositiveIntegerField(editable=False, db_index=True)),
+ ("level", models.PositiveIntegerField(editable=False, db_index=True)),
+ (
+ "parent",
+ mptt.fields.TreeForeignKey(
+ related_name="children",
+ verbose_name="parent",
+ blank=True,
+ to="categories.Category",
+ on_delete=models.CASCADE,
+ null=True,
+ ),
+ ),
],
options={
- 'ordering': ('tree_id', 'lft'),
- 'abstract': False,
- 'verbose_name': 'category',
- 'verbose_name_plural': 'categories',
+ "ordering": ("tree_id", "lft"),
+ "abstract": False,
+ "verbose_name": "category",
+ "verbose_name_plural": "categories",
},
),
migrations.CreateModel(
- name='CategoryRelation',
+ name="CategoryRelation",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('object_id', models.PositiveIntegerField(verbose_name='object id')),
- ('relation_type', models.CharField(help_text="A generic text field to tag a relation, like 'leadphoto'.", max_length='200', null=True, verbose_name='relation type', blank=True)),
- ('category', models.ForeignKey(verbose_name='category', to='categories.Category', on_delete=models.CASCADE)),
- ('content_type', models.ForeignKey(verbose_name='content type', to='contenttypes.ContentType', on_delete=models.CASCADE)),
+ ("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
+ ("object_id", models.PositiveIntegerField(verbose_name="object id")),
+ (
+ "relation_type",
+ models.CharField(
+ help_text="A generic text field to tag a relation, like 'leadphoto'.",
+ max_length="200",
+ null=True,
+ verbose_name="relation type",
+ blank=True,
+ ),
+ ),
+ (
+ "category",
+ models.ForeignKey(verbose_name="category", to="categories.Category", on_delete=models.CASCADE),
+ ),
+ (
+ "content_type",
+ models.ForeignKey(
+ verbose_name="content type", to="contenttypes.ContentType", on_delete=models.CASCADE
+ ),
+ ),
],
),
migrations.AlterUniqueTogether(
- name='category',
- unique_together=set([('parent', 'name')]),
+ name="category",
+ unique_together=set([("parent", "name")]),
),
]
diff --git a/categories/migrations/0002_auto_20170217_1111.py b/categories/migrations/0002_auto_20170217_1111.py
index 27b77ed..38c1f4f 100644
--- a/categories/migrations/0002_auto_20170217_1111.py
+++ b/categories/migrations/0002_auto_20170217_1111.py
@@ -1,27 +1,32 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-17 11:11
from __future__ import unicode_literals
-from django.db import migrations, models
import django.db.models.manager
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('categories', '0001_initial'),
+ ("categories", "0001_initial"),
]
operations = [
migrations.AlterModelManagers(
- name='category',
+ name="category",
managers=[
- ('tree', django.db.models.manager.Manager()),
+ ("tree", django.db.models.manager.Manager()),
],
),
migrations.AlterField(
- model_name='categoryrelation',
- name='relation_type',
- field=models.CharField(blank=True, help_text="A generic text field to tag a relation, like 'leadphoto'.", max_length=200, null=True, verbose_name='relation type'),
+ model_name="categoryrelation",
+ name="relation_type",
+ field=models.CharField(
+ blank=True,
+ help_text="A generic text field to tag a relation, like 'leadphoto'.",
+ max_length=200,
+ null=True,
+ verbose_name="relation type",
+ ),
),
]
diff --git a/categories/migrations/0003_auto_20200306_1050.py b/categories/migrations/0003_auto_20200306_1050.py
index c725321..21d98a3 100644
--- a/categories/migrations/0003_auto_20200306_1050.py
+++ b/categories/migrations/0003_auto_20200306_1050.py
@@ -1,35 +1,44 @@
# Generated by Django 3.0.4 on 2020-03-06 10:50
-from django.db import migrations, models
import django.db.models.deletion
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('contenttypes', '0002_remove_content_type_name'),
- ('categories', '0002_auto_20170217_1111'),
+ ("contenttypes", "0002_remove_content_type_name"),
+ ("categories", "0002_auto_20170217_1111"),
]
operations = [
migrations.AlterField(
- model_name='category',
- name='level',
+ model_name="category",
+ name="level",
field=models.PositiveIntegerField(editable=False),
),
migrations.AlterField(
- model_name='category',
- name='lft',
+ model_name="category",
+ name="lft",
field=models.PositiveIntegerField(editable=False),
),
migrations.AlterField(
- model_name='category',
- name='rght',
+ model_name="category",
+ name="rght",
field=models.PositiveIntegerField(editable=False),
),
migrations.AlterField(
- model_name='categoryrelation',
- name='content_type',
- field=models.ForeignKey(limit_choices_to=models.Q(models.Q(('app_label', 'simpletext'), ('model', 'simpletext')), models.Q(('app_label', 'flatpages'), ('model', 'flatpage')), _connector='OR'), on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='content type'),
+ model_name="categoryrelation",
+ name="content_type",
+ field=models.ForeignKey(
+ limit_choices_to=models.Q(
+ models.Q(("app_label", "simpletext"), ("model", "simpletext")),
+ models.Q(("app_label", "flatpages"), ("model", "flatpage")),
+ _connector="OR",
+ ),
+ on_delete=django.db.models.deletion.CASCADE,
+ to="contenttypes.ContentType",
+ verbose_name="content type",
+ ),
),
]
diff --git a/categories/migrations/0004_auto_20200517_1832.py b/categories/migrations/0004_auto_20200517_1832.py
index ec3f2a0..dcbde23 100644
--- a/categories/migrations/0004_auto_20200517_1832.py
+++ b/categories/migrations/0004_auto_20200517_1832.py
@@ -1,20 +1,22 @@
# Generated by Django 3.0.6 on 2020-05-17 18:32
-from django.db import migrations, models
import django.db.models.deletion
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('contenttypes', '0002_remove_content_type_name'),
- ('categories', '0003_auto_20200306_1050'),
+ ("contenttypes", "0002_remove_content_type_name"),
+ ("categories", "0003_auto_20200306_1050"),
]
operations = [
migrations.AlterField(
- model_name='categoryrelation',
- name='content_type',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='content type'),
+ model_name="categoryrelation",
+ name="content_type",
+ field=models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to="contenttypes.ContentType", verbose_name="content type"
+ ),
),
]
diff --git a/categories/models.py b/categories/models.py
index 15ddecb..3789de6 100644
--- a/categories/models.py
+++ b/categories/models.py
@@ -1,20 +1,26 @@
-from django.core.files.images import get_image_dimensions
-from django.urls import reverse
-from django.db import models
-from django.utils.encoding import force_text
-from django.contrib.contenttypes.models import ContentType
from functools import reduce
+
+from django.contrib.contenttypes.models import ContentType
+from django.core.files.images import get_image_dimensions
+from django.db import models
+from django.urls import reverse
+from django.utils.encoding import force_text
+
try:
from django.contrib.contenttypes.fields import GenericForeignKey
except ImportError:
from django.contrib.contenttypes.generic import GenericForeignKey
-from django.core.files.storage import get_storage_class
+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, THUMBNAIL_STORAGE)
-
from .base import CategoryBase
+from .settings import (
+ RELATION_MODELS,
+ RELATIONS,
+ THUMBNAIL_STORAGE,
+ THUMBNAIL_UPLOAD_PATH,
+)
STORAGE = get_storage_class(THUMBNAIL_STORAGE)
@@ -22,32 +28,28 @@ STORAGE = get_storage_class(THUMBNAIL_STORAGE)
class Category(CategoryBase):
thumbnail = models.FileField(
upload_to=THUMBNAIL_UPLOAD_PATH,
- null=True, blank=True,
- storage=STORAGE(),)
+ null=True,
+ blank=True,
+ storage=STORAGE(),
+ )
thumbnail_width = models.IntegerField(blank=True, null=True)
thumbnail_height = models.IntegerField(blank=True, null=True)
order = models.IntegerField(default=0)
alternate_title = models.CharField(
- blank=True,
- default="",
- max_length=100,
- help_text="An alternative title to use on pages with this category.")
+ blank=True, default="", max_length=100, help_text="An alternative title to use on pages with this category."
+ )
alternate_url = models.CharField(
blank=True,
max_length=200,
- help_text="An alternative URL to use instead of the one derived from "
- "the category hierarchy.")
+ help_text="An alternative URL to use instead of the one derived from " "the category hierarchy.",
+ )
description = models.TextField(blank=True, null=True)
meta_keywords = models.CharField(
- blank=True,
- default="",
- max_length=255,
- help_text="Comma-separated keywords for search engines.")
+ blank=True, default="", max_length=255, help_text="Comma-separated keywords for search engines."
+ )
meta_extra = models.TextField(
- blank=True,
- default="",
- help_text="(Advanced) Any additional HTML to be placed verbatim "
- "in the <head>")
+ blank=True, default="", help_text="(Advanced) Any additional HTML to be placed verbatim " "in the <head>"
+ )
@property
def short_title(self):
@@ -60,19 +62,21 @@ class Category(CategoryBase):
if self.alternate_url:
return self.alternate_url
try:
- prefix = reverse('categories_tree_list')
+ prefix = reverse("categories_tree_list")
except NoReverseMatch:
- prefix = '/'
- ancestors = list(self.get_ancestors()) + [self, ]
- return prefix + '/'.join([force_text(i.slug) for i in ancestors]) + '/'
+ prefix = "/"
+ ancestors = list(self.get_ancestors()) + [
+ self,
+ ]
+ return prefix + "/".join([force_text(i.slug) for i in ancestors]) + "/"
if RELATION_MODELS:
+
def get_related_content_type(self, content_type):
"""
Get all related items of the specified content type
"""
- return self.categoryrelation_set.filter(
- content_type__name=content_type)
+ return self.categoryrelation_set.filter(content_type__name=content_type)
def get_relation_type(self, relation_type):
"""
@@ -92,11 +96,11 @@ class Category(CategoryBase):
super(Category, self).save(*args, **kwargs)
class Meta(CategoryBase.Meta):
- verbose_name = _('category')
- verbose_name_plural = _('categories')
+ verbose_name = _("category")
+ verbose_name_plural = _("categories")
class MPTTMeta:
- order_insertion_by = ('order', 'name')
+ order_insertion_by = ("order", "name")
if RELATIONS:
@@ -123,17 +127,23 @@ class CategoryRelationManager(models.Manager):
class CategoryRelation(models.Model):
"""Related category item"""
- category = models.ForeignKey(Category, verbose_name=_('category'), on_delete=models.CASCADE)
+
+ category = models.ForeignKey(Category, verbose_name=_("category"), on_delete=models.CASCADE)
content_type = models.ForeignKey(
- ContentType, on_delete=models.CASCADE, limit_choices_to=CATEGORY_RELATION_LIMITS, verbose_name=_('content type'))
- object_id = models.PositiveIntegerField(verbose_name=_('object id'))
- content_object = GenericForeignKey('content_type', 'object_id')
+ ContentType,
+ on_delete=models.CASCADE,
+ limit_choices_to=CATEGORY_RELATION_LIMITS,
+ verbose_name=_("content type"),
+ )
+ object_id = models.PositiveIntegerField(verbose_name=_("object id"))
+ content_object = GenericForeignKey("content_type", "object_id")
relation_type = models.CharField(
- verbose_name=_('relation type'),
+ verbose_name=_("relation type"),
max_length=200,
blank=True,
null=True,
- help_text=_("A generic text field to tag a relation, like 'leadphoto'."))
+ help_text=_("A generic text field to tag a relation, like 'leadphoto'."),
+ )
objects = CategoryRelationManager()
diff --git a/categories/registration.py b/categories/registration.py
index e26bb12..d871e14 100644
--- a/categories/registration.py
+++ b/categories/registration.py
@@ -1,17 +1,17 @@
"""
These functions handle the adding of fields to other models
"""
-from django.db.models import ForeignKey, ManyToManyField, CASCADE
-from django.core.exceptions import FieldDoesNotExist
-from . import fields
+from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
+from django.db.models import CASCADE, ForeignKey, ManyToManyField
+
# from settings import self._field_registry, self._model_registry
from django.utils.translation import ugettext_lazy as _
-from django.core.exceptions import ImproperlyConfigured
+from . import fields
FIELD_TYPES = {
- 'ForeignKey': ForeignKey,
- 'ManyToManyField': ManyToManyField,
+ "ForeignKey": ForeignKey,
+ "ManyToManyField": ManyToManyField,
}
@@ -28,17 +28,20 @@ class Registry(object):
field_definitions: a string, tuple or list of field configurations
field_type: either 'ForeignKey' or 'ManyToManyField'
"""
- from django.apps import apps
import collections
+ from django.apps import apps
+
app_label = app
if isinstance(field_definitions, str):
field_definitions = [field_definitions]
elif not isinstance(field_definitions, collections.Iterable):
- raise ImproperlyConfigured(_('Field configuration for %(app)s should be a string or iterable') % {'app': app})
+ raise ImproperlyConfigured(
+ _("Field configuration for %(app)s should be a string or iterable") % {"app": app}
+ )
- if field_type not in ('ForeignKey', 'ManyToManyField'):
+ if field_type not in ("ForeignKey", "ManyToManyField"):
raise ImproperlyConfigured(_('`field_type` must be either `"ForeignKey"` or `"ManyToManyField"`.'))
try:
@@ -55,30 +58,31 @@ class Registry(object):
if model not in self._model_registry[app_label]:
self._model_registry[app_label].append(model)
except LookupError:
- raise ImproperlyConfigured('Model "%(model)s" doesn\'t exist in app "%(app)s".' % {'model': model_name, 'app': app})
+ raise ImproperlyConfigured(
+ 'Model "%(model)s" doesn\'t exist in app "%(app)s".' % {"model": model_name, "app": app}
+ )
if not isinstance(field_definitions, (tuple, list)):
field_definitions = [field_definitions]
for fld in field_definitions:
- extra_params = {'to': 'categories.Category', 'blank': True}
- if field_type != 'ManyToManyField':
- extra_params['on_delete'] = CASCADE
- extra_params['null'] = True
+ extra_params = {"to": "categories.Category", "blank": True}
+ if field_type != "ManyToManyField":
+ extra_params["on_delete"] = CASCADE
+ extra_params["null"] = True
if isinstance(fld, str):
field_name = fld
elif isinstance(fld, dict):
- if 'name' in fld:
- field_name = fld.pop('name')
+ if "name" in fld:
+ field_name = fld.pop("name")
else:
continue
extra_params.update(fld)
else:
raise ImproperlyConfigured(
- _("%(settings)s doesn't recognize the value of %(app)s.%(model)s") % {
- 'settings': 'CATEGORY_SETTINGS',
- 'app': app,
- 'model': model_name})
+ _("%(settings)s doesn't recognize the value of %(app)s.%(model)s")
+ % {"settings": "CATEGORY_SETTINGS", "app": app, "model": model_name}
+ )
registry_name = ".".join([app_label, model_name.lower(), field_name])
if registry_name in self._field_registry:
continue
@@ -89,10 +93,10 @@ class Registry(object):
self._field_registry[registry_name] = FIELD_TYPES[field_type](**extra_params)
self._field_registry[registry_name].contribute_to_class(model, field_name)
- def register_m2m(self, model, field_name='categories', extra_params={}):
+ def register_m2m(self, model, field_name="categories", extra_params={}):
return self._register(model, field_name, extra_params, fields.CategoryM2MField)
- def register_fk(self, model, field_name='category', extra_params={}):
+ def register_fk(self, model, field_name="category", extra_params={}):
return self._register(model, field_name, extra_params, fields.CategoryFKField)
def _register(self, model, field_name, extra_params={}, field=fields.CategoryFKField):
@@ -120,28 +124,32 @@ def _process_registry(registry, call_func):
"""
Given a dictionary, and a registration function, process the registry
"""
- from django.core.exceptions import ImproperlyConfigured
from django.apps import apps
+ from django.core.exceptions import ImproperlyConfigured
for key, value in list(registry.items()):
- model = apps.get_model(*key.split('.'))
+ model = apps.get_model(*key.split("."))
if model is None:
- raise ImproperlyConfigured(_('%(key)s is not a model') % {'key': key})
+ raise ImproperlyConfigured(_("%(key)s is not a model") % {"key": key})
if isinstance(value, (tuple, list)):
for item in value:
if isinstance(item, str):
call_func(model, item)
elif isinstance(item, dict):
- field_name = item.pop('name')
+ field_name = item.pop("name")
call_func(model, field_name, extra_params=item)
else:
- raise ImproperlyConfigured(_("%(settings)s doesn't recognize the value of %(key)s") %
- {'settings': 'CATEGORY_SETTINGS', 'key': key})
+ raise ImproperlyConfigured(
+ _("%(settings)s doesn't recognize the value of %(key)s")
+ % {"settings": "CATEGORY_SETTINGS", "key": key}
+ )
elif isinstance(value, str):
call_func(model, value)
elif isinstance(value, dict):
- field_name = value.pop('name')
+ field_name = value.pop("name")
call_func(model, field_name, extra_params=value)
else:
- raise ImproperlyConfigured(_("%(settings)s doesn't recognize the value of %(key)s") %
- {'settings': 'CATEGORY_SETTINGS', 'key': key})
+ raise ImproperlyConfigured(
+ _("%(settings)s doesn't recognize the value of %(key)s")
+ % {"settings": "CATEGORY_SETTINGS", "key": key}
+ )
diff --git a/categories/settings.py b/categories/settings.py
index bf77d66..2fedf6f 100644
--- a/categories/settings.py
+++ b/categories/settings.py
@@ -1,42 +1,46 @@
+import collections
+
from django.conf import settings
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
-import collections
DEFAULT_SETTINGS = {
- 'ALLOW_SLUG_CHANGE': False,
- 'M2M_REGISTRY': {},
- 'FK_REGISTRY': {},
- 'THUMBNAIL_UPLOAD_PATH': 'uploads/categories/thumbnails',
- 'THUMBNAIL_STORAGE': settings.DEFAULT_FILE_STORAGE,
- 'JAVASCRIPT_URL': getattr(settings, 'STATIC_URL', settings.MEDIA_URL) + 'js/',
- 'SLUG_TRANSLITERATOR': '',
- 'REGISTER_ADMIN': True,
- 'RELATION_MODELS': [],
+ "ALLOW_SLUG_CHANGE": False,
+ "M2M_REGISTRY": {},
+ "FK_REGISTRY": {},
+ "THUMBNAIL_UPLOAD_PATH": "uploads/categories/thumbnails",
+ "THUMBNAIL_STORAGE": settings.DEFAULT_FILE_STORAGE,
+ "JAVASCRIPT_URL": getattr(settings, "STATIC_URL", settings.MEDIA_URL) + "js/",
+ "SLUG_TRANSLITERATOR": "",
+ "REGISTER_ADMIN": True,
+ "RELATION_MODELS": [],
}
-DEFAULT_SETTINGS.update(getattr(settings, 'CATEGORIES_SETTINGS', {}))
+DEFAULT_SETTINGS.update(getattr(settings, "CATEGORIES_SETTINGS", {}))
-if DEFAULT_SETTINGS['SLUG_TRANSLITERATOR']:
- if isinstance(DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'], collections.Callable):
+if DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"]:
+ if isinstance(DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"], collections.Callable):
pass
- elif isinstance(DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'], str):
+ elif isinstance(DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"], str):
from django.utils.importlib import import_module
- bits = DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'].split(".")
+
+ bits = DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"].split(".")
module = import_module(".".join(bits[:-1]))
- DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'] = getattr(module, bits[-1])
+ DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"] = getattr(module, bits[-1])
else:
from django.core.exceptions import ImproperlyConfigured
- raise ImproperlyConfigured(_('%(transliterator) must be a callable or a string.') %
- {'transliterator': 'SLUG_TRANSLITERATOR'})
+
+ raise ImproperlyConfigured(
+ _("%(transliterator) must be a callable or a string.") % {"transliterator": "SLUG_TRANSLITERATOR"}
+ )
else:
- DEFAULT_SETTINGS['SLUG_TRANSLITERATOR'] = lambda x: x
+ DEFAULT_SETTINGS["SLUG_TRANSLITERATOR"] = lambda x: x
# Add all the keys/values to the module's namespace
globals().update(DEFAULT_SETTINGS)
-RELATIONS = [Q(app_label=al, model=m) for al, m in [x.split('.') for x in DEFAULT_SETTINGS['RELATION_MODELS']]]
+RELATIONS = [Q(app_label=al, model=m) for al, m in [x.split(".") for x in DEFAULT_SETTINGS["RELATION_MODELS"]]]
# The field registry keeps track of the individual fields created.
# {'app.model.field': Field(**extra_params)}
diff --git a/categories/static/js/genericcollections.js b/categories/static/js/genericcollections.js
index 584208e..8081eb8 100644
--- a/categories/static/js/genericcollections.js
+++ b/categories/static/js/genericcollections.js
@@ -17,4 +17,4 @@ function showGenericRelatedObjectLookupPopup(triggeringLink, ctArray) {
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
-}
\ No newline at end of file
+}
diff --git a/categories/templates/categories/ancestors_ul.html b/categories/templates/categories/ancestors_ul.html
index eb07cb2..d9173e2 100644
--- a/categories/templates/categories/ancestors_ul.html
+++ b/categories/templates/categories/ancestors_ul.html
@@ -8,4 +8,4 @@
{% else %}{{ node.name }}
{% endifequal %}
{% for level in structure.closed_levels %}{% endfor %}
-{% endfor %}
\ No newline at end of file
+{% endfor %}
diff --git a/categories/templates/categories/base.html b/categories/templates/categories/base.html
index 385820f..245102a 100644
--- a/categories/templates/categories/base.html
+++ b/categories/templates/categories/base.html
@@ -1,3 +1,3 @@
{% extends 'base.html' %}
{% block content %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/categories/templates/categories/breadcrumbs.html b/categories/templates/categories/breadcrumbs.html
index d6ec117..9fac9e2 100644
--- a/categories/templates/categories/breadcrumbs.html
+++ b/categories/templates/categories/breadcrumbs.html
@@ -1,3 +1,3 @@
{% spaceless %}{% for item in category.get_ancestors %}
{{ item.name }}{{ separator }}{% endfor %}{{ category.name }}
-{% endspaceless %}
\ No newline at end of file
+{% endspaceless %}
diff --git a/categories/templates/categories/category_detail.html b/categories/templates/categories/category_detail.html
index 3865fa1..c43e371 100644
--- a/categories/templates/categories/category_detail.html
+++ b/categories/templates/categories/category_detail.html
@@ -14,4 +14,4 @@
{% if category.parent %}{% endif %}
{% if category.description %}{{ category.description }}
{% endif %}
{% if category.children.count %}Subcategories
{% for child in category.children.all %}- {{ child }}
{% endfor %}
{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/categories/templates/categories/category_list.html b/categories/templates/categories/category_list.html
index ff87511..f9a2c26 100644
--- a/categories/templates/categories/category_list.html
+++ b/categories/templates/categories/category_list.html
@@ -2,4 +2,4 @@
{% block content %}
Categories
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/categories/templates/categories/ul_tree.html b/categories/templates/categories/ul_tree.html
index b6013de..891e298 100644
--- a/categories/templates/categories/ul_tree.html
+++ b/categories/templates/categories/ul_tree.html
@@ -8,4 +8,4 @@
{% else %}{{ node.name }}
{% endifequal %}
{% for level in structure.closed_levels %}{% endfor %}
-{% endfor %}{% endspaceless %}
\ No newline at end of file
+{% endfor %}{% endspaceless %}
diff --git a/categories/templatetags/category_tags.py b/categories/templatetags/category_tags.py
index 69d2aad..a93f70e 100644
--- a/categories/templatetags/category_tags.py
+++ b/categories/templatetags/category_tags.py
@@ -1,13 +1,18 @@
from django import template
from django.apps import apps
-from django.template import (Node, TemplateSyntaxError, VariableDoesNotExist)
+from django.template import Node, TemplateSyntaxError, VariableDoesNotExist
from django.template.base import FilterExpression
+from mptt.templatetags.mptt_tags import (
+ RecurseTreeNode,
+ full_tree_for_model,
+ tree_info,
+ tree_path,
+)
+from mptt.utils import drilldown_tree_for_node
from six import string_types
+
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, RecurseTreeNode,
- full_tree_for_model)
register = template.Library()
@@ -48,9 +53,9 @@ def get_category(category_string, model=Category):
"""
model_class = get_cat_model(model)
category = str(category_string).strip("'\"")
- category = category.strip('/')
+ category = category.strip("/")
- cat_list = category.split('/')
+ cat_list = category.split("/")
if len(cat_list) == 0:
return None
try:
@@ -88,7 +93,7 @@ class CategoryDrillDownNode(template.Node):
context[self.varname] = []
except Exception:
context[self.varname] = []
- return ''
+ return ""
@register.tag
@@ -114,30 +119,32 @@ def get_category_drilldown(parser, token):
Grandparent, Parent, Child 1, Child 2, Child n
"""
bits = token.split_contents()
- error_str = '%(tagname)s tag should be in the format {%% %(tagname)s ' \
- '"category name" [using "app.Model"] as varname %%} or ' \
- '{%% %(tagname)s category_obj as varname %%}.'
+ error_str = (
+ "%(tagname)s tag should be in the format {%% %(tagname)s "
+ '"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':
+ 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':
+ 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':
+ 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_string, separator=' > ', using='categories.category'):
+@register.inclusion_tag("categories/breadcrumbs.html")
+def breadcrumbs(category_string, separator=" > ", using="categories.category"):
"""
{% breadcrumbs category separator="::" using="categories.category" %}
@@ -146,11 +153,11 @@ def breadcrumbs(category_string, separator=' > ', using='categories.category'):
"""
cat = get_category(category_string, using)
- return {'category': cat, 'separator': separator}
+ return {"category": cat, "separator": separator}
-@register.inclusion_tag('categories/ul_tree.html')
-def display_drilldown_as_ul(category, using='categories.Category'):
+@register.inclusion_tag("categories/ul_tree.html")
+def display_drilldown_as_ul(category, using="categories.Category"):
"""
Render the category with ancestors and children using the
``categories/ul_tree.html`` template.
@@ -185,13 +192,13 @@ def display_drilldown_as_ul(category, using='categories.Category'):
"""
cat = get_category(category, using)
if cat is None:
- return {'category': cat, 'path': []}
+ return {"category": cat, "path": []}
else:
- return {'category': cat, 'path': drilldown_tree_for_node(cat)}
+ return {"category": cat, "path": drilldown_tree_for_node(cat)}
-@register.inclusion_tag('categories/ul_tree.html')
-def display_path_as_ul(category, using='categories.Category'):
+@register.inclusion_tag("categories/ul_tree.html")
+def display_path_as_ul(category, using="categories.Category"):
"""
Render the category with ancestors, but no children using the
``categories/ul_tree.html`` template.
@@ -219,7 +226,7 @@ def display_path_as_ul(category, using='categories.Category'):
else:
cat = get_category(category)
- return {'category': cat, 'path': cat.get_ancestors() or []}
+ return {"category": cat, "path": cat.get_ancestors() or []}
class TopLevelCategoriesNode(template.Node):
@@ -229,8 +236,8 @@ class TopLevelCategoriesNode(template.Node):
def render(self, context):
model = get_cat_model(self.model)
- context[self.varname] = model.objects.filter(parent=None).order_by('name')
- return ''
+ context[self.varname] = model.objects.filter(parent=None).order_by("name")
+ return ""
@register.tag
@@ -247,14 +254,14 @@ def get_top_level_categories(parser, token):
bits = token.split_contents()
usage = 'Usage: {%% %s [using "app.Model"] as %%}' % bits[0]
if len(bits) == 3:
- if bits[1] != 'as':
+ 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'):
+ if bits[1] not in ("as", "using") and bits[3] not in ("as", "using"):
raise template.TemplateSyntaxError(usage)
- if bits[1] == 'using':
+ if bits[1] == "using":
model = bits[2].strip("'\"")
varname = bits[4].strip("'\"")
else:
@@ -264,22 +271,21 @@ def get_top_level_categories(parser, token):
return TopLevelCategoriesNode(varname, model)
-def get_latest_objects_by_category(category, app_label, model_name, set_name, date_field='pub_date', num=15):
+def get_latest_objects_by_category(category, app_label, model_name, set_name, date_field="pub_date", num=15):
m = apps.get_model(app_label, model_name)
if not isinstance(category, CategoryBase):
category = Category.objects.get(slug=str(category))
children = category.children.all()
ids = []
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]])
+ 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]
+ 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,
- date_field='pub_date', num=15):
+ 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
"""
@@ -305,7 +311,7 @@ class LatestObjectsNode(Node):
result = get_latest_objects_by_category(category, app_label, model_name, set_name, date_field, num)
context[self.var_name] = result
- return ''
+ return ""
def do_get_latest_objects_by_category(parser, token):
@@ -317,7 +323,7 @@ def do_get_latest_objects_by_category(parser, token):
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':
+ 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))
@@ -328,11 +334,11 @@ def do_get_latest_objects_by_category(parser, token):
model_name = FilterExpression(bits[3], parser)
set_name = FilterExpression(bits[4], parser)
var_name = bits[-1]
- if bits[5] != 'as':
+ if bits[5] != "as":
date_field = FilterExpression(bits[5], parser)
else:
date_field = FilterExpression(None, parser)
- if bits[6] != 'as':
+ if bits[6] != "as":
num = FilterExpression(bits[6], parser)
else:
num = FilterExpression(None, parser)
@@ -348,8 +354,10 @@ def tree_queryset(value):
Converts a normal queryset from an MPTT model to include all the ancestors
so a filtered subset of items can be formatted correctly
"""
- from django.db.models.query import QuerySet
from copy import deepcopy
+
+ from django.db.models.query import QuerySet
+
if not isinstance(value, QuerySet):
return value
@@ -365,9 +373,9 @@ def tree_queryset(value):
# this cuts down the number of queries considerably since all ancestors
# will already be in include_pages when they are checked, thus not
# trigger additional queries.
- for p in qs2.order_by('rght').iterator():
+ for p in qs2.order_by("rght").iterator():
if p.parent_id and p.parent_id not in include_pages and p.id not in include_pages:
- ancestor_id_list = p.get_ancestors().values_list('id', flat=True)
+ ancestor_id_list = p.get_ancestors().values_list("id", flat=True)
include_pages.update(ancestor_id_list)
if include_pages:
@@ -400,10 +408,10 @@ def recursetree(parser, token):
"""
bits = token.contents.split()
if len(bits) != 2:
- raise template.TemplateSyntaxError('%s tag requires a queryset' % bits[0])
+ raise template.TemplateSyntaxError("%s tag requires a queryset" % bits[0])
queryset_var = FilterExpression(bits[1], parser)
- template_nodes = parser.parse(('endrecursetree',))
+ template_nodes = parser.parse(("endrecursetree",))
parser.delete_first_token()
return RecurseTreeNode(template_nodes, queryset_var)
diff --git a/categories/tests/test_admin.py b/categories/tests/test_admin.py
index 20759c1..ce1c7a3 100644
--- a/categories/tests/test_admin.py
+++ b/categories/tests/test_admin.py
@@ -1,68 +1,68 @@
-# -*- coding: utf-8 -*-
from django.contrib.auth.models import User
-from django.urls import reverse
from django.test import Client, TestCase
+from django.urls import reverse
from django.utils.encoding import smart_text
from categories.models import Category
class TestCategoryAdmin(TestCase):
-
def setUp(self):
self.client = Client()
def test_adding_parent_and_child(self):
- User.objects.create_superuser('testuser', 'testuser@example.com', 'password')
- self.client.login(username='testuser', password='password')
- url = reverse('admin:categories_category_add')
+ User.objects.create_superuser("testuser", "testuser@example.com", "password")
+ self.client.login(username="testuser", password="password")
+ url = reverse("admin:categories_category_add")
data = {
- 'parent': '',
- 'name': smart_text('Parent Catégory'),
- 'thumbnail': '',
- 'filename': '',
- 'active': 'on',
- 'alternate_title': '',
- 'alternate_url': '',
- 'description': '',
- 'meta_keywords': '',
- 'meta_extra': '',
- 'order': 0,
- 'slug': 'parent',
- '_save': '_save',
- 'categoryrelation_set-TOTAL_FORMS': '0',
- 'categoryrelation_set-INITIAL_FORMS': '0',
- 'categoryrelation_set-MIN_NUM_FORMS': '1000',
- 'categoryrelation_set-MAX_NUM_FORMS': '1000',
+ "parent": "",
+ "name": smart_text("Parent Catégory"),
+ "thumbnail": "",
+ "filename": "",
+ "active": "on",
+ "alternate_title": "",
+ "alternate_url": "",
+ "description": "",
+ "meta_keywords": "",
+ "meta_extra": "",
+ "order": 0,
+ "slug": "parent",
+ "_save": "_save",
+ "categoryrelation_set-TOTAL_FORMS": "0",
+ "categoryrelation_set-INITIAL_FORMS": "0",
+ "categoryrelation_set-MIN_NUM_FORMS": "1000",
+ "categoryrelation_set-MAX_NUM_FORMS": "1000",
}
resp = self.client.post(url, data=data)
self.assertEqual(resp.status_code, 302)
self.assertEqual(1, Category.objects.count())
# update parent
- data.update({'name': smart_text('Parent Catégory (Changed)')})
- resp = self.client.post(reverse('admin:categories_category_change', args=(1,)), data=data)
+ data.update({"name": smart_text("Parent Catégory (Changed)")})
+ resp = self.client.post(reverse("admin:categories_category_change", args=(1,)), data=data)
self.assertEqual(resp.status_code, 302)
self.assertEqual(1, Category.objects.count())
# add a child
- data.update({
- 'parent': '1',
- 'name': smart_text('Child Catégory'),
- 'slug': smart_text('child-category'),
- })
+ data.update(
+ {
+ "parent": "1",
+ "name": smart_text("Child Catégory"),
+ "slug": smart_text("child-category"),
+ }
+ )
resp = self.client.post(url, data=data)
self.assertEqual(resp.status_code, 302)
self.assertEqual(2, Category.objects.count())
# update child
- data.update({'name': 'Child (Changed)'})
- resp = self.client.post(reverse('admin:categories_category_change', args=(2,)), data=data)
+ data.update({"name": "Child (Changed)"})
+ resp = self.client.post(reverse("admin:categories_category_change", args=(2,)), data=data)
self.assertEqual(resp.status_code, 302)
self.assertEqual(2, Category.objects.count())
# test the admin list view
- url = reverse('admin:categories_category_changelist')
+ url = reverse("admin:categories_category_changelist")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
diff --git a/categories/tests/test_category_import.py b/categories/tests/test_category_import.py
index 3db1be4..acd366f 100644
--- a/categories/tests/test_category_import.py
+++ b/categories/tests/test_category_import.py
@@ -4,20 +4,21 @@
import os
from django.conf import settings
-from django.test import TestCase, override_settings
-from categories.models import Category
-from categories.management.commands.import_categories import Command
from django.core.management.base import CommandError
+from django.test import TestCase, override_settings
+
+from categories.management.commands.import_categories import Command
+from categories.models import Category
-@override_settings(INSTALLED_APPS=(app for app in settings.INSTALLED_APPS if app != 'django.contrib.flatpages'))
+@override_settings(INSTALLED_APPS=(app for app in settings.INSTALLED_APPS if app != "django.contrib.flatpages"))
class CategoryImportTest(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))
+ 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.handle(testfile)
roots = Category.tree.root_nodes()
@@ -26,31 +27,31 @@ class CategoryImportTest(TestCase):
for item in roots:
assert item.name in root_cats
- cat2 = Category.objects.get(name='Category 2')
+ cat2 = Category.objects.get(name="Category 2")
cat21 = cat2.children.all()[0]
- self.assertEqual(cat21.name, 'Category 2-1')
+ self.assertEqual(cat21.name, "Category 2-1")
cat211 = cat21.children.all()[0]
- self.assertEqual(cat211.name, 'Category 2-1-1')
+ self.assertEqual(cat211.name, "Category 2-1-1")
def testImportSpaceDelimited(self):
Category.objects.all().delete()
- self._import_file('test_category_spaces.txt')
+ 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')
+ 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')
+ 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')
+ 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):
"""
diff --git a/categories/tests/test_manager.py b/categories/tests/test_manager.py
index b2fb6c6..a9f2718 100644
--- a/categories/tests/test_manager.py
+++ b/categories/tests/test_manager.py
@@ -1,10 +1,11 @@
# test active returns only active items
from django.test import TestCase
+
from categories.models import Category
class CategoryManagerTest(TestCase):
- fixtures = ['categories.json']
+ fixtures = ["categories.json"]
def setUp(self):
pass
@@ -16,7 +17,7 @@ class CategoryManagerTest(TestCase):
all_count = Category.objects.all().count()
self.assertEqual(Category.objects.active().count(), all_count)
- cat1 = Category.objects.get(name='Category 1')
+ cat1 = Category.objects.get(name="Category 1")
cat1.active = False
cat1.save()
diff --git a/categories/tests/test_mgmt_commands.py b/categories/tests/test_mgmt_commands.py
index 7466910..b94c842 100644
--- a/categories/tests/test_mgmt_commands.py
+++ b/categories/tests/test_mgmt_commands.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
from django.core import management
from django.core.management.base import CommandError
from django.db import connection
@@ -6,7 +5,6 @@ from django.test import TestCase
class TestMgmtCommands(TestCase):
-
@classmethod
def setUpClass(cls):
connection.disable_constraint_checking()
@@ -18,13 +16,13 @@ class TestMgmtCommands(TestCase):
connection.enable_constraint_checking()
def test_add_category_fields(self):
- management.call_command('add_category_fields', verbosity=0)
+ management.call_command("add_category_fields", verbosity=0)
def test_add_category_fields_app(self):
- management.call_command('add_category_fields', 'flatpages', verbosity=0)
+ management.call_command("add_category_fields", "flatpages", verbosity=0)
def test_drop_category_field(self):
- management.call_command('drop_category_field', 'flatpages', 'flatpage', 'category', verbosity=0)
+ management.call_command("drop_category_field", "flatpages", "flatpage", "category", verbosity=0)
def test_drop_category_field_error(self):
- self.assertRaises(CommandError, management.call_command, 'drop_category_field', verbosity=0)
+ self.assertRaises(CommandError, management.call_command, "drop_category_field", verbosity=0)
diff --git a/categories/tests/test_models.py b/categories/tests/test_models.py
index 5649bee..5208baf 100644
--- a/categories/tests/test_models.py
+++ b/categories/tests/test_models.py
@@ -2,20 +2,19 @@ import os
from django.core.files import File
from django.core.files.uploadedfile import UploadedFile
+from django.test import TestCase
from categories.models import Category
-from django.test import TestCase
class TestCategoryThumbnail(TestCase):
-
def test_thumbnail(self):
- file_name = 'test_image.jpg'
+ file_name = "test_image.jpg"
- with open(os.path.join(os.path.dirname(__file__), file_name), 'rb') as f:
- test_image = UploadedFile(File(f), content_type='image/jpeg')
- category = Category.objects.create(name='Test Category', slug='test-category', thumbnail=test_image)
+ with open(os.path.join(os.path.dirname(__file__), file_name), "rb") as f:
+ test_image = UploadedFile(File(f), content_type="image/jpeg")
+ category = Category.objects.create(name="Test Category", slug="test-category", thumbnail=test_image)
self.assertEqual(category.pk, 1)
self.assertEqual(category.thumbnail_width, 640)
self.assertEqual(category.thumbnail_height, 480)
diff --git a/categories/tests/test_registration.py b/categories/tests/test_registration.py
index 842baec..918d8c9 100644
--- a/categories/tests/test_registration.py
+++ b/categories/tests/test_registration.py
@@ -14,43 +14,39 @@ class CategoryRegistrationTest(TestCase):
"""
def test_foreignkey_string(self):
- FK_REGISTRY = {
- 'flatpages.flatpage': 'category'
- }
+ FK_REGISTRY = {"flatpages.flatpage": "category"}
_process_registry(FK_REGISTRY, registry.register_fk)
from django.contrib.flatpages.models import FlatPage
- self.assertTrue('category' in [f.name for f in FlatPage()._meta.get_fields()])
+
+ self.assertTrue("category" in [f.name for f in FlatPage()._meta.get_fields()])
def test_foreignkey_dict(self):
- FK_REGISTRY = {
- 'flatpages.flatpage': {'name': 'category'}
- }
+ FK_REGISTRY = {"flatpages.flatpage": {"name": "category"}}
_process_registry(FK_REGISTRY, registry.register_fk)
from django.contrib.flatpages.models import FlatPage
- self.assertTrue('category' in [f.name for f in FlatPage()._meta.get_fields()])
+
+ self.assertTrue("category" in [f.name for f in FlatPage()._meta.get_fields()])
def test_foreignkey_list(self):
- FK_REGISTRY = {
- 'flatpages.flatpage': (
- {'name': 'category', 'related_name': 'cats'},
- )
- }
+ FK_REGISTRY = {"flatpages.flatpage": ({"name": "category", "related_name": "cats"},)}
_process_registry(FK_REGISTRY, registry.register_fk)
from django.contrib.flatpages.models import FlatPage
- self.assertTrue('category' in [f.name for f in FlatPage()._meta.get_fields()])
+
+ self.assertTrue("category" in [f.name for f in FlatPage()._meta.get_fields()])
if django.VERSION[1] >= 7:
+
def test_new_foreignkey_string(self):
- registry.register_model('flatpages', 'flatpage', 'ForeignKey', 'category')
+ registry.register_model("flatpages", "flatpage", "ForeignKey", "category")
from django.contrib.flatpages.models import FlatPage
- self.assertTrue('category' in [f.name for f in FlatPage()._meta.get_fields()])
+
+ self.assertTrue("category" in [f.name for f in FlatPage()._meta.get_fields()])
class Categorym2mTest(TestCase):
def test_m2m_string(self):
- M2M_REGISTRY = {
- 'flatpages.flatpage': 'categories'
- }
+ M2M_REGISTRY = {"flatpages.flatpage": "categories"}
_process_registry(M2M_REGISTRY, registry.register_m2m)
from django.contrib.flatpages.models import FlatPage
- self.assertTrue('category' in [f.name for f in FlatPage()._meta.get_fields()])
+
+ self.assertTrue("category" in [f.name for f in FlatPage()._meta.get_fields()])
diff --git a/categories/tests/test_templatetags.py b/categories/tests/test_templatetags.py
index f099715..ffe967c 100644
--- a/categories/tests/test_templatetags.py
+++ b/categories/tests/test_templatetags.py
@@ -1,13 +1,14 @@
-from django.test import TestCase
-from django import template
import re
+from django import template
+from django.test import TestCase
+
from categories.models import Category
class CategoryTagsTest(TestCase):
- fixtures = ['musicgenres.json']
+ fixtures = ["musicgenres.json"]
def render_template(self, template_string, context={}):
"""
@@ -21,7 +22,9 @@ class CategoryTagsTest(TestCase):
"""
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 %}')
+ self.assertRaises(
+ template.TemplateSyntaxError, self.render_template, "{% load category_tags %}{% get_category %}"
+ )
def testBasicUsage(self):
"""
@@ -30,46 +33,50 @@ class CategoryTagsTest(TestCase):
# display_path_as_ul
rock_resp = ''
resp = self.render_template('{% load category_tags %}{% display_path_as_ul "/Rock" %}')
- resp = re.sub(r'\n$', "", resp)
+ resp = re.sub(r"\n$", "", resp)
self.assertEqual(resp, rock_resp)
# display_drilldown_as_ul
expected_resp = ''
resp = self.render_template(
- '{% load category_tags %}'
- '{% display_drilldown_as_ul "/World/Worldbeat" "categories.category" %}')
- resp = re.sub(r'\n$', "", resp)
+ "{% load category_tags %}" '{% display_drilldown_as_ul "/World/Worldbeat" "categories.category" %}'
+ )
+ resp = re.sub(r"\n$", "", resp)
self.assertEqual(resp, expected_resp)
# breadcrumbs
expected_resp = 'World > Worldbeat'
resp = self.render_template(
- '{% load category_tags %}'
- '{% breadcrumbs "/World/Worldbeat" " > " "categories.category" %}')
+ "{% load category_tags %}" '{% breadcrumbs "/World/Worldbeat" " > " "categories.category" %}'
+ )
self.assertEqual(resp, expected_resp)
# get_top_level_categories
- expected_resp = 'Avant-garde|Blues|Country|Easy listening|Electronic|Hip hop/Rap music|Jazz|Latin|Modern folk|Pop|Reggae|Rhythm and blues|Rock|World|'
+ expected_resp = "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 %}'
+ "{% load category_tags %}"
'{% get_top_level_categories using "categories.category" as varname %}'
- '{% for item in varname %}{{ item }}|{% endfor %}')
+ "{% for item in varname %}{{ item }}|{% endfor %}"
+ )
self.assertEqual(resp, expected_resp)
# get_category_drilldown
expected_resp = "World|World > Worldbeat|"
resp = self.render_template(
- '{% load category_tags %}'
+ "{% load category_tags %}"
'{% get_category_drilldown "/World" using "categories.category" as var %}'
- '{% for item in var %}{{ item }}|{% endfor %}')
+ "{% for item in var %}{{ item }}|{% endfor %}"
+ )
self.assertEqual(resp, expected_resp)
# recursetree
- expected_resp = ''
- ctxt = {'nodes': Category.objects.filter(name__in=("Worldbeat", "Urban Cowboy"))}
+ expected_resp = ""
+ ctxt = {"nodes": Category.objects.filter(name__in=("Worldbeat", "Urban Cowboy"))}
resp = self.render_template(
- '{% load category_tags %}'
- '{% recursetree nodes|tree_queryset %}- {{ node.name }}'
- '{% if not node.is_leaf_node %}{% endif %}
{% endrecursetree %}
', ctxt)
+ "{% load category_tags %}"
+ "{% recursetree nodes|tree_queryset %}- {{ node.name }}"
+ "{% if not node.is_leaf_node %}{% endif %}
{% endrecursetree %}
",
+ ctxt,
+ )
self.assertEqual(resp, expected_resp)
diff --git a/categories/tests/test_views.py b/categories/tests/test_views.py
index d64435b..dac65f9 100644
--- a/categories/tests/test_views.py
+++ b/categories/tests/test_views.py
@@ -1,8 +1,9 @@
-from django.http import Http404
from django.contrib.auth.models import AnonymousUser
-from django.test import Client, TestCase, RequestFactory
-from categories.models import Category, CategoryRelation
+from django.http import Http404
+from django.test import Client, RequestFactory, TestCase
+
from categories import views
+from categories.models import Category, CategoryRelation
class MyCategoryRelationView(views.CategoryRelatedDetail):
@@ -10,16 +11,18 @@ class MyCategoryRelationView(views.CategoryRelatedDetail):
class TestCategoryViews(TestCase):
- fixtures = ['musicgenres.json', ]
+ fixtures = [
+ "musicgenres.json",
+ ]
def setUp(self):
self.client = Client()
self.factory = RequestFactory()
def test_category_detail(self):
- cat0 = Category.objects.get(slug='country', level=0)
- cat1 = cat0.children.get(slug='country-pop')
- cat2 = Category.objects.get(slug='urban-cowboy')
+ cat0 = Category.objects.get(slug="country", level=0)
+ cat1 = cat0.children.get(slug="country-pop")
+ cat2 = Category.objects.get(slug="urban-cowboy")
url = cat0.get_absolute_url()
response = self.client.get(url)
self.assertEquals(response.status_code, 200)
@@ -33,51 +36,48 @@ class TestCategoryViews(TestCase):
self.assertEquals(response.status_code, 404)
def test_get_category_for_path(self):
- cat0 = Category.objects.get(slug='country', level=0)
- cat1 = cat0.children.get(slug='country-pop')
- cat2 = Category.objects.get(slug='urban-cowboy')
+ cat0 = Category.objects.get(slug="country", level=0)
+ cat1 = cat0.children.get(slug="country-pop")
+ cat2 = Category.objects.get(slug="urban-cowboy")
- result = views.get_category_for_path('/country/country-pop/urban-cowboy/')
+ result = views.get_category_for_path("/country/country-pop/urban-cowboy/")
self.assertEquals(result, cat2)
- result = views.get_category_for_path('/country/country-pop/')
+ result = views.get_category_for_path("/country/country-pop/")
self.assertEquals(result, cat1)
- result = views.get_category_for_path('/country/')
+ result = views.get_category_for_path("/country/")
self.assertEquals(result, cat0)
def test_categorydetailview(self):
- request = self.factory.get('')
+ request = self.factory.get("")
request.user = AnonymousUser()
self.assertRaises(AttributeError, views.CategoryDetailView.as_view(), request)
- request = self.factory.get('')
+ request = self.factory.get("")
request.user = AnonymousUser()
- response = views.CategoryDetailView.as_view()(request, path='/country/country-pop/urban-cowboy/')
+ response = views.CategoryDetailView.as_view()(request, path="/country/country-pop/urban-cowboy/")
self.assertEquals(response.status_code, 200)
- request = self.factory.get('')
+ request = self.factory.get("")
request.user = AnonymousUser()
- self.assertRaises(Http404, views.CategoryDetailView.as_view(), request, path='/country/country-pop/foo/')
+ self.assertRaises(Http404, views.CategoryDetailView.as_view(), request, path="/country/country-pop/foo/")
def test_categoryrelateddetailview(self):
from simpletext.models import SimpleText
- stext = SimpleText.objects.create(
- name='Test',
- description='test description'
- )
- cat = Category.objects.get(slug='urban-cowboy')
- cat_rel = CategoryRelation.objects.create( # NOQA
- category=cat,
- content_object=stext
- )
- request = self.factory.get('')
+
+ stext = SimpleText.objects.create(name="Test", description="test description")
+ cat = Category.objects.get(slug="urban-cowboy")
+ cat_rel = CategoryRelation.objects.create(category=cat, content_object=stext) # NOQA
+ request = self.factory.get("")
request.user = AnonymousUser()
self.assertRaises(AttributeError, MyCategoryRelationView.as_view(), request)
- request = self.factory.get('')
+ request = self.factory.get("")
request.user = AnonymousUser()
- response = MyCategoryRelationView.as_view()(request, category_path='/country/country-pop/urban-cowboy/')
+ response = MyCategoryRelationView.as_view()(request, category_path="/country/country-pop/urban-cowboy/")
self.assertEquals(response.status_code, 200)
- request = self.factory.get('')
+ request = self.factory.get("")
request.user = AnonymousUser()
- self.assertRaises(Http404, MyCategoryRelationView.as_view(), request, category_path='/country/country-pop/foo/')
+ self.assertRaises(
+ Http404, MyCategoryRelationView.as_view(), request, category_path="/country/country-pop/foo/"
+ )
diff --git a/categories/urls.py b/categories/urls.py
index 986df79..7160f61 100644
--- a/categories/urls.py
+++ b/categories/urls.py
@@ -1,19 +1,11 @@
from django.conf.urls import url
from django.views.generic import ListView
-from .models import Category
+
from . import views
+from .models import Category
+categorytree_dict = {"queryset": Category.objects.filter(level=0)}
-categorytree_dict = {
- 'queryset': Category.objects.filter(level=0)
-}
+urlpatterns = (url(r"^$", ListView.as_view(**categorytree_dict), name="categories_tree_list"),)
-urlpatterns = (
- url(
- r'^$', ListView.as_view(**categorytree_dict), name='categories_tree_list'
- ),
-)
-
-urlpatterns += (
- url(r'^(?P.+)/$', views.category_detail, name='categories_category'),
-)
+urlpatterns += (url(r"^(?P.+)/$", views.category_detail, name="categories_category"),)
diff --git a/categories/views.py b/categories/views.py
index 65584f6..c92752d 100644
--- a/categories/views.py
+++ b/categories/views.py
@@ -1,5 +1,5 @@
+from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404
-from django.http import HttpResponse, Http404
from django.template.loader import select_template
from django.utils.translation import ugettext_lazy as _
from django.views.generic import DetailView, ListView
@@ -7,139 +7,126 @@ from django.views.generic import DetailView, ListView
from .models import Category
-def category_detail(request, path, template_name='categories/category_detail.html', extra_context={}):
- path_items = path.strip('/').split('/')
+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,
- parent__slug__iexact=path_items[-2])
+ Category, 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)
+ category = get_object_or_404(Category, slug__iexact=path_items[-1], level=len(path_items) - 1)
templates = []
while path_items:
- templates.append('categories/%s.html' % '_'.join(path_items))
+ templates.append("categories/%s.html" % "_".join(path_items))
path_items.pop()
templates.append(template_name)
- context = {'category': category}
+ context = {"category": category}
if extra_context:
context.update(extra_context)
return HttpResponse(select_template(templates).render(context))
def get_category_for_path(path, queryset=Category.objects.all()):
- path_items = path.strip('/').split('/')
+ path_items = path.strip("/").split("/")
if len(path_items) >= 2:
queryset = queryset.filter(
- slug__iexact=path_items[-1],
- level=len(path_items) - 1,
- parent__slug__iexact=path_items[-2])
+ 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)
+ queryset = queryset.filter(slug__iexact=path_items[-1], level=len(path_items) - 1)
return queryset.get()
class CategoryDetailView(DetailView):
model = Category
- path_field = 'path'
+ path_field = "path"
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
- raise AttributeError("Category detail view %s must be called with "
- "a %s." % (self.__class__.__name__, self.path_field))
+ raise AttributeError(
+ "Category detail view %s must be called with " "a %s." % (self.__class__.__name__, self.path_field)
+ )
if self.queryset is None:
queryset = self.get_queryset()
try:
return get_category_for_path(self.kwargs[self.path_field], self.model.objects.all())
except Category.DoesNotExist:
- raise Http404(_("No %(verbose_name)s found matching the query") %
- {'verbose_name': queryset.model._meta.verbose_name})
+ raise Http404(
+ _("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('/')
+ path_items = self.kwargs[self.path_field].strip("/").split("/")
while path_items:
- names.append('categories/%s.html' % '_'.join(path_items))
+ names.append("categories/%s.html" % "_".join(path_items))
path_items.pop()
names.extend(super(CategoryDetailView, self).get_template_names())
return names
class CategoryRelatedDetail(DetailView):
- path_field = 'category_path'
+ path_field = "category_path"
object_name_field = None
def get_object(self, **kwargs):
if self.path_field not in self.kwargs:
- raise AttributeError("Category detail view %s must be called with "
- "a %s." % (self.__class__.__name__, self.path_field))
+ raise AttributeError(
+ "Category detail view %s must be called with " "a %s." % (self.__class__.__name__, self.path_field)
+ )
queryset = super(CategoryRelatedDetail, self).get_queryset()
try:
category = get_category_for_path(self.kwargs[self.path_field])
except Category.DoesNotExist:
- raise Http404(_("No %(verbose_name)s found matching the query") %
- {'verbose_name': queryset.model._meta.verbose_name})
+ raise Http404(
+ _("No %(verbose_name)s found matching the query") % {"verbose_name": queryset.model._meta.verbose_name}
+ )
return queryset.get(category=category)
def get_template_names(self):
names = []
opts = self.object._meta
- path_items = self.kwargs[self.path_field].strip('/').split('/')
+ path_items = self.kwargs[self.path_field].strip("/").split("/")
if self.object_name_field:
path_items.append(getattr(self.object, self.object_name_field))
while path_items:
- names.append('%s/category_%s_%s%s.html' % (
- opts.app_label,
- '_'.join(path_items),
- opts.object_name.lower(),
- self.template_name_suffix)
+ 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'
+ path_field = "category_path"
def get_queryset(self):
if self.path_field not in self.kwargs:
- raise AttributeError("Category detail view %s must be called with "
- "a %s." % (self.__class__.__name__, self.path_field))
+ raise AttributeError(
+ "Category detail view %s must be called with " "a %s." % (self.__class__.__name__, self.path_field)
+ )
queryset = super(CategoryRelatedList, self).get_queryset()
category = get_category_for_path(self.kwargs[self.path_field])
return queryset.filter(category=category)
def get_template_names(self):
names = []
- if hasattr(self.object_list, 'model'):
+ if hasattr(self.object_list, "model"):
opts = self.object_list.model._meta
- path_items = self.kwargs[self.path_field].strip('/').split('/')
+ 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
diff --git a/doc_src/_static/default.css b/doc_src/_static/default.css
index c719235..a95ff54 100644
--- a/doc_src/_static/default.css
+++ b/doc_src/_static/default.css
@@ -770,4 +770,4 @@ display:inline;
}
li p {
margin-top:8px;
-}
\ No newline at end of file
+}
diff --git a/doc_src/_static/toc.js b/doc_src/_static/toc.js
index 7b70978..cc06ee8 100644
--- a/doc_src/_static/toc.js
+++ b/doc_src/_static/toc.js
@@ -17,4 +17,4 @@ var TOC = {
$(document).ready(function () {
TOC.load();
-});
\ No newline at end of file
+});
diff --git a/doc_src/adding_the_fields.rst b/doc_src/adding_the_fields.rst
index a6a920f..b40709b 100644
--- a/doc_src/adding_the_fields.rst
+++ b/doc_src/adding_the_fields.rst
@@ -20,4 +20,4 @@ Reconfiguring Fields
You can make changes to the field configurations as long as they do not change the underlying database structure. For example, adding a ``related_name`` (see :ref:`registering_a_m2one_relationship`\ ) because it only affects Django code. Changing the name of the field, however, is a different matter.
-Django Categories provides a complementary management command to drop a field from the database (the field must still be in the configuration to do so): ``python manage.py drop_category_field app_name model_name field_name``
\ No newline at end of file
+Django Categories provides a complementary management command to drop a field from the database (the field must still be in the configuration to do so): ``python manage.py drop_category_field app_name model_name field_name``
diff --git a/doc_src/code_examples/custom_categories1.py b/doc_src/code_examples/custom_categories1.py
index c8d4652..68a437e 100644
--- a/doc_src/code_examples/custom_categories1.py
+++ b/doc_src/code_examples/custom_categories1.py
@@ -7,4 +7,4 @@ class SimpleCategory(CategoryBase):
"""
class Meta:
- verbose_name_plural = 'simple categories'
+ verbose_name_plural = "simple categories"
diff --git a/doc_src/code_examples/custom_categories3.py b/doc_src/code_examples/custom_categories3.py
index d2aaa6f..27babd9 100644
--- a/doc_src/code_examples/custom_categories3.py
+++ b/doc_src/code_examples/custom_categories3.py
@@ -5,29 +5,25 @@ from categories.base import CategoryBase
class Category(CategoryBase):
thumbnail = models.FileField(
upload_to=settings.THUMBNAIL_UPLOAD_PATH,
- null=True, blank=True,
- storage=settings.THUMBNAIL_STORAGE,)
+ null=True,
+ blank=True,
+ storage=settings.THUMBNAIL_STORAGE,
+ )
thumbnail_width = models.IntegerField(blank=True, null=True)
thumbnail_height = models.IntegerField(blank=True, null=True)
order = models.IntegerField(default=0)
alternate_title = models.CharField(
- blank=True,
- default="",
- max_length=100,
- help_text="An alternative title to use on pages with this category.")
+ blank=True, default="", max_length=100, help_text="An alternative title to use on pages with this category."
+ )
alternate_url = models.CharField(
blank=True,
max_length=200,
- help_text="An alternative URL to use instead of the one derived from "
- "the category hierarchy.")
+ help_text="An alternative URL to use instead of the one derived from " "the category hierarchy.",
+ )
description = models.TextField(blank=True, null=True)
meta_keywords = models.CharField(
- blank=True,
- default="",
- max_length=255,
- help_text="Comma-separated keywords for search engines.")
+ blank=True, default="", max_length=255, help_text="Comma-separated keywords for search engines."
+ )
meta_extra = models.TextField(
- blank=True,
- default="",
- help_text="(Advanced) Any additional HTML to be placed verbatim "
- "in the <head>")
+ blank=True, default="", help_text="(Advanced) Any additional HTML to be placed verbatim " "in the <head>"
+ )
diff --git a/doc_src/code_examples/custom_categories4.py b/doc_src/code_examples/custom_categories4.py
index 87e1d3a..9356e05 100644
--- a/doc_src/code_examples/custom_categories4.py
+++ b/doc_src/code_examples/custom_categories4.py
@@ -3,8 +3,9 @@ from categories.models import Category
def save(self, *args, **kwargs):
if self.thumbnail:
- from django.core.files.images import get_image_dimensions
import django
+ from django.core.files.images import get_image_dimensions
+
if django.VERSION[1] < 2:
width, height = get_image_dimensions(self.thumbnail.file)
else:
diff --git a/doc_src/code_examples/custom_categories5.py b/doc_src/code_examples/custom_categories5.py
index 67109c6..e2f48d4 100644
--- a/doc_src/code_examples/custom_categories5.py
+++ b/doc_src/code_examples/custom_categories5.py
@@ -2,8 +2,8 @@ from categories.base import CategoryBase
class Meta(CategoryBase.Meta):
- verbose_name_plural = 'categories'
+ verbose_name_plural = "categories"
class MPTTMeta:
- order_insertion_by = ('order', 'name')
+ order_insertion_by = ("order", "name")
diff --git a/doc_src/code_examples/custom_categories6.py b/doc_src/code_examples/custom_categories6.py
index 3c09f03..387aa72 100644
--- a/doc_src/code_examples/custom_categories6.py
+++ b/doc_src/code_examples/custom_categories6.py
@@ -7,7 +7,7 @@ class CategoryAdminForm(CategoryBaseAdminForm):
model = Category
def clean_alternate_title(self):
- if self.instance is None or not self.cleaned_data['alternate_title']:
- return self.cleaned_data['name']
+ if self.instance is None or not self.cleaned_data["alternate_title"]:
+ return self.cleaned_data["name"]
else:
- return self.cleaned_data['alternate_title']
+ return self.cleaned_data["alternate_title"]
diff --git a/doc_src/code_examples/custom_categories7.py b/doc_src/code_examples/custom_categories7.py
index 4fcc1a2..6ec7041 100644
--- a/doc_src/code_examples/custom_categories7.py
+++ b/doc_src/code_examples/custom_categories7.py
@@ -4,18 +4,21 @@ from categories.base import CategoryBaseAdmin
class CategoryAdmin(CategoryBaseAdmin):
form = CategoryAdminForm
- list_display = ('name', 'alternate_title', 'active')
+ list_display = ("name", "alternate_title", "active")
fieldsets = (
- (None, {
- 'fields': ('parent', 'name', 'thumbnail', 'active')
- }),
- ('Meta Data', {
- 'fields': ('alternate_title', 'alternate_url', 'description',
- 'meta_keywords', 'meta_extra'),
- 'classes': ('collapse',),
- }),
- ('Advanced', {
- 'fields': ('order', 'slug'),
- 'classes': ('collapse',),
- }),
+ (None, {"fields": ("parent", "name", "thumbnail", "active")}),
+ (
+ "Meta Data",
+ {
+ "fields": ("alternate_title", "alternate_url", "description", "meta_keywords", "meta_extra"),
+ "classes": ("collapse",),
+ },
+ ),
+ (
+ "Advanced",
+ {
+ "fields": ("order", "slug"),
+ "classes": ("collapse",),
+ },
+ ),
)
diff --git a/doc_src/conf.py b/doc_src/conf.py
index 0ffb72f..f8400c6 100644
--- a/doc_src/conf.py
+++ b/doc_src/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# Django Categories documentation build configuration file, created by
# sphinx-quickstart on Tue Oct 6 07:53:33 2009.
@@ -11,14 +10,14 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys
import os
+import sys
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('..'))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'example.settings'
+sys.path.append(os.path.abspath(".."))
+os.environ["DJANGO_SETTINGS_MODULE"] = "example.settings"
import categories # noqa
@@ -32,17 +31,17 @@ extensions = []
templates_path = ['_templates']
# The suffix of source filenames.
-source_suffix = '.rst'
+source_suffix = ".rst"
# The encoding of source files.
# ource_encoding = 'utf-8'
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# General information about the project.
-project = 'Django Categories'
-copyright = '2010-2012, Corey Oordt'
+project = "Django Categories"
+copyright = "2010-2012, Corey Oordt"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -68,7 +67,7 @@ release = categories.get_version()
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
-exclude_trees = ['_build']
+exclude_trees = ["_build"]
# The reST default role (used for this markup: `text`) to use for all documents.
# efault_role = None
@@ -85,7 +84,7 @@ exclude_trees = ['_build']
# how_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# odindex_common_prefix = []
@@ -124,7 +123,7 @@ html_theme = 'default'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
@@ -162,7 +161,7 @@ html_static_path = ['_static']
# tml_file_suffix = ''
# Output file base name for HTML help builder.
-htmlhelp_basename = 'DjangoCategoriesdoc'
+htmlhelp_basename = "DjangoCategoriesdoc"
# -- Options for LaTeX output --------------------------------------------------
@@ -176,7 +175,7 @@ htmlhelp_basename = 'DjangoCategoriesdoc'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'DjangoCategories.tex', 'Django Categories Documentation', 'CoreyOordt', 'manual'),
+ ("index", "DjangoCategories.tex", "Django Categories Documentation", "CoreyOordt", "manual"),
]
# The name of an image file (relative to this directory) to place at the top of
diff --git a/doc_src/index.rst b/doc_src/index.rst
index 9c330ed..093de5a 100644
--- a/doc_src/index.rst
+++ b/doc_src/index.rst
@@ -41,4 +41,3 @@ Indices and tables
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
-
diff --git a/doc_src/reference/management_commands.rst b/doc_src/reference/management_commands.rst
index b090695..4818672 100644
--- a/doc_src/reference/management_commands.rst
+++ b/doc_src/reference/management_commands.rst
@@ -35,4 +35,4 @@ drop_category_field
Drop the ``field_name`` field from the ``app_name_model_name`` table, if the field is currently registered in ``CATEGORIES_SETTINGS``\ .
-Requires Django South.
\ No newline at end of file
+Requires Django South.
diff --git a/doc_src/reference/settings.rst b/doc_src/reference/settings.rst
index dd0ebee..96c542f 100644
--- a/doc_src/reference/settings.rst
+++ b/doc_src/reference/settings.rst
@@ -128,4 +128,4 @@ ADMIN_FIELDSETS
**Default:** ``{}``
-**Description:** Allows for selective customization of the default behavior of adding the fields to the admin class. See :ref:`admin_settings` for more information.
\ No newline at end of file
+**Description:** Allows for selective customization of the default behavior of adding the fields to the admin class. See :ref:`admin_settings` for more information.
diff --git a/doc_src/usage.rst b/doc_src/usage.rst
index c54c3b2..83e9779 100644
--- a/doc_src/usage.rst
+++ b/doc_src/usage.rst
@@ -59,4 +59,3 @@ comma-separated list of feature names. The valid feature names are:
Books -> []
Sci-fi -> [u'Books']
Dystopian Futures -> [u'Books', u'Sci-fi']
-
diff --git a/doc_src/usage_example_template.html b/doc_src/usage_example_template.html
index b0bee73..9428cf6 100644
--- a/doc_src/usage_example_template.html
+++ b/doc_src/usage_example_template.html
@@ -25,4 +25,4 @@
No entries for {{ category }}
{% endif %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/example/settings-testing.py b/example/settings-testing.py
index 9d2c3f1..ba91a32 100644
--- a/example/settings-testing.py
+++ b/example/settings-testing.py
@@ -16,108 +16,105 @@ ADMINS = (
MANAGERS = ADMINS
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': 'dev.db',
- 'USER': '',
- 'PASSWORD': '',
- 'HOST': '',
- 'PORT': '',
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": "dev.db",
+ "USER": "",
+ "PASSWORD": "",
+ "HOST": "",
+ "PORT": "",
}
}
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',
+ "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",
)
-TIME_ZONE = 'America/Chicago'
+TIME_ZONE = "America/Chicago"
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = "en-us"
SITE_ID = 1
USE_I18N = True
-MEDIA_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, 'media', 'uploads'))
+MEDIA_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, "media", "uploads"))
-MEDIA_URL = '/uploads/'
+MEDIA_URL = "/uploads/"
-STATIC_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, 'media', 'static'))
+STATIC_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, "media", "static"))
-STATIC_URL = '/static/'
+STATIC_URL = "/static/"
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
- 'django.contrib.staticfiles.finders.FileSystemFinder',
- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+ "django.contrib.staticfiles.finders.FileSystemFinder",
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
-SECRET_KEY = 'bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d'
+SECRET_KEY = "bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d"
MIDDLEWARE = (
- 'django.middleware.security.SecurityMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ "django.middleware.security.SecurityMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
+ "django.contrib.messages.middleware.MessageMiddleware",
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
)
-ROOT_URLCONF = 'urls'
+ROOT_URLCONF = "urls"
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'APP_DIRS': True,
- 'DIRS': [os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))],
- 'OPTIONS': {
- 'debug': DEBUG,
- 'context_processors': [
- 'django.contrib.auth.context_processors.auth',
- 'django.template.context_processors.debug',
- 'django.template.context_processors.i18n',
- 'django.template.context_processors.media',
- 'django.template.context_processors.static',
- 'django.template.context_processors.tz',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "APP_DIRS": True,
+ "DIRS": [os.path.abspath(os.path.join(os.path.dirname(__file__), "templates"))],
+ "OPTIONS": {
+ "debug": DEBUG,
+ "context_processors": [
+ "django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media",
+ "django.template.context_processors.static",
+ "django.template.context_processors.tz",
+ "django.contrib.messages.context_processors.messages",
],
- }
+ },
},
]
CATEGORIES_SETTINGS = {
- 'ALLOW_SLUG_CHANGE': True,
- 'RELATION_MODELS': ['simpletext.simpletext', 'flatpages.flatpage'],
- 'FK_REGISTRY': {
- 'flatpages.flatpage': (
- 'category',
- {'on_delete': models.CASCADE}
- ),
- 'simpletext.simpletext': (
- 'primary_category',
- {'name': 'secondary_category', 'related_name': 'simpletext_sec_cat'},
+ "ALLOW_SLUG_CHANGE": True,
+ "RELATION_MODELS": ["simpletext.simpletext", "flatpages.flatpage"],
+ "FK_REGISTRY": {
+ "flatpages.flatpage": ("category", {"on_delete": models.CASCADE}),
+ "simpletext.simpletext": (
+ "primary_category",
+ {"name": "secondary_category", "related_name": "simpletext_sec_cat"},
),
},
- 'M2M_REGISTRY': {
+ "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'},
+ "flatpages.flatpage": (
+ {"name": "other_categories", "related_name": "other_cats"},
+ {"name": "more_categories", "related_name": "more_cats"},
),
},
}
-TEST_RUNNER = 'django.test.runner.DiscoverRunner'
+TEST_RUNNER = "django.test.runner.DiscoverRunner"
diff --git a/example/settings.py b/example/settings.py
index 6eab74a..c303377 100644
--- a/example/settings.py
+++ b/example/settings.py
@@ -1,6 +1,7 @@
# Django settings for sample project.
import os
import sys
+
import django
from django.db import models
@@ -16,109 +17,106 @@ ADMINS = (
MANAGERS = ADMINS
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': 'dev.db',
- 'USER': '',
- 'PASSWORD': '',
- 'HOST': '',
- 'PORT': '',
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": "dev.db",
+ "USER": "",
+ "PASSWORD": "",
+ "HOST": "",
+ "PORT": "",
}
}
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',
+ "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",
)
-TIME_ZONE = 'America/Chicago'
+TIME_ZONE = "America/Chicago"
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = "en-us"
SITE_ID = 1
USE_I18N = True
-MEDIA_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, 'media', 'uploads'))
+MEDIA_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, "media", "uploads"))
-MEDIA_URL = '/uploads/'
+MEDIA_URL = "/uploads/"
-STATIC_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, 'media', 'static'))
+STATIC_ROOT = os.path.abspath(os.path.join(PROJ_ROOT, "media", "static"))
-STATIC_URL = '/static/'
+STATIC_URL = "/static/"
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
- 'django.contrib.staticfiles.finders.FileSystemFinder',
- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+ "django.contrib.staticfiles.finders.FileSystemFinder",
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
-SECRET_KEY = 'bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d'
+SECRET_KEY = "bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d"
MIDDLEWARE = (
- 'django.middleware.security.SecurityMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ "django.middleware.security.SecurityMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
+ "django.contrib.messages.middleware.MessageMiddleware",
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
)
-ROOT_URLCONF = 'urls'
+ROOT_URLCONF = "urls"
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'APP_DIRS': True,
- 'DIRS': [os.path.abspath(os.path.join(os.path.dirname(__file__), 'templates'))],
- 'OPTIONS': {
- 'debug': DEBUG,
- 'context_processors': [
- 'django.contrib.auth.context_processors.auth',
- 'django.template.context_processors.debug',
- 'django.template.context_processors.i18n',
- 'django.template.context_processors.media',
- 'django.template.context_processors.static',
- 'django.template.context_processors.tz',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "APP_DIRS": True,
+ "DIRS": [os.path.abspath(os.path.join(os.path.dirname(__file__), "templates"))],
+ "OPTIONS": {
+ "debug": DEBUG,
+ "context_processors": [
+ "django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media",
+ "django.template.context_processors.static",
+ "django.template.context_processors.tz",
+ "django.contrib.messages.context_processors.messages",
],
- }
+ },
}
]
CATEGORIES_SETTINGS = {
- 'ALLOW_SLUG_CHANGE': True,
- 'RELATION_MODELS': ['simpletext.simpletext', 'flatpages.flatpage'],
- 'FK_REGISTRY': {
- 'flatpages.flatpage': (
- 'category',
- {'on_delete': models.CASCADE}
- ),
- 'simpletext.simpletext': (
- 'primary_category',
- {'name': 'secondary_category', 'related_name': 'simpletext_sec_cat'},
+ "ALLOW_SLUG_CHANGE": True,
+ "RELATION_MODELS": ["simpletext.simpletext", "flatpages.flatpage"],
+ "FK_REGISTRY": {
+ "flatpages.flatpage": ("category", {"on_delete": models.CASCADE}),
+ "simpletext.simpletext": (
+ "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'},
+ "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"},
),
},
}
if django.VERSION[1] > 5:
- TEST_RUNNER = 'django.test.runner.DiscoverRunner'
+ TEST_RUNNER = "django.test.runner.DiscoverRunner"
diff --git a/example/simpletext/admin.py b/example/simpletext/admin.py
index dcf1947..9539514 100644
--- a/example/simpletext/admin.py
+++ b/example/simpletext/admin.py
@@ -1,21 +1,28 @@
-from .models import SimpleText, SimpleCategory
from django.contrib import admin
from categories.admin import CategoryBaseAdmin, CategoryBaseAdminForm
+from .models import SimpleCategory, SimpleText
+
class SimpleTextAdmin(admin.ModelAdmin):
fieldsets = (
- (None, {
- 'fields': ('name', 'description', )
- }),
+ (
+ None,
+ {
+ "fields": (
+ "name",
+ "description",
+ )
+ },
+ ),
)
class SimpleCategoryAdminForm(CategoryBaseAdminForm):
class Meta:
model = SimpleCategory
- fields = '__all__'
+ fields = "__all__"
class SimpleCategoryAdmin(CategoryBaseAdmin):
diff --git a/example/simpletext/migrations/0001_initial.py b/example/simpletext/migrations/0001_initial.py
index d66db39..fe231e1 100644
--- a/example/simpletext/migrations/0001_initial.py
+++ b/example/simpletext/migrations/0001_initial.py
@@ -1,10 +1,9 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2017-10-12 20:27
from __future__ import unicode_literals
-from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
+from django.db import migrations, models
class Migration(migrations.Migration):
@@ -15,35 +14,45 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
- name='SimpleCategory',
+ name="SimpleCategory",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=100, verbose_name='name')),
- ('slug', models.SlugField(verbose_name='slug')),
- ('active', models.BooleanField(default=True, verbose_name='active')),
- ('lft', models.PositiveIntegerField(db_index=True, editable=False)),
- ('rght', models.PositiveIntegerField(db_index=True, editable=False)),
- ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
- ('level', models.PositiveIntegerField(db_index=True, editable=False)),
- ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='simpletext.SimpleCategory', verbose_name='parent')),
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
+ ("name", models.CharField(max_length=100, verbose_name="name")),
+ ("slug", models.SlugField(verbose_name="slug")),
+ ("active", models.BooleanField(default=True, verbose_name="active")),
+ ("lft", models.PositiveIntegerField(db_index=True, editable=False)),
+ ("rght", models.PositiveIntegerField(db_index=True, editable=False)),
+ ("tree_id", models.PositiveIntegerField(db_index=True, editable=False)),
+ ("level", models.PositiveIntegerField(db_index=True, editable=False)),
+ (
+ "parent",
+ mptt.fields.TreeForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="children",
+ to="simpletext.SimpleCategory",
+ verbose_name="parent",
+ ),
+ ),
],
options={
- 'verbose_name_plural': 'simple categories',
+ "verbose_name_plural": "simple categories",
},
),
migrations.CreateModel(
- name='SimpleText',
+ name="SimpleText",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('name', models.CharField(max_length=255)),
- ('description', models.TextField(blank=True)),
- ('created', models.DateTimeField(auto_now_add=True)),
- ('updated', models.DateTimeField(auto_now=True)),
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
+ ("name", models.CharField(max_length=255)),
+ ("description", models.TextField(blank=True)),
+ ("created", models.DateTimeField(auto_now_add=True)),
+ ("updated", models.DateTimeField(auto_now=True)),
],
options={
- 'ordering': ('-created',),
- 'get_latest_by': 'updated',
- 'verbose_name_plural': 'Simple Text',
+ "ordering": ("-created",),
+ "get_latest_by": "updated",
+ "verbose_name_plural": "Simple Text",
},
),
]
diff --git a/example/simpletext/migrations/0002_auto_20171204_0721.py b/example/simpletext/migrations/0002_auto_20171204_0721.py
index 2205f4c..6ce4e0a 100644
--- a/example/simpletext/migrations/0002_auto_20171204_0721.py
+++ b/example/simpletext/migrations/0002_auto_20171204_0721.py
@@ -1,39 +1,46 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-12-04 07:21
from __future__ import unicode_literals
-from django.db import migrations, models
import django.db.models.deletion
import django.db.models.manager
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('categories', '0002_auto_20170217_1111'),
- ('simpletext', '0001_initial'),
+ ("categories", "0002_auto_20170217_1111"),
+ ("simpletext", "0001_initial"),
]
operations = [
migrations.AlterModelManagers(
- name='simplecategory',
+ name="simplecategory",
managers=[
- ('tree', django.db.models.manager.Manager()),
+ ("tree", django.db.models.manager.Manager()),
],
),
migrations.AddField(
- model_name='simpletext',
- name='categories',
- field=models.ManyToManyField(blank=True, related_name='m2mcats', to='categories.Category'),
+ model_name="simpletext",
+ name="categories",
+ field=models.ManyToManyField(blank=True, related_name="m2mcats", to="categories.Category"),
),
migrations.AddField(
- model_name='simpletext',
- name='primary_category',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='categories.Category'),
+ model_name="simpletext",
+ name="primary_category",
+ field=models.ForeignKey(
+ blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="categories.Category"
+ ),
),
migrations.AddField(
- model_name='simpletext',
- name='secondary_category',
- field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='simpletext_sec_cat', to='categories.Category'),
+ model_name="simpletext",
+ name="secondary_category",
+ field=models.ForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="simpletext_sec_cat",
+ to="categories.Category",
+ ),
),
]
diff --git a/example/simpletext/migrations/0003_auto_20200306_0928.py b/example/simpletext/migrations/0003_auto_20200306_0928.py
index 0d786bc..a33be27 100644
--- a/example/simpletext/migrations/0003_auto_20200306_0928.py
+++ b/example/simpletext/migrations/0003_auto_20200306_0928.py
@@ -6,23 +6,23 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('simpletext', '0002_auto_20171204_0721'),
+ ("simpletext", "0002_auto_20171204_0721"),
]
operations = [
migrations.AlterField(
- model_name='simplecategory',
- name='level',
+ model_name="simplecategory",
+ name="level",
field=models.PositiveIntegerField(editable=False),
),
migrations.AlterField(
- model_name='simplecategory',
- name='lft',
+ model_name="simplecategory",
+ name="lft",
field=models.PositiveIntegerField(editable=False),
),
migrations.AlterField(
- model_name='simplecategory',
- name='rght',
+ model_name="simplecategory",
+ name="rght",
field=models.PositiveIntegerField(editable=False),
),
]
diff --git a/example/simpletext/models.py b/example/simpletext/models.py
index 0fe96d1..e7ccaed 100755
--- a/example/simpletext/models.py
+++ b/example/simpletext/models.py
@@ -14,9 +14,9 @@ class SimpleText(models.Model):
updated = models.DateTimeField(auto_now=True)
class Meta:
- verbose_name_plural = 'Simple Text'
- ordering = ('-created',)
- get_latest_by = 'updated'
+ verbose_name_plural = "Simple Text"
+ ordering = ("-created",)
+ get_latest_by = "updated"
def __unicode__(self):
return self.name
@@ -24,16 +24,19 @@ class SimpleText(models.Model):
def get_absolute_url(self):
try:
from django.db.models import permalink
- return permalink('simpletext_detail_view_name', [str(self.id)])
+
+ return permalink("simpletext_detail_view_name", [str(self.id)])
except ImportError:
from django.urls import reverse
- return reverse('simpletext_detail_view_name', args=[str(self.id)])
+
+ return reverse("simpletext_detail_view_name", args=[str(self.id)])
class SimpleCategory(CategoryBase):
"""A Test of catgorizing"""
+
class Meta:
- verbose_name_plural = 'simple categories'
+ verbose_name_plural = "simple categories"
# mport categories
diff --git a/example/simpletext/tests.py b/example/simpletext/tests.py
index 73d6465..f51d798 100755
--- a/example/simpletext/tests.py
+++ b/example/simpletext/tests.py
@@ -16,9 +16,11 @@ class SimpleTest(TestCase):
self.assertEqual(1 + 1, 2)
-__test__ = {"doctest": """
+__test__ = {
+ "doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
-"""}
+"""
+}
diff --git a/example/static/editor/jquery.treeTable.css b/example/static/editor/jquery.treeTable.css
index f9fccd9..26828b6 100644
--- a/example/static/editor/jquery.treeTable.css
+++ b/example/static/editor/jquery.treeTable.css
@@ -62,4 +62,4 @@
.treeTable .ui-draggable-dragging {
color: #000;
z-index: 1;
-}
\ No newline at end of file
+}
diff --git a/example/static/editor/jquery.treeTable.js b/example/static/editor/jquery.treeTable.js
index 522b2c5..412bdaf 100644
--- a/example/static/editor/jquery.treeTable.js
+++ b/example/static/editor/jquery.treeTable.js
@@ -455,4 +455,4 @@
function parentOf(node) {
return $(node).parentOf();
}
-})(django.jQuery);
\ No newline at end of file
+})(django.jQuery);
diff --git a/example/static/js/genericcollections.js b/example/static/js/genericcollections.js
index 584208e..8081eb8 100644
--- a/example/static/js/genericcollections.js
+++ b/example/static/js/genericcollections.js
@@ -17,4 +17,4 @@ function showGenericRelatedObjectLookupPopup(triggeringLink, ctArray) {
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
-}
\ No newline at end of file
+}
diff --git a/example/urls.py b/example/urls.py
index 4c34998..cab9d28 100644
--- a/example/urls.py
+++ b/example/urls.py
@@ -12,23 +12,16 @@ ROOT_PATH = os.path.dirname(os.path.dirname(__file__))
urlpatterns = (
# Example:
# (r'^sample/', include('sample.foo.urls')),
-
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
# Uncomment the next line to enable the admin:
- url(r'^admin/', admin.site.urls),
- url(r'^categories/', include('categories.urls')),
+ url(r"^admin/", admin.site.urls),
+ url(r"^categories/", include("categories.urls")),
# r'^cats/', include('categories.urls')),
-
- url(r'^static/categories/(?P.*)$', serve,
- {'document_root': ROOT_PATH + '/categories/media/categories/'}),
-
+ url(r"^static/categories/(?P.*)$", serve, {"document_root": ROOT_PATH + "/categories/media/categories/"}),
# (r'^static/editor/(?P.*)$', 'django.views.static.serve',
# {'document_root': ROOT_PATH + '/editor/media/editor/',
# 'show_indexes':True}),
-
- url(r'^static/(?P.*)$', serve, {'document_root': os.path.join(ROOT_PATH, 'example', 'static')}),
-
+ url(r"^static/(?P.*)$", serve, {"document_root": os.path.join(ROOT_PATH, "example", "static")}),
)