Package: django-tools
Miscellaneous tools for django.Look also at the siblings project:django-cms-tools(Tools/helpers around Django-CMS).||https://pypi.python.org/pypi/django-tools/|
||github.com/jedie/django-tools/actions|
||codecov.io/gh/jedie/django-tools|
||coveralls.io/r/jedie/django-tools|(Logo contributed by@reallinfosee#16)try-oute.g.:~$ git clone https://github.com/jedie/django-tools.git
~$ cd django-tools/
~/django-tools$ make install
~/django-tools$ make
help                       List all commands
install-poetry             install or update poetry
install                    install django-tools via poetry
update                     update the sources and installation
lint                       Run code formatters and linter
fix-code-style             Fix code formatting
tox-listenvs               List all tox test environments
tox                        Run pytest via tox with all environments
tox-py37                   Run pytest via tox with *python v3.7*
tox-py38                   Run pytest via tox with *python v3.8*
tox-py39                   Run pytest via tox with *python v3.9*
pytest                     Run pytest
update-test-snapshot-files Update all snapshot files (by remove and recreate all snapshot files)
publish                    Release new version to PyPi
start-dev-server           Start Django dev. server with the test project
playwright-install         Install test browser for Playwright tests
playwright-inspector       Run Playwright inspector
playwright-tests           Run only the Playwright tests
safety                     Run https://github.com/pyupio/safetyexisting stuffServe User Media FileServesettings.MEDIA_ROOTfiles only for allowed users.See separate README here:django_tools/serve_media_appMode Version ProtectProtect a model against overwriting a newer entry with an older one, by adding a auto increment version number.See separate README here:django_tools/model_version_protectOverwriteFileSystemStorageA django filesystem storage that will overwrite existing files and can create backups, if content changed.
usage:class ExampleModel(models.Model):
    foo_file = models.FileField(
        storage=OverwriteFileSystemStorage(create_backups=True)
    )
    bar_image = models.ImageField(
        storage=OverwriteFileSystemStorage(create_backups=False)
    )Backup made by appending a suffix and sequential number, e.g.:source....: foo.barbackup 1..: foo.bar.bakbackup 2..: foo.bar.bak0backup 3..: foo.bar.bak1Backup files are only made if file content changed. But at least one time!Django Logging utilsPut this into your settings, e.g.:from django_tools.unittest_utils.logging_utils import CutPathnameLogRecordFactory, FilterAndLogWarnings

# Filter warnings and pipe them to logging system
# Warnings of external packages are displayed only once and only the file path.
warnings.showwarning = FilterAndLogWarnings()

# Adds 'cut_path' attribute on log record. So '%(cut_path)s' can be used in log formatter.
logging.setLogRecordFactory(CutPathnameLogRecordFactory(max_length=50))

LOGGING = {
    # ...
    'formatters': {
        'verbose': {
            'format': '%(levelname)8s %(cut_path)s:%(lineno)-3s %(message)s'
        },
    },
    # ...
}(Activate warnings by, e.g.:export PYTHONWARNINGS=all)ThrottledAdminEmailHandlerThrottledAdminEmailHandlerworks similar as the origindjango.utils.log.AdminEmailHandlerbut is will throttle the number of mails that can be send in a time range.
usage e.g.:LOGGING = {
    # ...
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "class": "django_tools.log_utils.throttle_admin_email_handler.ThrottledAdminEmailHandler",
            "formatter": "email",
            "min_delay_sec": 20, # << -- skip mails in this time range
        },
        # ...
    },
    # ...
}django_tools.template.loader.DebugCacheLoaderInsert template name as html comments, e.g.:<!-- START 'foo/bar.html' -->
...
<!-- END 'foo/bar.html' -->To use this, you must adddjango_tools.template.loader.DebugCacheLoaderas 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 mailsA helper class to send text+html mails used the django template library.You need two template files, e.g.:mail_test.txtmail_test.htmlYou 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.pyDelay toolsSometimes you want to simulate when processing takes a little longer.
There existsdjango_tools.debug.delay.SessionDelayanddjango_tools.debug.delay.CacheDelayfor this.
The usage will create logging entries and user messages, if user is authenticated.More info in seperatedjango_tools/debug/README.creolefile.Filemanager libraryLibrary for building django application like filemanager, gallery etc.more info, read./filemanager/README.creoleper-site cache middlewareSimilar todjango UpdateCacheMiddleware and FetchFromCacheMiddleware,
but has some enhancements:'per site cache' in ./cache/README.creolesmooth cache backendsSame as django cache backends, but addscache.smooth_update()to clears the cache smoothly depend on the current system load.
more info in:'smooth cache backends' in ./cache/README.creolelocal sync cacheKeep 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.threadlocals middlewareFor getting request object anywhere, use./middlewares/ThreadLocal.pyDynamic SITE_ID middlewareNote: Currently not maintained! TODO: Fix unittests for all python/django versionSet 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.StackInfoStorageMessage 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.limit to usergroupsLimit something with only one field, by selecting:anonymous usersstaff userssuperusers..all existing user groups..More info, read DocString in./limit_to_usergroups.pypermission helpersSeedjango_tools.permissionsand unittests:django_tools_tests.test_permissionsform/model fieldsDirectory field- check if exist and if in a defined base pathlanguage code field with validatorMedia Path fieldbrowse existign path to select and validate inputsign seperated form/model fielde.g. comma seperated fieldstatic path fieldurl fieldA flexible version of the original django form URLFieldunittests helpersSelenium Test CasesThere are Firefox and Chromium test cases, with and without django StaticLiveServerTestCase!Chromium + StaticLiveServer example:from django_tools.selenium.chromedriver import chromium_available
from django_tools.selenium.django import SeleniumChromiumStaticLiveServerTestCase

