mirror of
https://github.com/jazzband/django-categories.git
synced 2026-03-16 22:30:24 +00:00
Made updates to get everything working with Django 2
This commit is contained in:
parent
e770596430
commit
366ff74619
16 changed files with 91 additions and 38 deletions
|
|
@ -37,10 +37,12 @@ class CategoryBase(MPTTModel):
|
|||
"""
|
||||
parent = TreeForeignKey(
|
||||
'self',
|
||||
on_delete=models.CASCADE,
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name='children',
|
||||
verbose_name=_('parent'))
|
||||
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'))
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def items_for_tree_result(cl, result, form):
|
|||
result_repr = get_empty_value_display(cl)
|
||||
else:
|
||||
if f is None:
|
||||
if django.VERSION[1] == 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] == 4:
|
||||
if field_name == 'action_checkbox':
|
||||
row_class = ' class="action-checkbox disclosure"'
|
||||
allow_tags = getattr(attr, 'allow_tags', False)
|
||||
|
|
@ -60,14 +60,14 @@ def items_for_tree_result(cl, result, form):
|
|||
else:
|
||||
if value is None:
|
||||
result_repr = get_empty_value_display(cl)
|
||||
if 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, '')
|
||||
if isinstance(f, models.DateField) or isinstance(f, models.TimeField):
|
||||
row_class = ' class="nowrap"'
|
||||
if first:
|
||||
if django.VERSION[1] < 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
|
||||
try:
|
||||
f, attr, checkbox_value = lookup_field('action_checkbox', result, cl.model_admin)
|
||||
if row_class:
|
||||
|
|
@ -81,7 +81,7 @@ def items_for_tree_result(cl, result, form):
|
|||
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[1] < 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
|
||||
table_tag = 'td' # {True:'th', False:'td'}[first]
|
||||
else:
|
||||
table_tag = {True: 'th', False: 'td'}[first]
|
||||
|
|
@ -160,7 +160,7 @@ def result_tree_list(cl):
|
|||
'result_headers': list(result_headers(cl)),
|
||||
'results': list(tree_results(cl))
|
||||
}
|
||||
if django.VERSION[1] > 2:
|
||||
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))
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -67,13 +67,13 @@ class TreeEditorQuerySet(QuerySet):
|
|||
|
||||
class TreeChangeList(ChangeList):
|
||||
def _get_default_ordering(self):
|
||||
if django.VERSION[1] < 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
|
||||
return '', '' # ('tree_id', 'lft')
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_ordering(self, request=None, queryset=None):
|
||||
if django.VERSION[1] < 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
|
||||
return '', '' # ('tree_id', 'lft')
|
||||
else:
|
||||
return []
|
||||
|
|
@ -142,7 +142,7 @@ class TreeEditor(admin.ModelAdmin):
|
|||
pass
|
||||
|
||||
try:
|
||||
if django.VERSION[1] < 4:
|
||||
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,
|
||||
|
|
@ -241,7 +241,7 @@ class TreeEditor(admin.ModelAdmin):
|
|||
'actions_on_top': self.actions_on_top,
|
||||
'actions_on_bottom': self.actions_on_bottom,
|
||||
}
|
||||
if django.VERSION[1] < 4:
|
||||
if django.VERSION[0] == 1 and django.VERSION[1] < 4:
|
||||
context['root_path'] = self.admin_site.root_path
|
||||
else:
|
||||
selection_note_all = ungettext('%(total_count)s selected', 'All %(total_count)s selected', cl.result_count)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from django.contrib import admin
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.urlresolvers import reverse, NoReverseMatch
|
||||
from django.urls import reverse, NoReverseMatch
|
||||
import json
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Migration(migrations.Migration):
|
|||
('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', null=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'),
|
||||
|
|
@ -48,8 +48,8 @@ class Migration(migrations.Migration):
|
|||
('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')),
|
||||
('content_type', models.ForeignKey(verbose_name='content type', to='contenttypes.ContentType')),
|
||||
('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(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from django.core.files.images import get_image_dimensions
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.db import models
|
||||
from django.utils.encoding import force_text
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
|
@ -55,7 +55,7 @@ class Category(CategoryBase):
|
|||
|
||||
def get_absolute_url(self):
|
||||
"""Return a path"""
|
||||
from django.core.urlresolvers import NoReverseMatch
|
||||
from django.urls import NoReverseMatch
|
||||
|
||||
if self.alternate_url:
|
||||
return self.alternate_url
|
||||
|
|
@ -123,9 +123,9 @@ class CategoryRelationManager(models.Manager):
|
|||
|
||||
class CategoryRelation(models.Model):
|
||||
"""Related category item"""
|
||||
category = models.ForeignKey(Category, verbose_name=_('category'))
|
||||
category = models.ForeignKey(Category, verbose_name=_('category'), on_delete=models.CASCADE)
|
||||
content_type = models.ForeignKey(
|
||||
ContentType, limit_choices_to=CATEGORY_RELATION_LIMITS, verbose_name=_('content type'))
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class Registry(object):
|
|||
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
|
||||
if isinstance(fld, str):
|
||||
field_name = fld
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ class CategoryDrillDownNode(template.Node):
|
|||
context[self.varname] = drilldown_tree_for_node(cat)
|
||||
else:
|
||||
context[self.varname] = []
|
||||
except:
|
||||
except Exception:
|
||||
context[self.varname] = []
|
||||
return ''
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.urls import reverse
|
||||
from django.test import Client, TestCase
|
||||
from django.utils.encoding import smart_text
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ from django.test import TestCase
|
|||
class TestMgmtCommands(TestCase):
|
||||
|
||||
def test_add_category_fields(self):
|
||||
management.call_command('add_category_fields', verbosity=0, interactive=False)
|
||||
management.call_command('add_category_fields', verbosity=0)
|
||||
|
||||
def test_add_category_fields_app(self):
|
||||
management.call_command('add_category_fields', 'flatpages', verbosity=0, interactive=False)
|
||||
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, interactive=False)
|
||||
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, interactive=False)
|
||||
self.assertRaises(CommandError, management.call_command, 'drop_category_field', verbosity=0)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
from django.db import models
|
||||
|
||||
APP = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
PROJ_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.insert(0, APP)
|
||||
|
|
@ -64,13 +66,14 @@ STATICFILES_FINDERS = (
|
|||
|
||||
SECRET_KEY = 'bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d'
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
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.contrib.auth.middleware.SessionAuthenticationMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'urls'
|
||||
|
|
@ -99,7 +102,10 @@ CATEGORIES_SETTINGS = {
|
|||
'ALLOW_SLUG_CHANGE': True,
|
||||
'RELATION_MODELS': ['simpletext.simpletext', 'flatpages.flatpage'],
|
||||
'FK_REGISTRY': {
|
||||
'flatpages.flatpage': 'category',
|
||||
'flatpages.flatpage': (
|
||||
'category',
|
||||
{'on_delete': models.CASCADE}
|
||||
),
|
||||
'simpletext.simpletext': (
|
||||
'primary_category',
|
||||
{'name': 'secondary_category', 'related_name': 'simpletext_sec_cat'},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import os
|
||||
import sys
|
||||
import django
|
||||
from django.db import models
|
||||
|
||||
APP = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
PROJ_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
|
@ -65,12 +66,14 @@ STATICFILES_FINDERS = (
|
|||
|
||||
SECRET_KEY = 'bwq#m)-zsey-fs)0#4*o=2z(v5g!ei=zytl9t-1hesh4b&-u^d'
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
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',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'urls'
|
||||
|
|
@ -99,7 +102,10 @@ CATEGORIES_SETTINGS = {
|
|||
'ALLOW_SLUG_CHANGE': True,
|
||||
'RELATION_MODELS': ['simpletext.simpletext', 'flatpages.flatpage'],
|
||||
'FK_REGISTRY': {
|
||||
'flatpages.flatpage': 'category',
|
||||
'flatpages.flatpage': (
|
||||
'category',
|
||||
{'on_delete': models.CASCADE}
|
||||
),
|
||||
'simpletext.simpletext': (
|
||||
'primary_category',
|
||||
{'name': 'secondary_category', 'related_name': 'simpletext_sec_cat'},
|
||||
|
|
|
|||
39
example/simpletext/migrations/0002_auto_20171204_0721.py
Normal file
39
example/simpletext/migrations/0002_auto_20171204_0721.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# -*- 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
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('categories', '0002_auto_20170217_1111'),
|
||||
('simpletext', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelManagers(
|
||||
name='simplecategory',
|
||||
managers=[
|
||||
('tree', django.db.models.manager.Manager()),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
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'),
|
||||
),
|
||||
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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -18,7 +18,7 @@ urlpatterns = (
|
|||
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
url(r'^admin/', admin.site.urls),
|
||||
url(r'^categories/', include('categories.urls')),
|
||||
# r'^cats/', include('categories.urls')),
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
django-mptt>=0.8.6,<0.9
|
||||
django-mptt>=0.9.0,<0.10
|
||||
unicode-slugify==0.1.3
|
||||
|
|
|
|||
9
tox.ini
9
tox.ini
|
|
@ -2,23 +2,22 @@
|
|||
envlist =
|
||||
begin
|
||||
py27-lint
|
||||
py27-django{18,19,110}
|
||||
py36-django{18,19,110,111}
|
||||
py27-django{110,111}
|
||||
py36-django{110,111,2}
|
||||
coverage-report
|
||||
|
||||
[testenv]
|
||||
deps=
|
||||
django2: Django<2.1
|
||||
django111: Django<2.0
|
||||
django110: Django<1.11
|
||||
django19: Django<1.10
|
||||
django18: Django<1.9
|
||||
coverage
|
||||
pillow
|
||||
ipdb
|
||||
-r{toxinidir}/requirements.txt
|
||||
|
||||
commands=
|
||||
coverage run --source=categories --omit='.tox/*,example/*,*/tests/*' {toxinidir}/example/manage.py test --settings='settings-testing' categories
|
||||
coverage run --source=categories --omit='.tox/*,example/*,*/tests/*' {toxinidir}/example/manage.py test --settings='settings-testing' categories{posargs}
|
||||
|
||||
[testenv:begin]
|
||||
commands = coverage erase
|
||||
|
|
|
|||
Loading…
Reference in a new issue