Metadata-Version: 1.1
Name: django-tools
Version: 0.32.12
Summary: miscellaneous tools for django
Home-page: http://github.com/jedie/django-tools/
Author: Jens Diemer
Author-email: django-tools@jensdiemer.de
License: UNKNOWN
Description: ============
        django-tools
        ============
        
        Miscellaneous tools for django.
        
        Look also at the siblings project: `django-cms-tools <https://github.com/jedie/django-cms-tools>`_ (Tools/helpers around Django-CMS).
        
        +-----------------------------------+--------------------------------------------------+
        | |Build Status on travis-ci.org|   | `travis-ci.org/jedie/django-tools`_              |
        +-----------------------------------+--------------------------------------------------+
        | |Coverage Status on coveralls.io| | `coveralls.io/r/jedie/django-tools`_             |
        +-----------------------------------+--------------------------------------------------+
        | |Status on landscape.io|          | `landscape.io/github/jedie/django-tools/master`_ |
        +-----------------------------------+--------------------------------------------------+
        
        .. |Build Status on travis-ci.org| image:: https://travis-ci.org/jedie/django-tools.svg
        .. _travis-ci.org/jedie/django-tools: https://travis-ci.org/jedie/django-tools/
        .. |Coverage Status on coveralls.io| image:: https://coveralls.io/repos/jedie/django-tools/badge.svg
        .. _coveralls.io/r/jedie/django-tools: https://coveralls.io/r/jedie/django-tools
        .. |Status on landscape.io| image:: https://landscape.io/github/jedie/django-tools/master/landscape.svg
        .. _landscape.io/github/jedie/django-tools/master: https://landscape.io/github/jedie/django-tools/master
        
        --------------
        existing stuff
        --------------
        
        django_tools.template.loader.DebugCacheLoader
        =============================================
        
        Insert template name as html comments, e.g.:
        
        ::
        
            <!-- START 'foo/bar.html' -->
            ...
            <!-- END 'foo/bar.html' -->
        
        To use this, you must add **django_tools.template.loader.DebugCacheLoader** as template loader.
        
        e.g.: Activate it only in DEBUG mode:
        
        ::
        
            if DEBUG:
                TEMPLATES[0]["OPTIONS"]["loaders"] = [
                    (
                        "django_tools.template.loader.DebugCacheLoader", (
                            'django.template.loaders.filesystem.Loader',
                            'django.template.loaders.app_directories.Loader',
                        )
                    )
                ]
        
        send text+html mails
        ====================
        
        A helper class to send text+html mails used the django template library.
        
        You need two template files, e.g.:
        
        * `mail_test.txt <https://github.com/jedie/django-tools/blob/master/django_tools_test_project/django_tools_test_app/templates/mail_test.txt>`_
        
        * `mail_test.html <https://github.com/jedie/django-tools/blob/master/django_tools_test_project/django_tools_test_app/templates/mail_test.html>`_
        
        You have to specify the template file like this: ``template_base="mail_test.{ext}"``
        
        Send via Celery task:
        
        ::
        
            # settings.py
            SEND_MAIL_CELERY_TASK_NAME="mail:send_task"
            
            from django_tools.mail.send_mail import SendMailCelery
            SendMailCelery(
                template_base="mail_test.{ext}",
                mail_context={"foo": "first", "bar": "second"},
                subject="Only a test",
                recipient_list="foo@bar.tld"
            ).send()
        
        Send without Celery:
        
        ::
        
            from django_tools.mail.send_mail import SendMail
            SendMail(
                template_base="mail_test.{ext}",
                mail_context={"foo": "first", "bar": "second"},
                subject="Only a test",
                recipient_list="foo@bar.tld"
            ).send()
        
        See also the existing unittests:
        
        * `django_tools_tests/test_email.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_email.py>`_
        
        Filemanager library
        ===================
        
        Library for building django application like filemanager, gallery etc.
        
        more info, read `./filemanager/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/filemanager/README.creole>`_
        
        per-site cache middleware
        =========================
        
        Similar to `django UpdateCacheMiddleware and FetchFromCacheMiddleware <https://docs.djangoproject.com/en/1.4/topics/cache/#the-per-site-cache>`_,
        but has some enhancements: `'per site cache' in ./cache/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/cache/README.creole#per-site-cache-middleware>`_
        
        smooth cache backends
        =====================
        
        Same as django cache backends, but adds ``cache.smooth_update()`` to clears the cache smoothly depend on the current system load.
        more info in: `'smooth cache backends' in ./cache/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/cache/README.creole#smooth-cache-backends>`_
        
        local sync cache
        ================
        
        Keep a local dict in a multi-threaded environment up-to-date. Usefull for cache dicts.
        More info, read DocString in `./local_sync_cache/local_sync_cache.py <https://github.com/jedie/django-tools/blob/master/django_tools/local_sync_cache/local_sync_cache.py>`_.
        
        threadlocals middleware
        =======================
        
        For getting request object anywhere, use `./middlewares/ThreadLocal.py <https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py>`_
        
        Dynamic SITE_ID middleware
        ==========================
        
        Set settings.SITE_ID dynamically with a middleware base on the current request domain name.
        Domain name alias can be specify as a simple string or as a regular expression.
        
        more info, read `./dynamic_site/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/dynamic_site/README.creole>`_.
        
        StackInfoStorage
        ================
        
        Message storage like LegacyFallbackStorage, except, every message would have a stack info, witch is helpful, for debugging.
        Stack info would only be added, if settings DEBUG or MESSAGE_DEBUG is on.
        To use it, put this into your settings:
        
        ::
        
            MESSAGE_STORAGE = "django_tools.utils.messages.StackInfoStorage"
        
        More info, read DocString in `./utils/messages.py <https://github.com/jedie/django-tools/blob/master/django_tools/utils/messages.py>`_.
        
        limit to usergroups
        ===================
        
        Limit something with only one field, by selecting:
        
        * anonymous users
        
        * staff users
        
        * superusers
        
        * ..all existing user groups..
        
        More info, read DocString in `./limit_to_usergroups.py <https://github.com/jedie/django-tools/blob/master/django_tools/limit_to_usergroups.py>`_
        
        permission helpers
        ==================
        
        See `django_tools.permissions <https://github.com/jedie/django-tools/blob/master/django_tools/permissions.py>`_
        and unittests: `django_tools_tests.test_permissions <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_permissions.py>`_
        
        form/model fields
        =================
        
        * `Directory field <https://github.com/jedie/django-tools/blob/master/django_tools/fields/directory.py>`_ - check if exist and if in a defined base path
        
        * `language code field with validator <https://github.com/jedie/django-tools/blob/master/django_tools/fields/language_code.py>`_
        
        * `Media Path field <https://github.com/jedie/django-tools/blob/master/django_tools/fields/media_path.py>`_ browse existign path to select and validate input
        
        * `sign seperated form/model field <https://github.com/jedie/django-tools/blob/master/django_tools/fields/sign_separated.py>`_ e.g. comma seperated field
        
        * `static path field <https://github.com/jedie/django-tools/blob/master/django_tools/fields/static_path.py>`_
        
        * `url field <https://github.com/jedie/django-tools/blob/master/django_tools/fields/url.py>`_ A flexible version of the original django form URLField
        
        -----------------
        unittests helpers
        -----------------
        
        Mockup utils
        ============
        
        Create dummy PIL/django-filer images with Text, see:
        
        * `/django_tools/unittest_utils/mockup.py <https://github.com/jedie/django-tools/blob/master/django_tools/unittest_utils/mockup.py>`_
        
        usage/tests:
        
        * `/django_tools_tests/test_mockup.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_mockup.py>`_
        
        create users
        ============
        
        `/unittest_utils/user.py <https://github.com/jedie/django-tools/blob/master/django_tools/unittest_utils/user.py>`_:
        
        * ``django_tools.unittest_utils.user.create_user()`` - create users, get_super_user
        
        * ``django_tools.unittest_utils.user.get_super_user()`` - get the first existing superuser
        
        BaseUnittestCase
        ================
        
        **django_tools.unittest_utils.unittest_base.BaseUnittestCase** contains some low-level assert methods:
        
        * assertEqual_dedent()
        
        * assert_is_dir(), assert_not_is_dir()
        
        * assert_is_file(), assert_not_is_File()
        
        *django_tools.unittest_utils.tempdir* contains **TempDir**, a Context Manager Class:
        
        ::
        
            with TempDir(prefix="foo_") as tempfolder:
                # create a file:
                open(os.path.join(tempfolder, "bar"), "w").close()
            
            # the created temp folder was deleted with shutil.rmtree()
        
        usage/tests:
        
        * `/django_tools_tests/test_unittest_utils.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_unittest_utils.py>`_
        
        DjangoCommandMixin
        ==================
        
        Helper to run shell commands. e.g.: "./manage.py cms check"
        
        usage/tests:
        
        * `/django_tools_tests/test_unittest_django_command.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_unittest_django_command.py>`_
        
        DOM compare in unittests
        ========================
        
        The Problem:
        You can’t easy check if e.g. some form input fields are in the response,
        because the form rendering use a dict for storing all html attributes.
        So, the ordering of form field attributes are not sorted and varied.
        
        The Solution:
        You need to parse the response content into a DOM tree and compare nodes.
        
        We add the great work of Gregor Müllegger at his GSoC 2011 form-rendering branch.
        You will have the following assert methods inherit from: django_tools.unittest_utils.unittest_base.BaseTestCase
        
        * self.assertHTMLEqual() – for compare two HTML DOM trees
        
        * self.assertDOM() – for check if nodes in response or not.
        
        * self.assertContains() – Check if ond node occurs 'count’ times in response
        
        More info and examples in `./django_tools_tests/test_dom_asserts.py <https://github.com/jedie/django-tools/blob/master/django_tools/django_tools_tests/test_dom_asserts.py>`_
        
        @set_string_if_invalid() decorator
        ==================================
        
        Helper to check if there are missing template tags by set temporary ``'string_if_invalid'``, see: `https://docs.djangoproject.com/en/1.8/ref/templates/api/#invalid-template-variables <https://docs.djangoproject.com/en/1.8/ref/templates/api/#invalid-template-variables>`_
        
        Usage, e.g.:
        
        ::
        
            from django.test import SimpleTestCase
            from django_tools.unittest_utils.template import TEMPLATE_INVALID_PREFIX, set_string_if_invalid
            
            @set_string_if_invalid()
            class TestMyTemplate(SimpleTestCase):
                def test_valid_tag(self):
                    response = self.client.get('/foo/bar/')
                    self.assertNotIn(TEMPLATE_INVALID_PREFIX, response.content)
        
        You can also decorate the test method ;)
        
        @task_always_eager() celery decorator
        =====================================
        
        Decorator activate celery:
        
        ::
        
            CELERY_ALWAYS_EAGER=True # executed locally instead of being sent to the queue
            CELERY_EAGER_PROPAGATES_EXCEPTIONS=True # raise exceptions on errors
        
        Is also set these two items in settings by using ``override_settings``
        See also: `http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-task_always_eager <http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-task_always_eager>`_
        
        Usage, e.g.:
        
        ::
        
            from django.core import mail
            from django.test import SimpleTestCase
            from django_tools.unittest_utils.celery import task_always_eager
            
            @task_always_eager()
            class TestMyCeleryJobs(SimpleTestCase):
                def test_send_mail(self):
                    response = self.client.get('/send_mail/foo/')
                    self.assertEqual(len(mail.outbox), 1)
        
        You can also decorate the test method ;)
        
        Speedup tests
        =============
        
        Speedup test run start by disable migrations, e.g.:
        
        ::
        
            from django_tools.unittest_utils.disable_migrations import DisableMigrations
            MIGRATION_MODULES = DisableMigrations()
        
        small tools
        ===========
        
        debug_csrf_failure()
        --------------------
        
        Display the normal debug page and not the minimal csrf debug page.
        More info in DocString here: `django_tools/views/csrf.py <https://github.com/jedie/django-tools/blob/master/django_tools/views/csrf.py>`_
        
        import lib helper
        -----------------
        
        additional helper to the existing ``importlib``
        more info in the sourcecode: `./utils/importlib.py <https://github.com/jedie/django-tools/blob/master/django_tools/utils/importlib.py>`_
        
        http utils
        ----------
        
        Pimped HttpRequest to get some more information about a request.
        More info in DocString here: `django_tools/utils/http.py <https://github.com/jedie/django-tools/blob/master/django_tools/utils/http.py>`_
        
        @display_admin_error
        --------------------
        
        Developer helper to display silent errors in ModelAdmin.list_display callables.
        See: **display_admin_error** in `decorators.py <https://github.com/jedie/django-tools/blob/master/django_tools/decorators.py>`_
        
        upgrade virtualenv
        ==================
        
        A simple commandline script that calls ``pip install —-upgrade XY`` for every package thats installed in a virtualenv.
        Simply copy/symlink it into the root directory of your virtualenv and start it.
        
        **Note:** `Seems that this solution can't observe editables right. <https://github.com/pypa/pip/issues/319>`_
        
        To use it, without installing django-tools:
        
        ::
        
            ~/$ cd goto/your_env
            .../your_env/$ wget https://github.com/jedie/django-tools/raw/master/django_tools/upgrade_virtualenv.py
            .../your_env/$ chmod +x upgrade_virtualenv.py
            .../your_env/$ ./upgrade_virtualenv.py
        
        This script will be obsolete, if `pip has a own upgrade command <https://github.com/pypa/pip/issues/59>`_.
        
        django_tools.utils.url.GetDict
        ==============================
        
        Similar to origin django.http.QueryDict but:
        
        * urlencode() doesn't add "=" to empty values: "?empty" instead of "?empty="
        
        * always mutable
        
        * output will be sorted (easier for tests ;)
        
        More info, see tests: `django_tools_tests/test_utils_url.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_utils_url.py>`_
        
        SignedCookieStorage
        -------------------
        
        Store information in signed Cookies, use **django.core.signing**.
        So the cookie data can't be manipulated from the client.
        Sources/examples:
        
        * `/django_tools/utils/client_storage.py <https://github.com/jedie/django-tools/blob/master/django_tools/utils/client_storage.py>`_
        
        * `/django_tools_tests/test_signed_cookie.py <https://github.com/jedie/django-tools/blob/master/django_tools_tests/test_signed_cookie.py>`_
        
        Print SQL Queries
        =================
        
        Print the used SQL queries via context manager.
        
        usage e.g.:
        
        ::
        
            from django_tools.unittest_utils.print_sql import PrintQueries
            
            # e.g. use in unittests:
            class MyTests(TestCase):
                def test_foobar(self):
                    with PrintQueries("Create object"):
                        FooBar.objects.create("name"=foo)
            
            # e.g. use in views:
            def my_view(request):
                with PrintQueries("Create object"):
                    FooBar.objects.create("name"=foo)
        
        the output is like:
        
        ::
        
            _______________________________________________________________________________
             *** Create object ***
            1 - INSERT INTO "foobar" ("name")
                VALUES (foo)
            -------------------------------------------------------------------------------
        
        SetRequestDebugMiddleware
        =========================
        
        middleware to add debug bool attribute to request object.
        More info: `./debug/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/debug/README.creole>`_
        
        TracebackLogMiddleware
        ======================
        
        Put traceback in log by call `logging.exception() <https://docs.python.org/3/library/logging.html#logging.Logger.exception>`_ on ``process_exception()``
        Activate with:
        
        ::
        
            MIDDLEWARE_CLASSES = (
                ...
                'django_tools.middlewares.TracebackLogMiddleware.TracebackLogMiddleware',
                ...
            )
        
        InternalIps() - Unix shell-style wildcards in INTERNAL_IPS
        ==========================================================
        
        settings.py e.g.:
        
        ::
        
            from django_tools.settings_utils import InternalIps
            
            INTERNAL_IPS = InternalIps(["127.0.0.1", "::1", "192.168.*.*", "10.0.*.*"])
        
        StdoutStderrBuffer()
        ====================
        
        redirect stdout + stderr to a string buffer. e.g.:
        
        ::
        
            from django_tools.unittest_utils.stdout_redirect import StdoutStderrBuffer
            
            with StdoutStderrBuffer() as buffer:
                print("foo")
            output = buffer.get_output() # contains "foo\n"
        
        Management commands
        ===================
        
        nice_diffsettings
        -----------------
        
        Similar to django 'diffsettings', but used pretty-printed representation.
        
        To use it, add ``'django_tools.manage_commands.django_tools_nice_diffsettings'`` to your INSTALLED_APPS and call:
        
        ::
        
            $ ./manage.py nice_diffsettings
        
        list_models
        -----------
        
        Just list all existing models in app_label.ModelName format. Useful to use this in 'dumpdata' etc.
        
        To use it, add ``'django_tools.manage_commands.django_tools_list_models'`` to your INSTALLED_APPS and call:
        
        ::
        
            $ ./manage.py list_models
        
        ..all others…
        =============
        
        There exist many miscellaneous stuff. Look in the source, luke!
        
        ------------------------------
        running django-tools unittests
        ------------------------------
        
        Run all tests in all environment combinations:
        
        ::
        
            .../django-tools $ tox
        
        Run all tests in current environment:
        
        ::
        
            .../django-tools $ pytest
        
        Run specific tests, e.g.:
        
        ::
        
            .../django-tools $ pytest django_tools_tests/test_unittest_utils.py
        
        ------------------------------
        Backwards-incompatible changes
        ------------------------------
        
        -----
        v0.32
        -----
        
        remove outdated stuff:
        
        * django-tagging addon
        
        * upgrade_virtualenv.py (Alternative: `update_virtualenv_git_repos.py <https://github.com/jedie/python-code-snippets/blob/master/CodeSnippets/update_virtualenv_git_repos.py>`_)
        
        * utils.http
        
        -----
        v0.29
        -----
        
        **ClientCookieStorage** was renamed to **SignedCookieStorage**
        import e.g.:
        
        ::
        
            from django_tools.utils.client_storage import SignedCookieStorage
        
        -------
        v0.25.0
        -------
        
        SmoothCacheBackends API changed:
        The **cache.clear()** method will really clear the cache, as the origin backend API.
        You must call ``cache.smooth_update()`` to set the "last change" timestamp.
        
        v0.24.10
        ========
        
        AutoUpdateFileBasedCache is deprecated, use new SmoothCacheBackends.
        
        v0.9
        ====
        
        Language code field and SelectMediaPath are renamed.
        
        change:
        **from django_tools.fields import LanguageCodeFormField**
        to:
        **from django_tools.fields.language_code import LanguageCodeFormField**
        
        change and rename:
        **from django_tools.fields import LanguageCodeField**
        to:
        **from django_tools.fields.language_code import LanguageCodeModelField**
        
        change and rename:
        **from django_tools.widgets import SelectMediaPath**
        to:
        **from django_tools.fields.media_path import MediaPathWidget**
        
        --------------------
        Django compatibility
        --------------------
        
        +--------------+----------------+---------------+
        | django-tools | django version | python        |
        +==============+================+===============+
        | >= v0.30.1   | 1.8, 1.9, 1.10 | 2.7, 3.4, 3.5 |
        +--------------+----------------+---------------+
        | v0.30        | 1.8, 1.9       | 2.7, 3.4      |
        +--------------+----------------+---------------+
        | v0.29        | 1.6 - 1.8      | 2.7, 3.4      |
        +--------------+----------------+---------------+
        | v0.26        | <=1.6          |               |
        +--------------+----------------+---------------+
        | v0.25        | <=1.4          |               |
        +--------------+----------------+---------------+
        
        (since v0.29 the given version combination will be tested via travis-ci)
        
        -------
        history
        -------
        
        * v0.32.12 - 04.05.2017 - `compare v0.32.11...v0.32.12 <https://github.com/jedie/django-tools/compare/v0.32.11...v0.32.12>`_ 
        
            * NEW: ``self.assertIn_dedent()`` in ``django_tools.unittest_utils.unittest_base.BaseUnittestCase``
        
        * v0.32.11 - 02.05.2017 - `compare v0.32.10...v0.32.11 <https://github.com/jedie/django-tools/compare/v0.32.10...v0.32.11>`_ 
        
            * Fix PyPi package mistake (``.tar.gz`` archive contains ``.tox`` ;)
        
        * v0.32.10 - 02.05.2017 - `compare v0.32.9...v0.32.10 <https://github.com/jedie/django-tools/compare/v0.32.9...v0.32.10>`_ 
        
            * NEW: ``django_tools.mail`` to send text+html mails (see above)
        
        * v0.32.9 - 21.03.2017 - `compare v0.32.8...v0.32.9 <https://github.com/jedie/django-tools/compare/v0.32.8...v0.32.9>`_ 
        
            * Bugfix ``DebugCacheLoader`` if TemplateDoesNotExist was raised
        
        * v0.32.8 - 16.03.2017 - `compare v0.32.7...v0.32.8 <https://github.com/jedie/django-tools/compare/v0.32.7...v0.32.8>`_ 
        
            * NEW: ``django_tools.template.loader.DebugCacheLoader`` to add template name as html comments
        
            * Change temp filename in BrowserDebug and use ``django_tools_browserdebug_`` prefix
        
            * Bugfix in ``django_tools.middlewares.ThreadLocal.ThreadLocalMiddleware``
        
        * v0.32.7 - 10.03.2017 - `compare v0.32.6...v0.32.7 <https://github.com/jedie/django-tools/compare/v0.32.6...v0.32.7>`_ 
        
            * NEW: ``django_tools.permissions`` - helper for setup permissions
        
            * NEW: ``/unittest_utils/user.py`` - helper for creating users (needfull in unittests)
        
        * v0.32.6 - 22.02.2017 - `compare v0.32.5...v0.32.6 <https://github.com/jedie/django-tools/compare/v0.32.5...v0.32.6>`_
        
        * ``@task_always_eager()`` decorator will set ``CELERY_EAGER_PROPAGATES_EXCEPTIONS=True``, too.
        
        * v0.32.5 - 10.02.2017 - `compare v0.32.4...v0.32.5 <https://github.com/jedie/django-tools/compare/v0.32.4...v0.32.5>`_ 
        
            * NEW: Add ``template_name`` (optional) to ``self.assertResponse()`` (check with ``assertTemplateUsed()``)
        
        * v0.32.4 - 01.02.2017 - `compare v0.32.3...v0.32.4 <https://github.com/jedie/django-tools/compare/v0.32.3...v0.32.4>`_
        
        * Fix: Set "is_active" for created test users
        
        * v0.32.3 - 25.01.2017 - `compare v0.32.2...v0.32.3 <https://github.com/jedie/django-tools/compare/v0.32.2...v0.32.3>`_ 
        
            * Fix UnicodeDecodeError in BrowserDebug
        
            * NEW: ``@set_string_if_invalid()`` decorator
        
            * NEW: ``@task_always_eager()`` decorator
        
        * v0.32.2 - 13.01.2017 - `compare v0.32.1...v0.32.2 <https://github.com/jedie/django-tools/compare/v0.32.1...v0.32.2>`_ 
        
            * NEW: django_tools.utils.url.GetDict
        
        * v0.32.1 - 29.12.2016 - `compare v0.32.0...v0.32.1 <https://github.com/jedie/django-tools/compare/v0.32.0...v0.32.1>`_ 
        
            * NEW: TracebackLogMiddleware
        
        * v0.32.0 - 19.12.2016 - `compare v0.31.0...v0.32.0 <https://github.com/jedie/django-tools/compare/v0.31.0...v0.32.0>`_ 
        
            * NEW: Management commands: 'nice_diffsettings', 'list_models'
        
            * NEW: @display_admin_error to display silent errors in ModelAdmin.list_display callables.
        
            * NEW: django_tools.template.render.render_template_file
        
            * use `pytest-django <https://pypi.python.org/pypi/pytest-django>`_
        
            * remove outdated stuff: See 'Backwards-incompatible changes' above.
        
        * v0.31.0 - 03.11.2016 - `compare v0.30.4...v0.31.0 <https://github.com/jedie/django-tools/compare/v0.30.4...v0.31.0>`_ 
        
            * add Mockup utils to create dummy PIL/django-filer images with Text (see above)
        
            * move tests into ``/django_tools_tests/``
        
        * v0.30.4 - 27.10.2016 - `compare v0.30.2...v0.30.4 <https://github.com/jedie/django-tools/compare/v0.30.2...v0.30.4>`_ 
        
            * add DjangoCommandMixin
        
        * v0.30.2 - 05.10.2016 - `compare v0.30.1...v0.30.2 <https://github.com/jedie/django-tools/compare/v0.30.1...v0.30.2>`_ 
        
            * Bugfix Python 2 compatibility
        
        * v0.30.1 - 26.08.2016 - `compare v0.30.0...v0.30.1 <https://github.com/jedie/django-tools/compare/v0.30.0...v0.30.1>`_ 
        
            * add: ``django_tools.unittest_utils.disable_migrations.DisableMigrations`` (see above)
        
            * run tests also with django v1.10 and Python 3.5
        
            * use tox
        
        * v0.30.0 - 27.04.2016 - `compare v0.29.5...v0.30.0 <https://github.com/jedie/django-tools/compare/v0.29.5...v0.30.0>`_ 
        
            * Django 1.9 and Python 3 support contributed by `naegelyd <https://github.com/jedie/django-tools/pull/9>`_
        
        * v0.29.4 and v0.29.5 - 10.08.2015 - `compare v0.29.3...v0.29.5 <https://github.com/jedie/django-tools/compare/v0.29.3...v0.29.5>`_ 
        
            * Some bugfixes for django 1.6 support
        
        * v0.29.3 - 10.08.2015 - `compare v0.29.2...v0.29.3 <https://github.com/jedie/django-tools/compare/v0.29.2...v0.29.3>`_ 
        
            * Clear ThreadLocal request atttribute after response is processed (contributed by Lucas Wiman)
        
        * v0.29.2 - 19.06.2015 - `compare v0.29.1...v0.29.2 <https://github.com/jedie/django-tools/compare/v0.29.1...v0.29.2>`_ 
        
            * Bugfix in unittest_utils.selenium_utils.selenium2fakes_response
        
            * assertResponse used assertContains from django
        
            * Add QueryLogMiddleware (TODO: add tests)
        
        * v0.29.1 - 17.06.2015 - `compare v0.29.0...v0.29.1 <https://github.com/jedie/django-tools/compare/v0.29.0...v0.29.1>`_ 
        
            * Bugfixes for Py2 and Py3
        
            * add StdoutStderrBuffer()
        
        * v0.29.0 - 09.06.2015 - `compare v0.26.0...v0.29.0 <https://github.com/jedie/django-tools/compare/v0.26.0...v0.29.0>`_ 
        
            * WIP: Refactor unittests (DocTests must be updated for Py3 and more unittests must be written to cover all)
        
            * catch more directory traversal attacks in BaseFilesystemBrowser (and merge code parts)
        
            * Bugfix for "django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet." if using **UpdateInfoBaseModel**
        
            * Bugfixes in **dynamic_site** for django 1.7
        
            * add: `django_tools.settings_utils.InternalIps <https://github.com/jedie/django-tools/blob/master/django_tools/settings_utils.py>`_
        
        * v0.28.0 - 12.02.2015 - `compare v0.26.0...v0.28.0 <https://github.com/jedie/django-tools/compare/v0.26.0...v0.28.0>`_ 
        
            * Work-a-round for import loops
        
            * (new Version number, because of PyPi stress)
        
        * v0.26.0 - 11.02.2015 - `compare v0.25.1...v0.26.0 <https://github.com/jedie/django-tools/compare/v0.25.1...v0.26.0>`_ 
        
            * Updates for Django 1.6 and Python 3
        
        * v0.25.1 - 18.11.2013
        
            * Bugfix: Fall back to "UTF-8" if server send no encoding info
        
        * v0.25.0 - 28.08.2012
        
            * Rename **cache.clear()** in SmoothCacheBackends to **cache.smooth_update()**, so that reset timestamp is independ from clear the cache.
        
        * v0.24.10 - 24.08.2012
        
            * Add **SmoothCacheBackends**: `./cache/README.creole <https://github.com/jedie/django-tools/blob/master/django_tools/cache/README.creole>`_
        
        * v0.24.9 - 24.08.2012
        
            * Bugfix in per-site cache middleware: set inital count values to None, if counting is disabled.
        
        * v0.24.8 - 24.08.2012
        
            * Enhanced **per-site cache middleware**: `./cache/README.creole`_
        
            * Add **SetRequestDebugMiddleware**: `./debug/README.creole`_
        
        * v0.24.7 - 21.08.2012
        
            * Add the **per-site cache middleware** (see above)
        
            * Add **import lib helper**: `./utils/importlib.py`_
        
        * v0.24.6 - 21.08.2012
        
            * Add the **filemanager library** (see above)
        
        * v0.24.5 - 06.08.2012
        
            * Add **Print SQL Queries** context manager. (see above)
        
        * v0.24.4 - 26.07.2012
        
            * remove date from version string, cause of side-effects e.g.: user clone the repo and has the filter not installed
        
        * v0.24.3 - 25.07.2012
        
            * "Hardcode" the version string date attachment via `gitattribute filter script <https://github.com/jedie/python-code-snippets/tree/master/CodeSnippets/git>`_ to fix `a reported issues <https://github.com/jedie/django-tools/issues/1>`_ with `pip requirements file bug <https://github.com/pypa/pip/issues/145>`_.
        
        * v0.24.2 - 10.07.2012
        
            * Split `UpdateInfoBaseModel() <https://github.com/jedie/django-tools/blob/master/django_tools/models.py>`_: So you can only set "createtime", "lastupdatetime" or "createby", "lastupdateby" or both types (This is backwards compatible)
        
        * v0.24.1 - 12.06.2012
        
            * Bugfix: UsergroupsModelField() and add unittests for it
        
            * Add "normal users" in UsergroupsModelField()
        
            * New: Add create_user() and create_testusers() to BaseTestCase
        
            * Add a test project for the unittests. TODO: use this for all tests
        
        * v0.24.0 - 04.06.2012
        
            * `Don't use auto_now_add and auto_now in UpdateInfoBaseModel <https://github.com/jedie/django-tools/commit/a3cf1f7b2e9dbe4964306f4793c74f1782f8b2ea>`_
        
            * Bugfix in `UsergroupsModelField <https://github.com/jedie/django-tools/blob/master/django_tools/limit_to_usergroups.py>`_
        
        * v0.23.1
        
            * `Dynamic Site <https://github.com/jedie/django-tools/tree/master/django_tools/dynamic_site#dynamic-site-id>`_ would be only initialised if settings.USE_DYNAMIC_SITE_MIDDLEWARE = True
        
        * v0.23.0
        
            * Use cryptographic signing tools from django 1.4 in django_tools.utils.client_storage
        
        * v0.22.0
        
            * Add `static_path.py <https://github.com/jedie/django-tools/blob/master/django_tools/fields/static_path.py>`_ thats used settings.STATIC_ROOT.
        
            * The old `media_path.py <https://github.com/jedie/django-tools/blob/master/django_tools/fields/media_path.py>`_ which used settings.MEDIA_ROOT is deprecated and will be removed in the future.
        
            * auto_add_check_unique_together() can use settings.DATABASES["default"]["ENGINE"], too.
        
        * v0.21.1
        
            * Bugfixes in `Dynamic Site`_.
        
        * v0.21.0beta
        
            * New: site alias function
        
            * refractory 'DynamicSiteMiddleware' to a own app (**Backwards-incompatible change:** change your settings if you use the old DynamicSiteMiddleware.)
        
        * v0.20.1
        
            * New: `debug_csrf_failure() <https://github.com/jedie/django-tools/blob/master/django_tools/views/csrf.py>`_ to display the normal debug page and not the minimal csrf debug page.
        
        * v0.20.0
        
            * Add experimental `DynamicSiteMiddleware <https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/DynamicSite.py>`_, please test it and give feedback.
        
        * v0.19.6
        
            * Add some south introspection rules for LanguageCodeModelField and jQueryTagModelField
        
            * fallback if message for anonymous user can't created, because django.contrib.messages middleware not used.
        
            * Bugfix in django_tools.utils.messages.StackInfoStorage
        
        * v0.19.5
        
            * Add `http://bugs.python.org/file22767/hp_fix.diff <http://bugs.python.org/file22767/hp_fix.diff>`_ for `https://github.com/gregmuellegger/django/issues/1 <https://github.com/gregmuellegger/django/issues/1>`_
        
        * v0.19.4
        
            * Bugfix for PyPy in local_sync_cache get_cache_information(): sys.getsizeof() not implemented on PyPy
        
            * Bugfix in template.filters.chmod_symbol()
        
            * Nicer solution for template.filters.human_duration()
        
        * v0.19.3
        
            * Add support for https in utils/http.py
        
        * v0.19.2
        
            * Bugfix in utils/http.py timeout work-a-round
        
        * v0.19.1
        
            * utils/http.py changes:
        
                * Use a better solution, see:
        
                * Add timeout and add a work-a-round for Python < 2.6
        
        * v0.19.0
        
            * NEW: Add utils/http.py with helpers to get a webpage via http GET in unicode
        
            * Change README from textile to creole ;)
        
        * v0.18.2
        
            * Bugfix: Add missing template in pypi package
        
        * v0.18.0
        
            * NEW: Add DOM compare from Gregor Müllegger GSoC work into unittest utils.
        
        * v0.17.1
        
            * Bugfix in “limit_to_usergroups”: Make choices “lazy”: Don’t access the database in *init*
        
        * v0.17
        
            * Add the script “upgrade_virtualenv.py”
        
            * Add “limit_to_usergroups”
        
            * Add “local sync cache”
        
            * Add models.UpdateInfoBaseModel
        
            * Update decorators.render_to
        
            * render_to pass keyword arguments to render_to_response() (e.g.: mimetype=“text/plain”)
        
            * new argument “skip_fail” in get_filtered_apps(): If True: raise excaption if app is not importable
        
        * v0.16.4
        
            * Bugfix: ``get_db_prep_save() got an unexpected keyword argument 'connection’`` when save a SignSeparatedModelField()
        
        * v0.16.3
        
            * Update BrowserDebug: Use response.templates instead of response.template and make output nicer
        
        * v0.16.2
        
            * Merge stack info code and display better stack info on browser debug page
        
        * v0.16.1
        
            * Update django_tools.utils.messages.StackInfoStorage for django code changes.
        
        * v0.16.0
        
            * NEW: path model field (check if direcotry exist)
        
        * v0.15.0
        
            * NEW: Add a flexible URL field (own validator, model- and form-field)
        
        * v0.14.1
        
            * Bugfix: make path in MediaPathModelField relativ (remove slashes)
        
        * v0.14
        
            * NEW: django-tagging addon: Display existing tags under a tag field
        
        * v0.13
        
            * Bugfix UnicodeEncodeError in Browser debug
        
        * v0.12
        
            * NEW: django_tools.utils.messages.failsafe_message
        
        * v0.11
        
            * NEW: Store data in a secure cookie, see: utils/client_storage.py
        
        * v0.10.1
        
            * New: Display used templates in unittest BrowserDebug
        
            * Bugfix: catch if last usermessages exist
        
        * v0.10.0
        
            * NEW: utils around django messages, see: /django_tools/utils/messages.py
        
        * v0.9.1
        
            * Bugfix: database column was not created: don’t overwrite get_internal_type()
        
        * v0.9
        
            * New: stuff in /django_tools/fields/
        
            * see also backwards-incompatible changes, above!
        
        * v0.8.2
        
            * New: widgets.SelectMediaPath(): Select a sub directory in settings.MEDIA_ROOT
        
            * New: fields.SignSeparatedField()
        
        * v0.8.1
        
            * Add “no_args” keyword argument to installed_apps_utils.get_filtered_apps()
        
        * v0.8.0
        
            * Add model LanguageCode field and form LanguageCode field in Accept-Language header format (RFC 2616)
        
        * v0.7.0
        
            * Add decorators.py
        
        * v0.6.0
        
            * Add forms_utils.LimitManyToManyFields, crosspost: `http://www.djangosnippets.org/snippets/1691/ <http://www.djangosnippets.org/snippets/1691/>`_
        
        * v0.5.0
        
            * Add template/filters.py from PyLucid v0.8.x
        
        * v0.4.0
        
            * Add experimental “warn_invalid_template_vars”
        
        * v0.3.1
        
            * Bugfix: Exclude the instance if it was saved in the past.
        
        * v0.3.0
        
            * Add utils.installed_apps_utils
        
        * v0.2.0
        
            * Add models_utils, see: `http://www.jensdiemer.de/_command/118/blog/detail/67/ <http://www.jensdiemer.de/_command/118/blog/detail/67/>`_ (de)
        
        * v0.1.0
        
            * first version cut out from PyLucid CMS – `http://www.pylucid.org <http://www.pylucid.org>`_
        
        -----
        links
        -----
        
        +----------+----------------------------------------------+
        | Homepage | `http://github.com/jedie/django-tools`_      |
        +----------+----------------------------------------------+
        | PyPi     | `http://pypi.python.org/pypi/django-tools/`_ |
        +----------+----------------------------------------------+
        
        .. _http://github.com/jedie/django-tools: http://github.com/jedie/django-tools
        .. _http://pypi.python.org/pypi/django-tools/: http://pypi.python.org/pypi/django-tools/
        
        --------
        donation
        --------
        
        * `paypal.me/JensDiemer <https://www.paypal.me/JensDiemer>`_
        
        * `Flattr This! <https://flattr.com/submit/auto?uid=jedie&url=https%3A%2F%2Fgithub.com%2Fjedie%2Fdjango-tools%2F>`_
        
        * Send `Bitcoins <http://www.bitcoin.org/>`_ to `1823RZ5Md1Q2X5aSXRC5LRPcYdveCiVX6F <https://blockexplorer.com/address/1823RZ5Md1Q2X5aSXRC5LRPcYdveCiVX6F>`_
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Programming Language :: Python
Classifier: Framework :: Django
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Documentation
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