@unittest.skipUnless(chromium_available(), "Skip because Chromium is not available!")
class ExampleChromiumTests(SeleniumChromiumStaticLiveServerTestCase):
    def test_admin_login_page(self):
        self.driver.get(self.live_server_url + "/admin/login/")
        self.assert_equal_page_title("Log in | Django site admin")
        self.assert_in_page_source('<form action="/admin/login/" method="post" id="login-form">')
        self.assert_no_javascript_alert()Firefox + StaticLiveServer example:from django_tools.selenium.django import SeleniumFirefoxStaticLiveServerTestCase
from django_tools.selenium.geckodriver import firefox_available

@unittest.skipUnless(firefox_available(), "Skip because Firefox is not available!")
class ExampleFirefoxTests(SeleniumFirefoxStaticLiveServerTestCase):
    def test_admin_login_page(self):
        self.driver.get(self.live_server_url + "/admin/login/")
        self.assert_equal_page_title("Log in | Django site admin")
        self.assert_in_page_source('<form action="/admin/login/" method="post" id="login-form">')
        self.assert_no_javascript_alert()Test cases without StaticLiveServer:from django_tools.selenium.chromedriver import SeleniumChromiumTestCase
from django_tools.selenium.geckodriver import SeleniumFirefoxTestCaseSee also existing unitests here:/django_tools/django_tools_tests/test_unittest_selenium.pySetup Web DriversSelenium test cases needs the browser and the web driver.SeleniumChromiumTestCaseandSeleniumFirefoxTestCasewill automaticly install the web driver viawebdriver-managerThere is a small CLI (calleddjango_tools_selenium) to check / install the web drivers, e.g.:~/django-tools$ poetry run django_tools_selenium install
~/django-tools$ poetry run django_tools_selenium infoMockup utilsCreate dummy PIL/django-filer images with Text, see:/django_tools/unittest_utils/mockup.pyusage/tests:/django_tools_tests/test_mockup.pyModel instance unittest code generatorGenerate unittest code skeletons from existing model instance. You can use this feature as django manage command or as admin action.Usage as management command, e.g.:$ ./manage.py generate_model_test_code auth.
...
#
# pk:1 from auth.User <class 'django.contrib.auth.models.User'>
#
user = User.objects.create(
    password='pbkdf2_sha256$36000$ybRfVQDOPQ9F$jwmgc5UsqRQSXxJs/NrZeTLguieUSSZfaSZbMmC+L5w=', # CharField, String (up to 128)
    last_login=datetime.datetime(2018, 4, 24, 8, 27, 49, 578107, tzinfo=<UTC>), # DateTimeField, Date (with time)
    is_superuser=True, # BooleanField, Boolean (Either True or False)
    username='test', # CharField, String (up to 150)
    first_name='', # CharField, String (up to 30)
    last_name='', # CharField, String (up to 30)
    email='', # CharField, Email address
    is_staff=True, # BooleanField, Boolean (Either True or False)
    is_active=True, # BooleanField, Boolean (Either True or False)
    date_joined=datetime.datetime(2018, 3, 6, 17, 15, 50, 93136, tzinfo=<UTC>), # DateTimeField, Date (with time)
)
...create users/unittest_utils/user.py:django_tools.unittest_utils.user.create_user()- create users, get_super_userdjango_tools.unittest_utils.user.get_super_user()- get the first existing superuserIsolated Filesystem decorator / context managerdjango_tools.unittest_utils.isolated_filesystem.isolated_filesystemacts as either a decorator or a context manager.
Useful to for tests that will create files/directories in current work dir, it does this:create a new temp directorychange the current working directory to the temp directoryafter exit:Delete an entire temp directory treeusage e.g.:from django_tools.unittest_utils.isolated_filesystem import isolated_filesystem

