[Python-modules-commits] [python-django-treebeard] 01/11: Import python-django-treebeard_4.1.2+dfsg.orig.tar.gz
Michael Fladischer
fladi at moszumanska.debian.org
Wed Jul 12 20:44:03 UTC 2017
This is an automated email from the git hooks/post-receive script.
fladi pushed a commit to branch master
in repository python-django-treebeard.
commit fa17de54982188d431a9b41c73231cf5392aa235
Author: Michael Fladischer <fladi at debian.org>
Date: Fri Jun 23 11:35:28 2017 +0200
Import python-django-treebeard_4.1.2+dfsg.orig.tar.gz
---
CHANGES | 14 ++
MANIFEST.in | 1 +
PKG-INFO | 21 +-
README.rst | 19 +-
django_treebeard.egg-info/PKG-INFO | 21 +-
django_treebeard.egg-info/SOURCES.txt | 5 +
docs/README.md | 23 ++
docs/make.bat | 263 +++++++++++++++++++++
docs/source/_ext/djangodocs.py | 10 +
docs/source/_static/treebeard-admin-advanced.png | Bin 0 -> 116531 bytes
docs/source/_static/treebeard-admin-basic.png | Bin 0 -> 96077 bytes
docs/source/tutorial.rst | 12 +-
setup.cfg | 1 -
treebeard/__init__.py | 2 +-
treebeard/mp_tree.py | 99 +++++---
.../templates/admin/tree_change_list_results.html | 62 ++---
treebeard/templates/admin/tree_list_results.html | 1 -
treebeard/tests/settings.py | 13 +
18 files changed, 494 insertions(+), 73 deletions(-)
diff --git a/CHANGES b/CHANGES
index fa29e61..479918b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,17 @@
+Release 4.1.2 (Jun 22, 2017)
+---------------------------
+
+* Fixed MANIFEST.in for Debian packaging.
+
+
+Release 4.1.1 (May 24, 2017)
+---------------------------
+
+* Removed deprecated templatetag inclusion
+* Added support for Python-3.6
+* Added support for MS-SQL
+
+
Release 4.1.0 (Nov 24, 2016)
---------------------------
diff --git a/MANIFEST.in b/MANIFEST.in
index 99ca10d..3a0efcb 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -3,3 +3,4 @@ recursive-include treebeard *.py
recursive-include treebeard/static *
recursive-include treebeard/templates *
recursive-include treebeard/locale *
+recursive-include docs Makefile README.md make.bat *.py *.png *.rst
diff --git a/PKG-INFO b/PKG-INFO
index d165513..f71bd45 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: django-treebeard
-Version: 4.1.0
+Version: 4.1.2
Summary: Efficient tree implementations for Django
Home-page: https://github.com/django-treebeard/django-treebeard/
Author: Gustavo Picon
@@ -11,10 +11,27 @@ Description: ================
================
**django-treebeard** is a library that implements efficient tree implementations
- for the Django Web Framework 1.7 and later.
+ for the Django Web Framework 1.8 and later.
It is written by Gustavo Picón and licensed under the Apache License 2.0.
+ Status
+ ------
+
+ .. image:: https://readthedocs.org/projects/django-treebeard/badge/?version=latest
+ :target: https://readthedocs.org/projects/django-treebeard/
+
+ .. image:: https://travis-ci.org/django-treebeard/django-treebeard.svg?branch=master
+ :target: https://travis-ci.org/django-treebeard/django-treebeard
+
+ .. image:: https://ci.appveyor.com/api/projects/status/mwbf062v68lhw05c?svg=true
+ :target: https://ci.appveyor.com/project/mvantellingen/django-treebeard
+
+ .. image:: https://img.shields.io/pypi/v/django-treebeard.svg
+ :target: https://pypi.python.org/pypi/django-treebeard/
+
+ Features
+ --------
django-treebeard is:
- **Flexible**: Includes 3 different tree implementations with the same API:
diff --git a/README.rst b/README.rst
index 0294d14..2d8ad10 100644
--- a/README.rst
+++ b/README.rst
@@ -3,10 +3,27 @@ django-treebeard
================
**django-treebeard** is a library that implements efficient tree implementations
-for the Django Web Framework 1.7 and later.
+for the Django Web Framework 1.8 and later.
It is written by Gustavo Picón and licensed under the Apache License 2.0.
+Status
+------
+
+.. image:: https://readthedocs.org/projects/django-treebeard/badge/?version=latest
+ :target: https://readthedocs.org/projects/django-treebeard/
+
+.. image:: https://travis-ci.org/django-treebeard/django-treebeard.svg?branch=master
+ :target: https://travis-ci.org/django-treebeard/django-treebeard
+
+.. image:: https://ci.appveyor.com/api/projects/status/mwbf062v68lhw05c?svg=true
+ :target: https://ci.appveyor.com/project/mvantellingen/django-treebeard
+
+.. image:: https://img.shields.io/pypi/v/django-treebeard.svg
+ :target: https://pypi.python.org/pypi/django-treebeard/
+
+Features
+--------
django-treebeard is:
- **Flexible**: Includes 3 different tree implementations with the same API:
diff --git a/django_treebeard.egg-info/PKG-INFO b/django_treebeard.egg-info/PKG-INFO
index d165513..f71bd45 100644
--- a/django_treebeard.egg-info/PKG-INFO
+++ b/django_treebeard.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: django-treebeard
-Version: 4.1.0
+Version: 4.1.2
Summary: Efficient tree implementations for Django
Home-page: https://github.com/django-treebeard/django-treebeard/
Author: Gustavo Picon
@@ -11,10 +11,27 @@ Description: ================
================
**django-treebeard** is a library that implements efficient tree implementations
- for the Django Web Framework 1.7 and later.
+ for the Django Web Framework 1.8 and later.
It is written by Gustavo Picón and licensed under the Apache License 2.0.
+ Status
+ ------
+
+ .. image:: https://readthedocs.org/projects/django-treebeard/badge/?version=latest
+ :target: https://readthedocs.org/projects/django-treebeard/
+
+ .. image:: https://travis-ci.org/django-treebeard/django-treebeard.svg?branch=master
+ :target: https://travis-ci.org/django-treebeard/django-treebeard
+
+ .. image:: https://ci.appveyor.com/api/projects/status/mwbf062v68lhw05c?svg=true
+ :target: https://ci.appveyor.com/project/mvantellingen/django-treebeard
+
+ .. image:: https://img.shields.io/pypi/v/django-treebeard.svg
+ :target: https://pypi.python.org/pypi/django-treebeard/
+
+ Features
+ --------
django-treebeard is:
- **Flexible**: Includes 3 different tree implementations with the same API:
diff --git a/django_treebeard.egg-info/SOURCES.txt b/django_treebeard.egg-info/SOURCES.txt
index 12b59f6..2854c37 100644
--- a/django_treebeard.egg-info/SOURCES.txt
+++ b/django_treebeard.egg-info/SOURCES.txt
@@ -11,6 +11,8 @@ django_treebeard.egg-info/dependency_links.txt
django_treebeard.egg-info/requires.txt
django_treebeard.egg-info/top_level.txt
docs/Makefile
+docs/README.md
+docs/make.bat
docs/source/admin.rst
docs/source/al_tree.rst
docs/source/api.rst
@@ -25,6 +27,9 @@ docs/source/mp_tree.rst
docs/source/ns_tree.rst
docs/source/tests.rst
docs/source/tutorial.rst
+docs/source/_ext/djangodocs.py
+docs/source/_static/treebeard-admin-advanced.png
+docs/source/_static/treebeard-admin-basic.png
treebeard/__init__.py
treebeard/admin.py
treebeard/al_tree.py
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..6285310
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,23 @@
+This is the documentation source for django-treebeard.
+You can read the documentation on:
+
+http://django-treebeard.readthedocs.io/en/latest/
+
+Or create the documentation yourself by compiling the ReStructured Text files:
+
+If you want to build the docs you'll need the graphviz tool, if you are using a Mac and Brew
+you can install it like this:
+
+$ brew install graphviz
+
+Then you'll need at least Django and Sphinx:
+
+$ pip install Django
+$ pip install Sphinx
+
+To build the docs run:
+
+```bash
+$ cd docs/
+$ make html
+```
\ No newline at end of file
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..23f696e
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,263 @@
+ at ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set I18NSPHINXOPTS=%SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ echo. coverage to run coverage check of the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+REM Check if sphinx-build is available and fallback to Python version if any
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 goto sphinx_python
+goto sphinx_ok
+
+:sphinx_python
+
+set SPHINXBUILD=python -m sphinx.__init__
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+:sphinx_ok
+
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-treebeard.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-treebeard.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "coverage" (
+ %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of coverage in the sources finished, look at the ^
+results in %BUILDDIR%/coverage/python.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/docs/source/_ext/djangodocs.py b/docs/source/_ext/djangodocs.py
new file mode 100644
index 0000000..3b59f3c
--- /dev/null
+++ b/docs/source/_ext/djangodocs.py
@@ -0,0 +1,10 @@
+# taken from:
+# http://reinout.vanrees.org/weblog/2012/12/01/django-intersphinx.html
+
+
+def setup(app):
+ app.add_crossref_type(
+ directivename="setting",
+ rolename="setting",
+ indextemplate="pair: %s; setting",
+ )
diff --git a/docs/source/_static/treebeard-admin-advanced.png b/docs/source/_static/treebeard-admin-advanced.png
new file mode 100644
index 0000000..28e9539
Binary files /dev/null and b/docs/source/_static/treebeard-admin-advanced.png differ
diff --git a/docs/source/_static/treebeard-admin-basic.png b/docs/source/_static/treebeard-admin-basic.png
new file mode 100644
index 0000000..b0d010f
Binary files /dev/null and b/docs/source/_static/treebeard-admin-basic.png differ
diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst
index 86d5756..7a92709 100644
--- a/docs/source/tutorial.rst
+++ b/docs/source/tutorial.rst
@@ -1,22 +1,26 @@
Tutorial
========
-Create a basic model for your tree. In this example we'll use a Materialized
-Path tree:
+Create a basic model for your tree. In this example we'll use a Materialized Path tree:
.. code-block:: python
from django.db import models
+ from django.utils.encoding import python_2_unicode_compatible
+
from treebeard.mp_tree import MP_Node
+ @python_2_unicode_compatible
class Category(MP_Node):
name = models.CharField(max_length=30)
node_order_by = ['name']
- def __unicode__(self):
- return 'Category: %s' % self.name
+ def __str__(self):
+ return 'Category: {}'.format(self.name)
+This example works on Python 3 as well as on Python 2. If you don't need Python 2 support
+remove the ``@python_2_unicode_compatible`` decorator.
Run syncdb:
diff --git a/setup.cfg b/setup.cfg
index 861a9f5..8bfd5a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,4 @@
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff --git a/treebeard/__init__.py b/treebeard/__init__.py
index 41458ca..b8edffd 100644
--- a/treebeard/__init__.py
+++ b/treebeard/__init__.py
@@ -17,4 +17,4 @@ Release logic:
11. git commit -m 'Start with <version>'
12. git push
"""
-__version__ = '4.1.0'
+__version__ = '4.1.2'
diff --git a/treebeard/mp_tree.py b/treebeard/mp_tree.py
index bc3698f..99753b6 100644
--- a/treebeard/mp_tree.py
+++ b/treebeard/mp_tree.py
@@ -17,6 +17,34 @@ from treebeard.exceptions import InvalidMoveToDescendant, PathOverflow,\
NodeAlreadySaved
+# The following functions generate vendor-specific SQL functions
+def sql_concat(*args, **kwargs):
+ vendor = kwargs.pop('vendor', None)
+ if vendor == 'mysql':
+ return 'CONCAT({})'.format(', '.join(args))
+ if vendor == 'microsoft':
+ return ' + '.join(args)
+ return '||'.join(args)
+
+
+def sql_length(field, vendor=None):
+ if vendor == 'microsoft':
+ return 'LEN({})'.format(field)
+ return 'LENGTH({})'.format(field)
+
+
+def sql_substr(field, pos, length=None, **kwargs):
+ vendor = kwargs.pop('vendor', None)
+ function = 'SUBSTR({field}, {pos})'
+ if length:
+ function = 'SUBSTR({field}, {pos}, {length})'
+ if vendor == 'microsoft':
+ if not length:
+ length = 'LEN({})'.format(field)
+ function = 'SUBSTRING({field}, {pos}, {length})'
+ return function.format(field=field, pos=pos, length=length)
+
+
def get_result_class(cls):
"""
For the given model class, determine what class we should use for the
@@ -261,7 +289,7 @@ class MP_ComplexAddMoveHandler(MP_AddHandler):
# http://dev.mysql.com/doc/refman/5.0/en/ansi-mode.html
sqlpath = "CONCAT(%s, SUBSTR(path, %s))"
else:
- sqlpath = "%s||SUBSTR(path, %s)"
+ sqlpath = sql_concat("%s", sql_substr("path", "%s", vendor=vendor), vendor=vendor)
sql2 = ["path=%s" % (sqlpath, )]
vals = [newpath, len(oldpath) + 1]
@@ -270,7 +298,7 @@ class MP_ComplexAddMoveHandler(MP_AddHandler):
# done in another query
# doesn't even work with sql_mode='ANSI,TRADITIONAL'
# TODO: FIND OUT WHY?!?? right now I'm just blaming mysql
- sql2.append("depth=LENGTH(%s)/%%s" % (sqlpath, ))
+ sql2.append(("depth=" + sql_length("%s", vendor=vendor) + "/%%s") % (sqlpath, ))
vals.extend([newpath, len(oldpath) + 1, self.node_cls.steplen])
sql3 = "WHERE path LIKE %s"
vals.extend([oldpath + '%'])
@@ -544,7 +572,8 @@ class MP_MoveHandler(MP_ComplexAddMoveHandler):
:returns: The sql needed to update the depth of all the nodes in a
branch.
"""
- sql = "UPDATE %s SET depth=LENGTH(path)/%%s WHERE path LIKE %%s" % (
+ vendor = self.node_cls.get_database_vendor('write')
+ sql = ("UPDATE %s SET depth=" + sql_length("path", vendor=vendor) + "/%%s WHERE path LIKE %%s") % (
connection.ops.quote_name(
get_result_class(self.node_cls)._meta.db_table), )
vals = [self.node_cls.steplen, path + '%']
@@ -660,6 +689,7 @@ class MP_Node(Node):
5. a list of ids nodes that report a wrong number of children
"""
cls = get_result_class(cls)
+ vendor = cls.get_database_vendor('write')
evil_chars, bad_steplen, orphans = [], [], []
wrong_depth, wrong_numchild = [], []
@@ -688,7 +718,7 @@ class MP_Node(Node):
real_numchild = cls.objects.filter(
path__range=cls._get_children_path_interval(node.path)
).extra(
- where=['LENGTH(path)/%d=%d' % (cls.steplen, node.depth + 1)]
+ where=[(sql_length("path", vendor=vendor) + '/%d=%d') % (cls.steplen, node.depth + 1)]
).count()
if real_numchild != node.numchild:
wrong_numchild.append(node.pk)
@@ -735,6 +765,7 @@ class MP_Node(Node):
patches are welcome).
"""
cls = get_result_class(cls)
+ vendor = cls.get_database_vendor('write')
if destructive:
dump = cls.dump_bulk(None, True)
@@ -745,10 +776,11 @@ class MP_Node(Node):
# fix the depth field
# we need the WHERE to speed up postgres
- sql = "UPDATE %s "\
- "SET depth=LENGTH(path)/%%s "\
- "WHERE depth!=LENGTH(path)/%%s" % (
- connection.ops.quote_name(cls._meta.db_table), )
+ sql = (
+ "UPDATE %s "
+ "SET depth=" + sql_length("path", vendor=vendor) + "/%%s "
+ "WHERE depth!=" + sql_length("path", vendor=vendor) + "/%%s"
+ ) % (connection.ops.quote_name(cls._meta.db_table), )
vals = [cls.steplen, cls.steplen]
cursor.execute(sql, vals)
@@ -756,18 +788,18 @@ class MP_Node(Node):
vals = ['_' * cls.steplen]
# the cake and sql portability are a lie
if cls.get_database_vendor('read') == 'mysql':
- sql = "SELECT tbn1.path, tbn1.numchild, ("\
- "SELECT COUNT(1) "\
- "FROM %(table)s AS tbn2 "\
- "WHERE tbn2.path LIKE "\
- "CONCAT(tbn1.path, %%s)) AS real_numchild "\
- "FROM %(table)s AS tbn1 "\
- "HAVING tbn1.numchild != real_numchild" % {
- 'table': connection.ops.quote_name(
- cls._meta.db_table)}
+ sql = (
+ "SELECT tbn1.path, tbn1.numchild, ("
+ "SELECT COUNT(1) "
+ "FROM %(table)s AS tbn2 "
+ "WHERE tbn2.path LIKE " +
+ sql_concat("tbn1.path", "%%s", vendor=vendor) + ") AS real_numchild "
+ "FROM %(table)s AS tbn1 "
+ "HAVING tbn1.numchild != real_numchild"
+ ) % {'table': connection.ops.quote_name(cls._meta.db_table)}
else:
subquery = "(SELECT COUNT(1) FROM %(table)s AS tbn2"\
- " WHERE tbn2.path LIKE tbn1.path||%%s)"
+ " WHERE tbn2.path LIKE " + sql_concat("tbn1.path", "%%s", vendor=vendor) + ")"
sql = ("SELECT tbn1.path, tbn1.numchild, " + subquery +
" FROM %(table)s AS tbn1 WHERE tbn1.numchild != " +
subquery)
@@ -838,6 +870,7 @@ class MP_Node(Node):
#~
cls = get_result_class(cls)
+ vendor = cls.get_database_vendor('write')
if parent:
depth = parent.depth + 1
@@ -848,19 +881,23 @@ class MP_Node(Node):
params = []
extrand = ''
- sql = 'SELECT * FROM %(table)s AS t1 INNER JOIN '\
- ' (SELECT '\
- ' SUBSTR(path, 1, %(subpathlen)s) AS subpath, '\
- ' COUNT(1)-1 AS count '\
- ' FROM %(table)s '\
- ' WHERE depth >= %(depth)s %(extrand)s'\
- ' GROUP BY subpath) AS t2 '\
- ' ON t1.path=t2.subpath '\
- ' ORDER BY t1.path' % {
- 'table': connection.ops.quote_name(cls._meta.db_table),
- 'subpathlen': depth * cls.steplen,
- 'depth': depth,
- 'extrand': extrand}
+ subpath = sql_substr("path", "1", "%(subpathlen)s", vendor=vendor)
+
+ sql = (
+ 'SELECT * FROM %(table)s AS t1 INNER JOIN '
+ ' (SELECT '
+ ' ' + subpath + ' AS subpath, '
+ ' COUNT(1)-1 AS count '
+ ' FROM %(table)s '
+ ' WHERE depth >= %(depth)s %(extrand)s'
+ ' GROUP BY '+ subpath + ') AS t2 '
+ ' ON t1.path=t2.subpath '
+ ' ORDER BY t1.path'
+ ) % {
+ 'table': connection.ops.quote_name(cls._meta.db_table),
+ 'subpathlen': depth * cls.steplen,
+ 'depth': depth,
+ 'extrand': extrand}
cursor = cls._get_database_cursor('write')
cursor.execute(sql, params)
diff --git a/treebeard/templates/admin/tree_change_list_results.html b/treebeard/templates/admin/tree_change_list_results.html
index 716e6db..4d7d7ae 100644
--- a/treebeard/templates/admin/tree_change_list_results.html
+++ b/treebeard/templates/admin/tree_change_list_results.html
@@ -4,35 +4,37 @@
</div>
{% endif %}
{% if results %}
- <table cellspacing="0" id="result_list">
- <thead>
- <tr>
- {% for header in result_headers %}
- <th{{ header.class_attrib }}>
- {% if header.sortable %}<a href="{{ header.url }}"
- {% if header.tooltip %}title="{{ header.tooltip }}"{% endif %}>{% endif %}
- {{ header.text|capfirst }}
- {% if header.sortable %}</a>{% endif %}</th>{% endfor %}
- </tr>
- </thead>
- <tbody>
- {% for node_id, parent_id, node_level, has_children, result in results %}
- <tr id="node-{{ node_id }}-id" class="{% cycle 'row1' 'row2' %}"
- level="{{ node_level }}" children-num="{{ children_num }}"
- parent="{{ parent_id }}" node="{{ node_id }}">
- {% for item in result %}
- {% if forloop.counter == 1 %}
- {% for spacer in item.depth %}<span class="grab">
- </span>{% endfor %}
- {% endif %}
- {{ item }}
- {% endfor %}</tr>
- {% endfor %}
- </tbody>
- </table>
- <input type="hidden" id="has-filters" value="{{ filtered|yesno:"1,0" }}"/>
- <script>
- var MOVE_NODE_ENDPOINT = 'move/';
- </script>
+ <div class="results">
+ <table cellspacing="0" id="result_list">
+ <thead>
+ <tr>
+ {% for header in result_headers %}
+ <th{{ header.class_attrib }}>
+ {% if header.sortable %}<a href="{{ header.url }}"
+ {% if header.tooltip %}title="{{ header.tooltip }}"{% endif %}>{% endif %}
+ {{ header.text|capfirst }}
+ {% if header.sortable %}</a>{% endif %}</th>{% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for node_id, parent_id, node_level, has_children, result in results %}
+ <tr id="node-{{ node_id }}-id" class="{% cycle 'row1' 'row2' %}"
+ level="{{ node_level }}" children-num="{{ children_num }}"
+ parent="{{ parent_id }}" node="{{ node_id }}">
+ {% for item in result %}
+ {% if forloop.counter == 1 %}
+ {% for spacer in item.depth %}<span class="grab">
+ </span>{% endfor %}
+ {% endif %}
+ {{ item }}
+ {% endfor %}</tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ <input type="hidden" id="has-filters" value="{{ filtered|yesno:"1,0" }}"/>
+ <script>
+ var MOVE_NODE_ENDPOINT = 'move/';
+ </script>
+ </div>
{% endif %}
diff --git a/treebeard/templates/admin/tree_list_results.html b/treebeard/templates/admin/tree_list_results.html
index 69099ee..a4fe2c2 100644
--- a/treebeard/templates/admin/tree_list_results.html
+++ b/treebeard/templates/admin/tree_list_results.html
@@ -1,4 +1,3 @@
-{% load cycle from future %}
{% if results %}
<ul>
{% for result in results %}
diff --git a/treebeard/tests/settings.py b/treebeard/tests/settings.py
index 876c735..9b26215 100644
--- a/treebeard/tests/settings.py
+++ b/treebeard/tests/settings.py
@@ -36,6 +36,19 @@ def get_db_conf():
'HOST': '127.0.0.1',
'PORT': '',
}
+ elif database_engine == "mssql":
+ return {
+ 'ENGINE': 'sql_server.pyodbc',
+ 'NAME': 'master',
+ 'USER': 'sa',
+ 'PASSWORD': 'Password12!',
+ 'HOST': '(local)\SQL2016',
+ 'PORT': '',
+ 'OPTIONS': {
+ 'driver': 'SQL Server Native Client 11.0',
+ 'MARS_Connection': 'True',
+ },
+ }
DATABASES = {'default': get_db_conf()}
SECRET_KEY = '7r33b34rd'
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django-treebeard.git
More information about the Python-modules-commits
mailing list