with isolated_filesystem(prefix="temp_dir_prefix"):
    open("foo.txt", "w").write("bar")BaseUnittestCasedjango_tools.unittest_utils.unittest_base.BaseUnittestCasecontains some low-level assert methods:assertEqual_dedent()Note: assert methods will be migrated to:django_tools.unittest_utils.assertmentsin the future!django_tools.unittest_utils.tempdircontainsTempDir, 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.pyDjangoCommandMixinHelper to run shell commands. e.g.: "./manage.py cms check" in unittests.usage/tests:/django_tools_tests/test_unittest_django_command.pyDOM compare in unittestsThe 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.BaseTestCaseself.assertHTMLEqual() – for compare two HTML DOM treesself.assertDOM() – for check if nodes in response or not.self.assertContains() – Check if ond node occurs 'count’ times in responseMore info and examples in./django_tools_tests/test_dom_asserts.py@set_string_if_invalid() decoratorHelper 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-variablesUsage, 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 ;)unittest_utils/signals.pySignalsContextManagerconnect/disconnet signal callbacks via with statementunittest_utils/assertments.pyThe file contains some common assert functions:assert_startswith- Check if test starts with prefix.assert_endswith- Check if text ends with suffix.assert_locmem_mail_backend- Check if current email backend is the In-memory backend.{{{assert_language_code() - Check if given language_code is in settings.LANGUAGESassert_installed_apps()- Check entries in settings.INSTALLED_APPSassert_is_dir- Check if given path is a directoryassert_is_file- Check if given path is a fileassert_path_not_exists- Check if given path doesn't existsSpeedup testsSpeedup test run start by disable migrations, e.g.:from django_tools.unittest_utils.disable_migrations import DisableMigrations
MIGRATION_MODULES = DisableMigrations()small toolsdebug_csrf_failure()Display the normal debug page and not the minimal csrf debug page.
More info in DocString here:django_tools/views/csrf.pyimport lib helperadditional helper to the existingimportlibmore info in the sourcecode:./utils/importlib.pyhttp utilsPimped HttpRequest to get some more information about a request.
More info in DocString here:django_tools/utils/http.py@display_admin_errorDeveloper helper to display silent errors in ModelAdmin.list_display callables.
See:display_admin_errorindecorators.pyupgrade virtualenvA simple commandline script that callspip install —-upgrade XYfor 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.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.pyThis script will be obsolete, ifpip has a own upgrade command.django_tools.utils.url.GetDictSimilar to origin django.http.QueryDict but:urlencode() doesn't add "=" to empty values: "?empty" instead of "?empty="always mutableoutput will be sorted (easier for tests ;)More info, see tests:django_tools_tests/test_utils_url.pySignedCookieStorageStore information in signed Cookies, usedjango.core.signing.
So the cookie data can't be manipulated from the client.
Sources/examples:/django_tools/utils/client_storage.py/django_tools_tests/test_signed_cookie.pyPrint SQL QueriesPrint 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)
-------------------------------------------------------------------------------SetRequestDebugMiddlewaremiddleware to add debug bool attribute to request object.
More info:./debug/README.creoleTracebackLogMiddlewarePut traceback in log by calllogging.exception()onprocess_exception()Activate with:MIDDLEWARE_CLASSES = (
    ...
    'django_tools.middlewares.TracebackLogMiddleware.TracebackLogMiddleware',
    ...
)FnMatchIps() - Unix shell-style wildcards in INTERNAL_IPS / ALLOWED_HOSTSsettings.py e.g.:from django_tools.settings_utils import FnMatchIps

INTERNAL_IPS = FnMatchIps(["127.0.0.1", "::1", "192.168.*.*", "10.0.*.*"])
ALLOWED_HOSTS = FnMatchIps(["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 commandspermission_infoList all permissions for one django user.
(Needs'django_tools'in INSTALLED_APPS)e.g.:$ ./manage.py permission_info
No username given!

All existing users are:
foo, bar, john, doe

$ ./manage.py permission_info foo
All permissions for user 'test_editor':
	is_active    : yes
	is_staff     : yes
	is_superuser : no
[*] admin.add_logentry
[*] admin.change_logentry
[*] admin.delete_logentry
[ ] auth.add_group
[ ] auth.add_permission
[ ] auth.add_user
...logging_infoShows a list of all loggers and marks which ones are configured in settings.LOGGING:$ ./manage.py logging_infonice_diffsettingsSimilar to django 'diffsettings', but used pretty-printed representation:$ ./manage.py nice_diffsettingsdatabase_infoJust display some information about the used database and connections:$ ./manage.py database_infolist_modelsJust list all existing models in app_label.ModelName format. Useful to use this in 'dumpdata' etc:$ ./manage.py list_models..all others…There exist many miscellaneous stuff. Look in the source, luke!Backwards-incompatible changesOld changes archived in git history here:>=v0.47>=v0.35v0.51All Selenium helper are deprecated, please migrate toPlaywright;)v0.50Removed old selenium helper function,deprecated since v0.43Make all Selenium web driver instances persistent for the complete test run session.
This speedup tests and fixed some bugs in Selenium.This result in the same browser/webdriver settings for all test classes!Django compatibilitydjango-toolsdjango versionpython>= v0.52.03.2, 4.0, 4.13.8, 3.9, 3.10>= v0.50.02.2, 3.2, 4.03.8, 3.9, 3.10>= v0.49.02.2, 3.1, 3.23.7, 3.8, 3.9>= v0.47.02.2, 3.0, 3.1>= 3.6, pypy3>= v0.391.11, 2.03.5, 3.6, pypy3>= v0.38.11.8, 1.113.5, 3.6, pypy3>= v0.38.01.8, 1.113.5, 3.6>= v0.37.01.8, 1.113.4, 3.5>= v0.33.01.8, 1.112.7, 3.4, 3.5v0.30.1-v0.32.141.8, 1.9, 1.102.7, 3.4, 3.5v0.301.8, 1.92.7, 3.4v0.291.6 - 1.82.7, 3.4v0.26<=1.6v0.25<=1.4(See also combinations fortox in pyproject.toml)historydev-compare v0.54.0...mainTBCv0.54.0 - 15.09.2022Runsafetyin CI pipeline.NEW:SyslogHandlerfor easy logging tosyslogReplace creole README with markdownv0.53.0 - 18.08.2022NEW:MassContextManagerBase,DenyStdWrite+ Updated:StdoutStderrBufferEnhancerun_testservercommandSmall test project setup updatesv0.52.0 - 17.08.2022Moverun_testservermanagement command fromdjango_tools_test_apptodjango_toolsand polish it.RestrictAlwaysLoggedInAsSuperUserMiddlewareto the admin.Test with Django 3.2, 4.0 and 4.1v0.51.0 - 26.07.2022NEW:check_editor_config()to check editor config and line length in projectsDEPRECATE all Selenium helper, please migrate to Playwright ;)NEW:Playwrightbase Unittest class and login helperv0.50.0 - 29.05.2022Rename git "master" branch to "main"Usewebdriver-managerto setup selenium web driversCHANGE: Now all web driver instances are cached and reused for the complete test run!Usedarkerfor code formattingUpdate test matrix: Add Python 3.10 and Django v4.0 (remove Python 3.7 and Django 3.1)v0.49.0 - 22.11.2021 -compare v0.48.3...v0.49.0NEW:VersionProtectBaseModel- Protect a model against overwriting a newer entry with an older one, by adding a auto increment version number.NEW:AlwaysLoggedInAsSuperUserMiddlewareuseful for local dev server run to auto login into Django AdminEnhance Selenium test helpers andfix #21: Set chrome accept_languages in headless modeUpdate project: Tests, code-style etc.v0.48.3 - 20.12.2020 -compare v0.47.2...v0.48.3NEW:ImageDummy().in_memory_image_file()useful for e.g.: POST a image upload via Django's test clientv0.48.2 - 06.12.2020 -compare v0.47.1...v0.48.2Bugfix "Serve User Media File": Create tokens via migrations and handle if tokens not existsv0.48.1 - 06.12.2020 -compare v0.47.0...v0.48.1Add migration file to "Serve User Media File"v0.48.0 - 06.12.2020 -compare v0.47.0...v0.48.0NEW: "Serve User Media File" reuseable appNEW: django_tools.unittest_utils.signals.SignalsContextManagerUpdateinstalled_apps_utils.get_filtered_apps()and support app config entries insettings.INSTALLED_APPSv0.47.0 - 26.11.2020 -compare v0.46.1...v0.47.0updates for newer django versionsNEW: assert_warnings(), assert_no_warnings() and assert_in_logs()remove broken LoggingBuffer()update project setup, fix tests and pipelinesv0.46.1 - 19.02.2020 -compare v0.46.0...v0.46.1less restricted dependency specificationNEW:"django_tools.middlewares.LogHeaders.LogRequestHeadersMiddleware"SeleniumChromiumTestCase: set "accept_languages" and disable "headless" mode, see also:https://github.com/jedie/django-tools/issues/21v0.46.0 - 13.02.2020 -compare v0.45.3...v0.46.0dynamic_sitewas removed. Please use e.g.:django-hostsmodernize project setup and usepoetryremovelxmldecency by usingbleachforhtml_utils.html2textupdate code and code stylev0.45.3 - 25.08.2019 -compare v0.45.2...v0.45.3Addexcepted_exit_codetodjango_tools.unittest_utils.django_command.DjangoCommandMixinto it's possible to test errors in manage commandsv0.45.2 - 26.06.2019 -compare v0.45.1...v0.45.2NEW:django_tools.log_utils.throttle_admin_email_handler.ThrottledAdminEmailHandlerv0.45.1 - 03.04.2019 -compare v0.45.0...v0.45.1Bugfix ValueError indjango_tools.unittest_utils.email.print_mailboxv0.45.0 - 01.04.2019 -compare v0.44.2...v0.45.0NEW:OverwriteFileSystemStoragewith backup functionalityNEW:print_exc_plus()- traceback with a listing of all the local variablesNEW:assert_pformat_equalwithpprintppandicdiffNEW:assert_filenames_and_contentv0.44.2 - 02.01.2019 -compare v0.44.1...v0.44.2Handle errors like:https://github.com/andymccurdy/redis-py/issues/995v0.44.1 - 02.01.2019 -compare v0.44.0...v0.44.1LoggingBuffer: Don't deactivate existing log handler, just append the buffer handler.v0.44.0 - 13.12.2018 -compare v0.43.2...v0.44.0NEW:django_file = ImageDummy().create_django_file_info_image(text="")e.g.: for attach tomodels.ImageField()Makemockup.ImageDummy()usable even if django-filer is not installed.mockup.ImageDummy()default image format changed from png to jpegCleanup: remove old, since v0.35 deprecated mockup image APIv0.43.2 - 11.12.2018 -compare v0.43.1...v0.43.2Bugfix Selenium refactor: Use the class with the same functionality if old usage places are used.v0.43.1 - 11.12.2018 -compare v0.43.0...v0.43.1Bugfix: Selenium test cases: clearwindow.localStorageafter test runv0.43.0 - 11.12.2018 -compare v0.42.4...v0.43.0Refactor selenium helpersSplit selenium test cases: with and without Django StaticLiveServerTestCaseNEW: Selenium helper to accesswindow.localStoragev0.42.4 - 12.10.2018 -compare v0.42.3...v0.42.4Addrequestobject toTestUserMixin.login()(needed for e.g.: django-axes auth backend)v0.42.3 - 10.10.2018 -compare v0.42.2...v0.42.3NEW: *assertments.assert_is_dir,assertments.assert_is_file,assertments.assert_path_not_existsv0.42.2 - 18.09.2018 -compare v0.42.1...v0.42.2NEW:assert_installed_apps()- Check entries in settings.INSTALLED_APPSv0.42.1 - 17.09.2018 -compare v0.42.0...v0.42.1NEW:django_tools.unittest_utils.assertments.assert_language_code- Check if given language_code is in settings.LANGUAGESv0.42.0 - 07.09.2018 -compare v0.41.0...v0.42.0remove all celery stuffNEW:$ ./manage.py logging_infoShows a list of all loggers and marks which ones are configured in settings.LOGGINGmanage commandslist_modelsandnice_diffsettingsare moved from seperate appsv0.41.0 - 28.08.2018 -compare v0.40.6...v0.41.0NEW:unittest_utils/assertments.pywith some common assert functionsRemove@task_always_eager()decoratorv0.40.6 - 28.08.2018 -compare v0.40.5...v0.40.6Bugfix@task_always_eager()decoratorv0.40.5 - 27.08.2018 -compare v0.40.4...v0.40.5BugfixDjangoCommandMixin.call_manage_py(): Use the givenmanage.pyfilenamev0.40.4 - 21.08.2018 -compare v0.40.3...v0.40.4NEW:django_tools.debug.delayto simulate longer processing time by set a delay via GET parameter (see above)v0.40.3 - 18.07.2018 -compare v0.40.2...v0.40.3Enhance selenium test cases:NEW:assert_visible_by_id()NEW:assert_clickable_by_id()NEW:assert_clickable_by_xpath()adddesired_capabilitiesto firefox and chrome test casesenable logging in chrome test caseNEW:assert_in_browser_log()in chrome test casev0.40.2 - 04.07.2018 -compare v0.40.1...v0.40.2Bugfix selenium Test Case if driver is NoneBugfix django compatibilityv0.40.1 - 28.06.2018 -compare v0.40.0...v0.40.1Bugfix selenium test case if executable can't be found.v0.40.0 - 15.06.2018 -compare v0.39.6...v0.40.0NEW: selenium chrome and firefox test cases indjango_tools.unittest_utils.selenium_utilsFix test project and addrun_test_project_dev_server.shfor easy testFixing testsv0.39.6 - 04.05.2018 -compare v0.39.5...v0.39.6Enhance model instance unittest code generatorv0.39.5 - 24.04.2018 -compare v0.39.4...v0.39.5NEW: Model instance unittest code generator (see above)v0.39.4 - 06.04.2018 -compare v0.39.3...v0.39.4NEW:django_tools.unittest_utils.logging_utils.FilterAndLogWarningsanddjango_tools.unittest_utils.logging_utils.CutPathnameLogRecordFactoryv0.39.3 - 22.03.2018 -compare v0.39.2...v0.39.3django_tools.permissions.get_filtered_permissionshas new keyword argument:exclude_actionsv0.39.2 - 22.03.2018 -compare v0.39.1...v0.39.2NEW:django_tools.parler_utils.parler_fixtures.ParlerDummyGeneratorNEW:django_tools.fixture_tools.languages.iter_languagesv0.39.1 - 19.03.2018 -compare v0.39.0...v0.39.1NEW:django_tools.unittest_utils.email.print_mailbox()minor updatesv0.39.0 - 02.03.2018 -compare v0.38.9...v0.39.0NEW: Isolated Filesystem decorator / context managerBackwards-incompatible change: file renameddjango_tools/unittest_utils/{celery.py => celery_utils.py}Skip run test with Django 1.8 and run tests with Django 1.11 and 2.0v0.38.9 - 05.02.2018 -compare v0.38.8...v0.38.9lowering log level on missing permissions from "error" to "debug"v0.38.8 - 05.02.2018 -compare v0.38.7...v0.38.8send mail: use from celery import shared_task instead of djcelery_transactionsv0.38.7 - 15.01.2018 -compare v0.38.6...v0.38.7Add missing arguments (like "attachments", "cc" etc.) todjango_tools.mail.send_mail.SendMailCeleryv0.38.6 - 10.01.2018 -compare v0.38.4...v0.38.5NEW:./manage.py clear_cacheDisplay POST data in browser debug (django_tools.unittest_utils.BrowserDebug.debug_response)v0.38.5 - 02.01.2018 -compare v0.38.4...v0.38.5NEW: Helper to assert django message framework output in unittests:BaseUnittestCase.get_messages(): return a list of all messagesBaseTestCase.assertMessages(): compare messagesBaseTestCase.assertResponse(): has new keyword argumentmessagesNEW:BaseUnittestCase.assert_exception_startswith()v0.38.4 - 28.12.2017 -compare v0.38.3...v0.38.4Bugfix attach user group on existing user in:django_tools.unittest_utils.user.get_or_create_userv0.38.3 - 28.12.2017 -compare v0.38.2...v0.38.3Bugfix:unittest_utils.user.get_or_create_groupalso removes obsolete permissions, too.v0.38.2 - 27.12.2017 -compare v0.38.1...v0.38.2NEW:./manage.py update_permissionsv0.38.1 - 21.12.2017 -compare v0.38.0...v0.38.1refactor travis/tox/pytest/coverage stuffTests can be run viapython3 setup.py toxand/orpython3 setup.py testTest also with pypy3 on Travis CI.v0.38.0 - 19.12.2017 -compare v0.37.0...v0.38.0NEW:django_tools.unittest_utils.user.get_or_create_groupNEW:django_tools.unittest_utils.user.get_or_create_userNEW:django_tools.unittest_utils.user.get_or_create_user_and_groupNEW:BaseUnittestCase.get_admin_change_url()andBaseUnittestCase.get_admin_add_url()NEW:BaseUnittestCase.assert_startswith()andBaseUnittestCase.assert_endswith()v0.37.0 - 11.12.2017 -compare v0.36.0...v0.37.0Skip official support for python v2 (remove from text matrix)NEW:./manage.py permission_info: Display a list of all permissions for one django userNEW:django_tools.permissions.get_filtered_permissions()anddjango_tools.permissions.pprint_filtered_permissions()django_tools.settings_utils.InternalIpswas renamed toFnMatchIpsand can be also used forALLOWED_HOSTSBugfix/Enhance permission helpersv0.36.0 - 20.11.2017 -compare v0.35.0...v0.36.0NEW:./manage.py database_infoBugfix:ModelPermissionMixinDynamic Sites is no longer maintained and tests are deactivated. It's currently not compatible with all django versions.v0.35.0 - 26.09.2017 -compare v0.34.0...v0.35.0CHANGE: The dummy image generation function indjango_tools.unittest_utils.mockuphas a new API.v0.34.0 - 18.09.2017 -compare v0.33.0...v0.34.0CHANGE: The test usernames changed and spaces was replace with underscores e.g.: "staff test user" -> "staff_test_user"Bugfix in mockup.create_pil_image: Created images has wrong sizesv0.33.0 - 11.07.2017 -compare v0.32.14...v0.33.0Run tests only against Django v1.8 TLS and v1.11 TLSFor Django 1.11: Add support for new-style middleware - contributed by benkonrathNEW:django_tools.utils.request.create_fake_request()for easier create a faked request object withRequestFactoryNEW:django_tools.utils.html_utils.html2text()- Strip HTML tags with lxml Cleaner + Django 'strip_tags'v0.32.14 - 14.06.2017 -compare v0.32.13...v0.32.14Bugfix for Python 2:mockbackport package is needed and added tosetup.install_requiresv0.32.13 - 24.05.2017 -compare v0.32.12...v0.32.13remove some warningsv0.32.12 - 04.05.2017 -compare v0.32.11...v0.32.12NEW:self.assertIn_dedent()indjango_tools.unittest_utils.unittest_base.BaseUnittestCasev0.32.11 - 02.05.2017 -compare v0.32.10...v0.32.11Fix PyPi package mistake (.tar.gzarchive contains.tox;)v0.32.10 - 02.05.2017 -compare v0.32.9...v0.32.10NEW:django_tools.mailto send text+html mails (see above)v0.32.9 - 21.03.2017 -compare v0.32.8...v0.32.9BugfixDebugCacheLoaderif TemplateDoesNotExist was raisedv0.32.8 - 16.03.2017 -compare v0.32.7...v0.32.8NEW:django_tools.template.loader.DebugCacheLoaderto add template name as html commentsChange temp filename in BrowserDebug and usedjango_tools_browserdebug_prefixBugfix indjango_tools.middlewares.ThreadLocal.ThreadLocalMiddlewarev0.32.7 - 10.03.2017 -compare v0.32.6...v0.32.7NEW:django_tools.permissions- helper for setup permissionsNEW:/unittest_utils/user.py- helper for creating users (needfull in unittests)v0.32.6 - 22.02.2017 -compare v0.32.5...v0.32.6@task_always_eager()decorator will setCELERY_EAGER_PROPAGATES_EXCEPTIONS=True, too.v0.32.5 - 10.02.2017 -compare v0.32.4...v0.32.5NEW: Addtemplate_name(optional) toself.assertResponse()(check withassertTemplateUsed())v0.32.4 - 01.02.2017 -compare v0.32.3...v0.32.4Fix: Set "is_active" for created test usersv0.32.3 - 25.01.2017 -compare v0.32.2...v0.32.3Fix UnicodeDecodeError in BrowserDebugNEW:@set_string_if_invalid()decoratorNEW:@task_always_eager()decoratorv0.32.2 - 13.01.2017 -compare v0.32.1...v0.32.2NEW: django_tools.utils.url.GetDictv0.32.1 - 29.12.2016 -compare v0.32.0...v0.32.1NEW: TracebackLogMiddlewarev0.32.0 - 19.12.2016 -compare v0.31.0...v0.32.0NEW: 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_fileusepytest-djangoremove outdated stuff: See 'Backwards-incompatible changes' above.v0.31.0 - 03.11.2016 -compare v0.30.4...v0.31.0add 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.4add DjangoCommandMixinv0.30.2 - 05.10.2016 -compare v0.30.1...v0.30.2Bugfix Python 2 compatibilityv0.30.1 - 26.08.2016 -compare v0.30.0...v0.30.1add:django_tools.unittest_utils.disable_migrations.DisableMigrations(see above)run tests also with django v1.10 and Python 3.5use toxv0.30.0 - 27.04.2016 -compare v0.29.5...v0.30.0Django 1.9 and Python 3 support contributed bynaegelydv0.29.4 and v0.29.5 - 10.08.2015 -compare v0.29.3...v0.29.5Some bugfixes for django 1.6 supportv0.29.3 - 10.08.2015 -compare v0.29.2...v0.29.3Clear ThreadLocal request atttribute after response is processed (contributed by Lucas Wiman)v0.29.2 - 19.06.2015 -compare v0.29.1...v0.29.2Bugfix in unittest_utils.selenium_utils.selenium2fakes_responseassertResponse used assertContains from djangoAdd QueryLogMiddleware (TODO: add tests)v0.29.1 - 17.06.2015 -compare v0.29.0...v0.29.1Bugfixes for Py2 and Py3add StdoutStderrBuffer()v0.29.0 - 09.06.2015 -compare v0.26.0...v0.29.0WIP: 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 usingUpdateInfoBaseModelBugfixes indynamic_sitefor django 1.7add:django_tools.settings_utils.InternalIpsv0.28.0 - 12.02.2015 -compare v0.26.0...v0.28.0Work-a-round for import loops(new Version number, because of PyPi stress)v0.26.0 - 11.02.2015 -compare v0.25.1...v0.26.0Updates for Django 1.6 and Python 3v0.25.1 - 18.11.2013Bugfix: Fall back to "UTF-8" if server send no encoding infov0.25.0 - 28.08.2012Renamecache.clear()in SmoothCacheBackends tocache.smooth_update(), so that reset timestamp is independ from clear the cache.v0.24.10 - 24.08.2012AddSmoothCacheBackends:./cache/README.creolev0.24.9 - 24.08.2012Bugfix in per-site cache middleware: set inital count values to None, if counting is disabled.v0.24.8 - 24.08.2012Enhancedper-site cache middleware:./cache/README.creoleAddSetRequestDebugMiddleware:./debug/README.creolev0.24.7 - 21.08.2012Add theper-site cache middleware(see above)Addimport lib helper:./utils/importlib.pyv0.24.6 - 21.08.2012Add thefilemanager library(see above)v0.24.5 - 06.08.2012AddPrint SQL Queriescontext manager. (see above)v0.24.4 - 26.07.2012remove date from version string, cause of side-effects e.g.: user clone the repo and has the filter not installedv0.24.3 - 25.07.2012"Hardcode" the version string date attachment viagitattribute filter scriptto fixa reported issueswithpip requirements file bug.v0.24.2 - 10.07.2012SplitUpdateInfoBaseModel(): So you can only set "createtime", "lastupdatetime" or "createby", "lastupdateby" or both types (This is backwards compatible)v0.24.1 - 12.06.2012Bugfix: UsergroupsModelField() and add unittests for itAdd "normal users" in UsergroupsModelField()New: Add create_user() and create_testusers() to BaseTestCaseAdd a test project for the unittests. TODO: use this for all testsv0.24.0 - 04.06.2012Don't use auto_now_add and auto_now in UpdateInfoBaseModelBugfix inUsergroupsModelFieldv0.23.1Dynamic Sitewould be only initialised if settings.USE_DYNAMIC_SITE_MIDDLEWARE = Truev0.23.0Use cryptographic signing tools from django 1.4 in django_tools.utils.client_storagev0.22.0Addstatic_path.pythats used settings.STATIC_ROOT.The oldmedia_path.pywhich 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.1Bugfixes inDynamic Site.v0.21.0betaNew: site alias functionrefractory 'DynamicSiteMiddleware' to a own app (Backwards-incompatible change:change your settings if you use the old DynamicSiteMiddleware.)v0.20.1New:debug_csrf_failure()to display the normal debug page and not the minimal csrf debug page.v0.20.0Add experimentalDynamicSiteMiddleware, please test it and give feedback.v0.19.6Add some south introspection rules for LanguageCodeModelField and jQueryTagModelFieldfallback if message for anonymous user can't created, because django.contrib.messages middleware not used.Bugfix in django_tools.utils.messages.StackInfoStoragev0.19.5Addhttp://bugs.python.org/file22767/hp_fix.diffforhttps://github.com/gregmuellegger/django/issues/1v0.19.4Bugfix for PyPy in local_sync_cache get_cache_information(): sys.getsizeof() not implemented on PyPyBugfix in template.filters.chmod_symbol()Nicer solution for template.filters.human_duration()v0.19.3Add support for https in utils/http.pyv0.19.2Bugfix in utils/http.py timeout work-a-roundv0.19.1utils/http.py changes:Use a better solution, see:Add timeout and add a work-a-round for Python < 2.6v0.19.0NEW: Add utils/http.py with helpers to get a webpage via http GET in unicodeChange README from textile to creole ;)v0.18.2Bugfix: Add missing template in pypi packagev0.18.0NEW: Add DOM compare from Gregor Müllegger GSoC work into unittest utils.v0.17.1Bugfix in “limit_to_usergroups”: Make choices “lazy”: Don’t access the database ininitv0.17Add the script “upgrade_virtualenv.py”Add “limit_to_usergroups”Add “local sync cache”Add models.UpdateInfoBaseModelUpdate decorators.render_torender_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 importablev0.16.4Bugfix:get_db_prep_save() got an unexpected keyword argument 'connection’when save a SignSeparatedModelField()v0.16.3Update BrowserDebug: Use response.templates instead of response.template and make output nicerv0.16.2Merge stack info code and display better stack info on browser debug pagev0.16.1Update django_tools.utils.messages.StackInfoStorage for django code changes.v0.16.0NEW: path model field (check if direcotry exist)v0.15.0NEW: Add a flexible URL field (own validator, model- and form-field)v0.14.1Bugfix: make path in MediaPathModelField relativ (remove slashes)v0.14NEW: django-tagging addon: Display existing tags under a tag fieldv0.13Bugfix UnicodeEncodeError in Browser debugv0.12NEW: django_tools.utils.messages.failsafe_messagev0.11NEW: Store data in a secure cookie, see: utils/client_storage.pyv0.10.1New: Display used templates in unittest BrowserDebugBugfix: catch if last usermessages existv0.10.0NEW: utils around django messages, see: /django_tools/utils/messages.pyv0.9.1Bugfix: database column was not created: don’t overwrite get_internal_type()v0.9New: stuff in /django_tools/fields/see also backwards-incompatible changes, above!v0.8.2New: widgets.SelectMediaPath(): Select a sub directory in settings.MEDIA_ROOTNew: fields.SignSeparatedField()v0.8.1Add “no_args” keyword argument to installed_apps_utils.get_filtered_apps()v0.8.0Add model LanguageCode field and form LanguageCode field in Accept-Language header format (RFC 2616)v0.7.0Add decorators.pyv0.6.0Add forms_utils.LimitManyToManyFields, crosspost:http://www.djangosnippets.org/snippets/1691/v0.5.0Add template/filters.py from PyLucid v0.8.xv0.4.0Add experimental “warn_invalid_template_vars”v0.3.1Bugfix: Exclude the instance if it was saved in the past.v0.3.0Add utils.installed_apps_utilsv0.2.0Add models_utils, see:http://www.jensdiemer.de/_command/118/blog/detail/67/(de)v0.1.0first version cut out from PyLucid CMS –http://www.pylucid.orglinks| Homepage |https://github.com/jedie/django-tools|
| PyPi     |https://pypi.python.org/pypi/django-tools/|donationpaypal.me/JensDiemerFlattr This!SendBitcoinsto1823RZ5Md1Q2X5aSXRC5LRPcYdveCiVX6F