[Python-modules-commits] [python-django-extensions] 01/05: Import python-django-extensions_1.6.3.orig.tar.gz

Brian May bam at moszumanska.debian.org
Sun May 1 08:56:01 UTC 2016


This is an automated email from the git hooks/post-receive script.

bam pushed a commit to branch master
in repository python-django-extensions.

commit 6f7d6c6b2899bc99eace29aee502ecc3ea08ef88
Author: Brian May <bam at debian.org>
Date:   Sun May 1 18:48:10 2016 +1000

    Import python-django-extensions_1.6.3.orig.tar.gz
---
 .gitignore                                         |   5 +-
 .travis.yml                                        |  11 +-
 CHANGELOG.md                                       |  39 +++++
 Makefile                                           |  40 +++++
 README.rst                                         |  48 ++----
 conftest.py                                        |  72 --------
 django_extensions/__init__.py                      |   4 +-
 django_extensions/admin/__init__.py                |  16 +-
 django_extensions/admin/widgets.py                 |   9 +-
 django_extensions/compat.py                        |  59 ++++++-
 django_extensions/db/__init__.py                   |   1 +
 django_extensions/db/fields/__init__.py            |  30 ++--
 django_extensions/db/fields/encrypted.py           |   9 +-
 django_extensions/db/fields/json.py                |  13 +-
 django_extensions/db/models.py                     |   5 +
 django_extensions/jobs/__init__.py                 |   1 +
 django_extensions/jobs/daily/__init__.py           |   1 +
 django_extensions/jobs/daily/cache_cleanup.py      |   1 +
 django_extensions/jobs/daily/daily_cleanup.py      |   1 +
 django_extensions/jobs/hourly/__init__.py          |   1 +
 django_extensions/jobs/minutely/__init__.py        |   1 +
 django_extensions/jobs/monthly/__init__.py         |   1 +
 django_extensions/jobs/weekly/__init__.py          |   1 +
 django_extensions/jobs/yearly/__init__.py          |   1 +
 django_extensions/logging/__init__.py              |   1 +
 django_extensions/logging/filters.py               |   1 +
 django_extensions/management/__init__.py           |   1 +
 django_extensions/management/base.py               |   1 +
 django_extensions/management/color.py              |   1 +
 django_extensions/management/commands/__init__.py  |   1 +
 .../management/commands/admin_generator.py         |  48 +++---
 django_extensions/management/commands/clean_pyc.py |  23 +--
 .../management/commands/clear_cache.py             |   2 +-
 .../management/commands/compile_pyc.py             |  18 +-
 .../management/commands/create_app.py              |  32 ++--
 .../management/commands/create_command.py          |  56 ++++---
 .../management/commands/create_jobs.py             |  42 +++--
 .../management/commands/create_template_tags.py    |  17 +-
 .../management/commands/describe_form.py           |   4 +-
 .../management/commands/drop_test_database.py      |  59 ++++---
 .../management/commands/dumpscript.py              |  29 ++--
 .../management/commands/export_emails.py           |  23 +--
 .../management/commands/find_template.py           |  14 +-
 .../management/commands/generate_secret_key.py     |   8 +-
 .../management/commands/graph_models.py            | 181 ++++++++++++++-------
 .../management/commands/mail_debug.py              |  22 ++-
 django_extensions/management/commands/notes.py     |  13 +-
 django_extensions/management/commands/passwd.py    |   4 +-
 .../management/commands/pipchecker.py              |  36 ++--
 .../management/commands/print_settings.py          |  17 +-
 .../management/commands/print_user_for_session.py  |   4 +-
 django_extensions/management/commands/reset_db.py  |  73 +++++----
 django_extensions/management/commands/runjob.py    |  15 +-
 django_extensions/management/commands/runjobs.py   |  15 +-
 .../management/commands/runprofileserver.py        |  96 ++++++-----
 django_extensions/management/commands/runscript.py |   5 +-
 .../management/commands/runserver_plus.py          |  88 +++++-----
 .../management/commands/set_default_site.py        |  28 ++--
 .../management/commands/set_fake_emails.py         |  48 +++---
 .../management/commands/set_fake_passwords.py      |  25 +--
 .../management/commands/shell_plus.py              |  81 +++++----
 .../management/commands/show_template_tags.py      |   7 +-
 .../management/commands/show_templatetags.py       |   1 +
 django_extensions/management/commands/show_urls.py |  68 +++++---
 django_extensions/management/commands/sqlcreate.py |  22 +--
 django_extensions/management/commands/sqldiff.py   |  39 +++--
 django_extensions/management/commands/sqldsn.py    |  39 ++---
 django_extensions/management/commands/sync_s3.py   |  73 +++++----
 django_extensions/management/commands/syncdata.py  |  16 +-
 .../management/commands/unreferenced_files.py      |   7 +-
 .../management/commands/update_permissions.py      |   3 +-
 .../management/commands/validate_templates.py      |  32 ++--
 .../management/email_notifications.py              |  31 ++--
 django_extensions/management/jobs.py               |   1 +
 django_extensions/management/modelviz.py           |  85 +++++++---
 django_extensions/management/mysql.py              |  43 +++++
 django_extensions/management/notebook_extension.py |   1 +
 django_extensions/management/shells.py             |   1 +
 django_extensions/management/signals.py            |   1 +
 django_extensions/management/technical_response.py |   1 +
 django_extensions/management/utils.py              |   1 +
 django_extensions/models.py                        |   1 +
 django_extensions/mongodb/__init__.py              |   1 +
 django_extensions/mongodb/fields/__init__.py       |   7 +-
 django_extensions/mongodb/fields/encrypted.py      |   3 +-
 django_extensions/mongodb/fields/json.py           |   1 +
 django_extensions/mongodb/models.py                |   1 +
 django_extensions/settings.py                      |   1 +
 django_extensions/south_migrations/__init__.py     |   1 +
 django_extensions/templatetags/__init__.py         |   1 +
 django_extensions/templatetags/highlighting.py     |   3 +-
 django_extensions/templatetags/indent_text.py      |   1 +
 django_extensions/templatetags/syntax_color.py     |   1 +
 django_extensions/templatetags/truncate_letters.py |   1 +
 django_extensions/templatetags/widont.py           |   1 +
 django_extensions/utils/__init__.py                |   1 +
 django_extensions/utils/dia2django.py              |  69 ++++----
 django_extensions/utils/text.py                    |   1 +
 django_extensions/utils/validatingtemplatetags.py  |   1 +
 django_extensions/validators.py                    |   1 +
 docs/AUTHORS                                       |   3 +-
 docs/command_extensions.rst                        |   2 +
 docs/conf.py                                       |  72 ++++----
 docs/field_extensions.rst                          |  32 +++-
 docs/runprofileserver.rst                          |  20 +++
 docs/runscript.rst                                 |  40 +++--
 docs/runserver_plus.rst                            |  21 +++
 setup.cfg                                          |   2 +-
 setup.py                                           |  24 ++-
 tests/__init__.py                                  |   1 +
 tests/management/__init__.py                       |   1 +
 tests/management/commands/__init__.py              |   1 +
 tests/management/commands/error_raising_command.py |   1 +
 tests/test_autoslug_fields.py                      |   1 +
 tests/test_clean_pyc.py                            |   1 +
 tests/test_compile_pyc.py                          |   1 +
 tests/test_dumpscript.py                           |   1 +
 tests/test_encrypted_fields.py                     |   1 +
 tests/test_find_template.py                        |  19 +++
 tests/test_json_field.py                           |  29 ++++
 tests/test_management_command.py                   | 103 ++++++++++++
 tests/test_models.py                               |   1 +
 tests/test_randomchar_field.py                     |  22 +--
 tests/test_runscript.py                            |   1 +
 tests/test_shortuuid_field.py                      |   1 +
 tests/test_templatetags.py                         |   1 +
 tests/test_timestamped_model.py                    |  25 +++
 tests/test_uuid_field.py                           |   1 +
 tests/testapp/__init__.py                          |   1 +
 tests/testapp/apps.py                              |   1 +
 tests/testapp/models.py                            |  15 +-
 tests/testapp/scripts/__init__.py                  |   1 +
 tests/testapp/scripts/sample_script.py             |   1 +
 tests/testapp/settings.py                          |  35 ++++
 tests/testapp/urls.py                              |   1 +
 tox.ini                                            |  35 +---
 136 files changed, 1639 insertions(+), 950 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7fd246f..12dd2a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
-*.pyc
-*.pyo
+*.py[cod]
 *.egg-info
 MANIFEST
 build
@@ -7,7 +6,6 @@ dist
 docs/_build
 docs/_static
 venv*
-*.egg-info
 .tox
 *.bak
 .DS_Store
@@ -15,4 +13,3 @@ venv*
 .idea/
 .coverage
 .cache/
-
diff --git a/.travis.yml b/.travis.yml
index 1de43c1..a1e7814 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,14 +9,9 @@ env:
     - TOX_ENV=py27-flake8
     - TOX_ENV=py34-flake8
     - TOX_ENV=py35-flake8
-    - TOX_ENV=py27-dj14
-    - TOX_ENV=py27-dj15
     - TOX_ENV=py27-dj16
-    - TOX_ENV=py32-dj15
     - TOX_ENV=py32-dj16
-    - TOX_ENV=py33-dj15
     - TOX_ENV=py33-dj16
-    - TOX_ENV=py34-dj15
     - TOX_ENV=py34-dj16
     - TOX_ENV=py27-dj17
     - TOX_ENV=py27-dj18
@@ -24,10 +19,8 @@ env:
     - TOX_ENV=py27-djmaster
     - TOX_ENV=py32-dj17
     - TOX_ENV=py32-dj18
-    - TOX_ENV=py32-djmaster
     - TOX_ENV=py33-dj17
     - TOX_ENV=py33-dj18
-    - TOX_ENV=py33-djmaster
     - TOX_ENV=py34-dj17
     - TOX_ENV=py34-dj18
     - TOX_ENV=py34-dj19
@@ -46,14 +39,12 @@ matrix:
   allow_failures:
     - env: TOX_ENV=py35-djmaster
     - env: TOX_ENV=py34-djmaster
-    - env: TOX_ENV=py33-djmaster
-    - env: TOX_ENV=py32-djmaster
     - env: TOX_ENV=py27-djmaster
     - env: TOX_ENV=pypy-djmaster
     - env: TOX_ENV=pypy3-djmaster
 
 install:
-  - pip install tox coveralls
+  - pip install "virtualenv<14.0.0" tox coveralls
 
 script:
   - tox -e $TOX_ENV
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b85bca1..6a50eae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,45 @@
 Changelog
 =========
 
+1.6.2
+-----
+
+The long over due release :-)
+
+Changes:
+ - Fix: JsonFields, do not parse floats as decimals. This fixes bugs that causes
+        them to be returned as strings after multiple saves. Note that this can
+        be backwards incompatible !
+ - Fix: use add_arguments() instead of option_list (Django 1.10)
+ - Fix: create_command, Django 1.9 fixes
+ - Fix: create_jobs, Django 1.9 fixes
+ - Fix: RandomCharField, when not unique get the first value from the generator
+ - Fix: graph_models, render() must be called with a dict
+ - Fix: graph_models, use force_bytes fixes command for Python 3
+ - Fix: graph_models, fix django 1.6 compatibility for strings defined relation
+ - Fix: graph_models, fix settings.GRAPH_MODELS breaking the command
+ - Fix: graph_models, add support for lazy relationships
+ - Fix: ForeignKeyAutocompleteAdmin, url_patterns is just a list (Django 1.9+)
+ - Fix: ForeignKeySearchInput, use url reversing instead of hardcoded paths
+ - Fix: find_template, Fix for Django 1.8+
+ - Fix: admin_generator, incompatible "default" identifier raising TypeError
+ - Improvement: show_urls, add json and pretty-json formatting
+ - Improvement: runserver_plus, add support for whitenoise
+ - Improvement: ModificationDateTimeField, add parameter to preserve timestamps on save
+ - Improvement: runprofileserver, raise command error when hotspot is not available
+ - Improvement: reset_db, better parsing of mysql cnf file
+ - Improvement: restored coverage for Python 3.2
+ - Improvement: pep8 fixes, remove unused shims & imports & commented code
+ - Improvement: graph_models, JSON output
+ - Improvement: graph_models, add wildcard filters
+ - Docs: removed text on donations, the hope was that we could generate some
+         funds to have more consistent development and outreach.
+ - Docs: runserver_plus, added some documentation about LOGGING
+ - Docs: runscript, update documentation to match Django tutorial for Django 1.8+
+ - Docs: runprofileserver, add documentation on profiler choices
+ - Docs: update_permissions, add basic documentation for command
+
+
 1.6.1
 -----
 
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1865c1a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,40 @@
+help:
+	@echo "clean - remove all build, test, coverage and Python artifacts"
+	@echo "clean-build - remove build artifacts"
+	@echo "clean-pyc - remove Python file artifacts"
+	@echo "clean-test - remove test and coverage artifacts"
+	@echo "test - run tests quickly with the default Python"
+	@echo "coverage - check code coverage quickly with the default Python"
+	@echo "install - install the package to the active Python's site-packages"
+
+clean: clean-test clean-build clean-pyc
+
+clean-build:
+	rm -fr build/
+	rm -fr dist/
+	rm -fr .eggs/
+	find . -name '*.egg-info' -exec rm -fr {} +
+	find . -name '*.egg' -exec rm -fr {} +
+
+clean-pyc:
+	find . -name '*.pyc' -exec rm -f {} +
+	find . -name '*.pyo' -exec rm -f {} +
+	find . -name '*~' -exec rm -f {} +
+	find . -name '__pycache__' -exec rm -fr {} +
+
+clean-test:
+	rm -fr .cache/
+	rm -fr .tox/
+	rm -f .coverage
+	rm -fr htmlcov/
+
+test:
+	python setup.py test --pytest-args="tests --ds=tests.testapp.settings --cov=django_extensions"
+
+coverage:
+	coverage run --source django_extensions setup.py test
+	coverage report -m
+	coverage html
+
+install: clean
+	python setup.py install
diff --git a/README.rst b/README.rst
index 0fcbf6a..f722439 100644
--- a/README.rst
+++ b/README.rst
@@ -2,21 +2,25 @@
  Django Extensions
 ===================
 
-.. image:: https://img.shields.io/badge/license-MIT-blue.svg
+.. image:: https://img.shields.io/pypi/l/django-extensions.svg
    :target: https://raw.githubusercontent.com/django-extensions/django-extensions/master/LICENSE
 
 .. image:: https://secure.travis-ci.org/django-extensions/django-extensions.png?branch=master
     :alt: Build Status
     :target: http://travis-ci.org/django-extensions/django-extensions
 
-.. image:: https://pypip.in/v/django-extensions/badge.png
+.. image:: https://img.shields.io/pypi/v/django-extensions.svg
     :target: https://pypi.python.org/pypi/django-extensions/
     :alt: Latest PyPI version
 
-.. image:: https://pypip.in/d/django-extensions/badge.png
+.. image:: https://img.shields.io/pypi/dm/django-extensions.svg
     :target: https://pypi.python.org/pypi/django-extensions/
     :alt: Number of PyPI downloads
 
+.. image:: https://img.shields.io/pypi/wheel/django-extensions.svg
+    :target: https://pypi.python.org/pypi/django-extensions/
+    :alt: Supports Wheel format
+
 .. image:: https://coveralls.io/repos/django-extensions/django-extensions/badge.png?branch=master
    :target: https://coveralls.io/r/django-extensions/django-extensions?branch=master
    :alt: Coverage
@@ -113,40 +117,14 @@ You can view documentation online at:
 Or you can look at the docs/ directory in the repository.
 
 
-Donations
-=========
-
-Django Extensions is free and always will be. From time to time people and company's have expressed the willingness
-to donation to the project to help foster it's development. We prefer people to become active in the project and support
-us by sending pull requests but will humbly accept donations as well.
-
-Donations will be used to make Django Extensions better by allowing developers to spend more time on it, paying to go
-to conferences, paying for infrastructure, etc. If for some reason we would receive more donations then needed they will
-go towards the Django and Python foundations.
-
-We have setup a couple of ways you can donate towards Django Extensions using the buttons below:
-
- - Bountysource
- - Gratipay (formerly Gittip)
- - Flattr
- - PayPal
- - Patreon `here <https://patreon.com/trbs>`_
-
-.. image:: https://www.bountysource.com/badge/team?team_id=7470&style=bounties_posted
-    :target: https://www.bountysource.com/teams/django-extensions/bounties?utm_source=django-extensions&utm_medium=shield&utm_campaign=bounties_posted
-    :alt: BountySource
-
-.. image:: https://img.shields.io/flattr/donate.png
-    :target: https://flattr.com/submit/auto?user_id=Trbs&url=https%3A%2F%2Fgithub.com%2Fdjango-extensions%2Fdjango-extensions
-    :alt: Flattr this
+Support
+=======
 
-.. image:: https://img.shields.io/paypal/donate.png
-    :target: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=P57EJJ9QYL232
-    :alt: PayPal Donations
+Django Extensions is free and always will be. It is development and maintained by developers in an Open Source manner.
+Any support is welcome. You could help by writing documentation, pull-requests, report issues and/or translations.
 
-.. image:: https://img.shields.io/gratipay/trbs.png
-    :target: https://gratipay.com/trbs/
-    :alt: Gifts received
+Please remember that nobody is payed directly to develop or maintain Django Extensions so we do have to divide our time
+between putting food on the table, family, this project and the rest of life :-)
 
 
 __ http://ericholscher.com/blog/2008/sep/12/screencast-django-command-extensions/
diff --git a/conftest.py b/conftest.py
deleted file mode 100644
index 3091bdd..0000000
--- a/conftest.py
+++ /dev/null
@@ -1,72 +0,0 @@
-from django.conf import settings
-
-
-def pytest_configure():
-    import sys
-
-    try:
-        import django  # NOQA
-    except ImportError:
-        print("Error: missing test dependency:")
-        print("  django library is needed to run test suite")
-        print("  you can install it with 'pip install django'")
-        print("  or use tox to automatically handle test dependencies")
-        sys.exit(1)
-
-    try:
-        import shortuuid  # NOQA
-    except ImportError:
-        print("Error: missing test dependency:")
-        print("  shortuuid library is needed to run test suite")
-        print("  you can install it with 'pip install shortuuid'")
-        print("  or use tox to automatically handle test dependencies")
-        sys.exit(1)
-
-    try:
-        import dateutil  # NOQA
-    except ImportError:
-        print("Error: missing test dependency:")
-        print("  dateutil library is needed to run test suite")
-        print("  you can install it with 'pip install python-dateutil'")
-        print("  or use tox to automatically handle test dependencies")
-        sys.exit(1)
-
-    try:
-        import six  # NOQA
-    except ImportError:
-        print("Error: missing test dependency:")
-        print("  six library is needed to run test suite")
-        print("  you can install it with 'pip install six'")
-        print("  or use tox to automatically handle test dependencies")
-        sys.exit(1)
-
-    # Dynamically configure the Django settings with the minimum necessary to
-    # get Django running tests.
-    settings.configure(
-        INSTALLED_APPS=[
-            'django.contrib.auth',
-            'django.contrib.contenttypes',
-            'django.contrib.admin',
-            'django.contrib.sessions',
-            'tests.testapp',
-            'django_extensions',
-        ],
-        MIDDLEWARE_CLASSES=(
-            'django.contrib.sessions.middleware.SessionMiddleware',
-            'django.contrib.auth.middleware.AuthenticationMiddleware',
-            'django.contrib.messages.middleware.MessageMiddleware',
-        ),
-        # Django replaces this, but it still wants it. *shrugs*
-        DATABASE_ENGINE='django.db.backends.sqlite3',
-        DATABASES={
-            'default': {
-                'ENGINE': 'django.db.backends.sqlite3',
-                'NAME': ':memory:',
-            }
-        },
-        MEDIA_ROOT='/tmp/django_extensions_test_media/',
-        MEDIA_PATH='/media/',
-        ROOT_URLCONF='tests.urls',
-        DEBUG=True,
-        TEMPLATE_DEBUG=True,
-    )
diff --git a/django_extensions/__init__.py b/django_extensions/__init__.py
index 81c14e0..85e2f28 100644
--- a/django_extensions/__init__.py
+++ b/django_extensions/__init__.py
@@ -1,5 +1,5 @@
-
-VERSION = (1, 6, 1)
+# coding=utf-8
+VERSION = (1, 6, 3)
 
 # Dynamically calculate the version based on VERSION tuple
 if len(VERSION) > 2 and VERSION[2] is not None:
diff --git a/django_extensions/admin/__init__.py b/django_extensions/admin/__init__.py
index 4581a81..a147034 100644
--- a/django_extensions/admin/__init__.py
+++ b/django_extensions/admin/__init__.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 #
 # Autocomplete feature for admin panel
 #
@@ -55,7 +56,7 @@ class ForeignKeyAutocompleteAdmin(ModelAdmin):
     autocomplete_limit = getattr(settings, 'FOREIGNKEY_AUTOCOMPLETE_LIMIT', None)
 
     def get_urls(self):
-        from django.conf.urls import patterns, url
+        from django.conf.urls import url
 
         def wrap(view):
             def wrapper(*args, **kwargs):
@@ -69,7 +70,16 @@ class ForeignKeyAutocompleteAdmin(ModelAdmin):
         else:
             info = self.model._meta.app_label, self.model._meta.model_name
 
-        urlpatterns = patterns('', url(r'foreignkey_autocomplete/$', wrap(self.foreignkey_autocomplete), name='%s_%s_autocomplete' % info))
+        _url = url(r'foreignkey_autocomplete/$', wrap(self.foreignkey_autocomplete), name='%s_%s_autocomplete' % info)
+
+        # django.conf.urls.patterns is deprecated in django version 1.9 and removed in django version 1.10.
+        # It is replaced by a simple Python list
+        if django.VERSION < (1, 9):
+            from django.conf.urls import patterns
+            urlpatterns = patterns('', _url)
+        else:
+            urlpatterns = [_url]
+
         urlpatterns += super(ForeignKeyAutocompleteAdmin, self).get_urls()
         return urlpatterns
 
@@ -156,7 +166,7 @@ class ForeignKeyAutocompleteAdmin(ModelAdmin):
         Overrides the default widget for Foreignkey fields if they are
         specified in the related_search_fields class attribute.
         """
-        if (isinstance(db_field, models.ForeignKey) and db_field.name in self.related_search_fields):
+        if isinstance(db_field, models.ForeignKey) and db_field.name in self.related_search_fields:
             model_name = db_field.rel.to._meta.object_name
             help_text = self.get_help_text(db_field.name, model_name)
             if kwargs.get('help_text'):
diff --git a/django_extensions/admin/widgets.py b/django_extensions/admin/widgets.py
index 87a5505..c1e4676 100644
--- a/django_extensions/admin/widgets.py
+++ b/django_extensions/admin/widgets.py
@@ -1,7 +1,9 @@
+# coding=utf-8
 import six
 from django import forms
 from django.contrib.admin.sites import site
 from django.contrib.admin.widgets import ForeignKeyRawIdWidget
+from django.core.urlresolvers import reverse
 from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
 from django.utils.text import Truncator
@@ -15,7 +17,7 @@ class ForeignKeySearchInput(ForeignKeyRawIdWidget):
     # Set in subclass to render the widget with a different template
     widget_template = None
     # Set this to the patch of the search view
-    search_path = '../foreignkey_autocomplete/'
+    search_path = None
 
     def _media(self):
         js_files = ['django_extensions/js/jquery.bgiframe.min.js',
@@ -40,11 +42,12 @@ class ForeignKeySearchInput(ForeignKeyRawIdWidget):
     def render(self, name, value, attrs=None):
         if attrs is None:
             attrs = {}
-        #output = [super(ForeignKeySearchInput, self).render(name, value, attrs)]
         opts = self.rel.to._meta
         app_label = opts.app_label
         model_name = opts.object_name.lower()
-        related_url = '../../../%s/%s/' % (app_label, model_name)
+        related_url = reverse('admin:%s_%s_changelist' % (app_label, model_name))
+        if not self.search_path:
+            self.search_path = '%s/foreignkey_autocomplete/' % related_url
         params = self.url_parameters()
         if params:
             url = '?' + '&'.join(['%s=%s' % (k, v) for k, v in params.items()])
diff --git a/django_extensions/compat.py b/django_extensions/compat.py
index a820848..62e2259 100644
--- a/django_extensions/compat.py
+++ b/django_extensions/compat.py
@@ -1,9 +1,12 @@
+# coding=utf-8
 from __future__ import unicode_literals
 
 import sys
+from optparse import make_option
 import django
 from django.conf import settings
-from django.core.management.base import CommandError
+from django.core.management.base import (BaseCommand, AppCommand, LabelCommand,
+                                         CommandError)
 
 # flake8: noqa
 
@@ -194,3 +197,57 @@ def add_to_builtins_compat(name):
     else:
         from django.template import engines
         engines['django'].engine.builtins.append(name)
+
+
+def get_model(path):
+    if django.VERSION < (1, 7):
+        from django.db.models.loading import get_model
+        return get_model(*path.split('.', 1))
+    else:
+        from django.apps import apps
+        return apps.get_model(*path.split('.', 1))
+
+
+class ProxyParser(object):
+    """Faux parser object that will ferry our arguments into options."""
+
+    def __init__(self, command):
+        self.command = command
+
+    def add_argument(self, *args, **kwargs):
+        """Transform our argument into an option to append to self.option_list.
+
+        In argparse, "available specifiers [in help strings] include the
+        program name, %(prog)s and most keyword arguments to add_argument()".
+        However, optparse only mentions %default in the help string, and we
+        must alter the format to properly replace in optparse without error.
+        """
+        if 'help' in kwargs:
+            kwargs['help'] = kwargs['help'].replace('%(default)s', '%default')
+        self.command.option_list += (make_option(*args, **kwargs), )
+
+class CompatibilityBaseCommand(BaseCommand):
+    """Provides a compatibility between optparse and argparse transition.
+
+    Starting in Django 1.8, argparse is used. In Django 1.9, optparse support
+    will be removed.
+
+    For optparse, you append to the option_list class attribute.
+    For argparse, you must define add_arguments(self, parser).
+    BaseCommand uses the presence of option_list to decide what course to take.
+    """
+
+    def __init__(self, *args, **kwargs):
+        if django.VERSION < (1, 8) and hasattr(self, 'add_arguments'):
+            self.option_list = BaseCommand.option_list
+            parser = ProxyParser(self)
+            self.add_arguments(parser)
+        super(CompatibilityBaseCommand, self).__init__(*args, **kwargs)
+
+
+class CompatibilityAppCommand(AppCommand, CompatibilityBaseCommand):
+    """AppCommand is a BaseCommand sub-class without its own __init__."""
+
+
+class CompatibilityLabelCommand(LabelCommand, CompatibilityBaseCommand):
+    """LabelCommand is a BaseCommand sub-class without its own __init__."""
diff --git a/django_extensions/db/__init__.py b/django_extensions/db/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/db/__init__.py
+++ b/django_extensions/db/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/db/fields/__init__.py b/django_extensions/db/fields/__init__.py
index d48774d..a84ee36 100644
--- a/django_extensions/db/fields/__init__.py
+++ b/django_extensions/db/fields/__init__.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 Django Extensions additional model fields
 """
@@ -184,7 +185,7 @@ class AutoSlugField(UniqueFieldMixin, SlugField):
         return "SlugField"
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect the _actual_ field.
         from south.modelsinspector import introspector
         field_class = '%s.AutoSlugField' % self.__module__
@@ -196,7 +197,7 @@ class AutoSlugField(UniqueFieldMixin, SlugField):
             'allow_duplicates': repr(self.allow_duplicates),
         })
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(AutoSlugField, self).deconstruct()
@@ -295,7 +296,9 @@ class RandomCharField(UniqueFieldMixin, CharField):
 
         random_chars = self.random_char_generator(population)
         if not self.unique:
-            return random_chars
+            new = six.next(random_chars)
+            setattr(model_instance, self.attname, new)
+            return new
 
         return super(RandomCharField, self).find_unique(
             model_instance,
@@ -307,7 +310,7 @@ class RandomCharField(UniqueFieldMixin, CharField):
         return "CharField"
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect the _actual_ field.
         from south.modelsinspector import introspector
         field_class = '%s.RandomCharField' % self.__module__
@@ -322,7 +325,7 @@ class RandomCharField(UniqueFieldMixin, CharField):
         })
         del kwargs['max_length']
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(RandomCharField, self).deconstruct()
@@ -359,12 +362,12 @@ class CreationDateTimeField(DateTimeField):
         return "DateTimeField"
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect ourselves, since we inherit.
         from south.modelsinspector import introspector
         field_class = "django.db.models.fields.DateTimeField"
         args, kwargs = introspector(self)
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(CreationDateTimeField, self).deconstruct()
@@ -393,12 +396,12 @@ class ModificationDateTimeField(CreationDateTimeField):
         return "DateTimeField"
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect ourselves, since we inherit.
         from south.modelsinspector import introspector
         field_class = "django.db.models.fields.DateTimeField"
         args, kwargs = introspector(self)
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(ModificationDateTimeField, self).deconstruct()
@@ -406,6 +409,11 @@ class ModificationDateTimeField(CreationDateTimeField):
             kwargs['auto_now'] = True
         return name, path, args, kwargs
 
+    def pre_save(self, model_instance, add):
+        if not model_instance.update_modified:
+            return model_instance.modified
+        return super(ModificationDateTimeField, self).pre_save(model_instance, add)
+
 
 class UUIDVersionError(Exception):
     pass
@@ -471,13 +479,13 @@ class UUIDField(CharField):
         return super(UUIDField, self).formfield(**kwargs)
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect the _actual_ field.
         from south.modelsinspector import introspector
         field_class = "django.db.models.fields.CharField"
         args, kwargs = introspector(self)
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(UUIDField, self).deconstruct()
diff --git a/django_extensions/db/fields/encrypted.py b/django_extensions/db/fields/encrypted.py
index f013340..27dbe0b 100644
--- a/django_extensions/db/fields/encrypted.py
+++ b/django_extensions/db/fields/encrypted.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 import sys
 import warnings
 
@@ -119,13 +120,13 @@ class EncryptedTextField(six.with_metaclass(models.SubfieldBase,
         return super(EncryptedTextField, self).formfield(**defaults)
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect the _actual_ field.
         from south.modelsinspector import introspector
         field_class = "django.db.models.fields.TextField"
         args, kwargs = introspector(self)
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
 
 class EncryptedCharField(six.with_metaclass(models.SubfieldBase,
@@ -142,10 +143,10 @@ class EncryptedCharField(six.with_metaclass(models.SubfieldBase,
         return super(EncryptedCharField, self).formfield(**defaults)
 
     def south_field_triple(self):
-        "Returns a suitable description of this field for South."
+        """Returns a suitable description of this field for South."""
         # We'll just introspect the _actual_ field.
         from south.modelsinspector import introspector
         field_class = "django.db.models.fields.CharField"
         args, kwargs = introspector(self)
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
diff --git a/django_extensions/db/fields/json.py b/django_extensions/db/fields/json.py
index 89eece7..100df64 100644
--- a/django_extensions/db/fields/json.py
+++ b/django_extensions/db/fields/json.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 JSONField automatically serializes most Python terms to JSON data.
 Creates a TEXT field with a default value of "{}".  See test_json.py for
@@ -11,8 +12,6 @@ more information.
 """
 from __future__ import absolute_import
 
-from decimal import Decimal
-
 import six
 from django.conf import settings
 from django.core.serializers.json import DjangoJSONEncoder
@@ -33,7 +32,6 @@ def dumps(value):
 def loads(txt):
     value = json.loads(
         txt,
-        parse_float=Decimal,
         encoding=settings.DEFAULT_CHARSET
     )
     return value
@@ -92,6 +90,10 @@ class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)):
         else:
             return value
 
+    def get_prep_value(self, value):
+        """Do not call `to_python` method."""
+        return super(models.TextField, self).get_prep_value(value)
+
     def get_db_prep_save(self, value, connection, **kwargs):
         """Convert our JSON object to a string before we save"""
         if value is None and self.null:
@@ -100,7 +102,8 @@ class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)):
         # run through `dumps`
         if not isinstance(value, six.string_types):
             value = dumps(value)
-        return super(JSONField, self).get_db_prep_save(value, connection=connection, **kwargs)
+
+        return value
 
     def south_field_triple(self):
         """Returns a suitable description of this field for South."""
@@ -109,7 +112,7 @@ class JSONField(six.with_metaclass(models.SubfieldBase, models.TextField)):
         field_class = "django.db.models.fields.TextField"
         args, kwargs = introspector(self)
         # That's our definition!
-        return (field_class, args, kwargs)
+        return field_class, args, kwargs
 
     def deconstruct(self):
         name, path, args, kwargs = super(JSONField, self).deconstruct()
diff --git a/django_extensions/db/models.py b/django_extensions/db/models.py
index 4fcd3c4..01d7317 100644
--- a/django_extensions/db/models.py
+++ b/django_extensions/db/models.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 Django Extensions abstract base model classes.
 """
@@ -24,6 +25,10 @@ class TimeStampedModel(models.Model):
     created = CreationDateTimeField(_('created'))
     modified = ModificationDateTimeField(_('modified'))
 
+    def save(self, **kwargs):
+        self.update_modified = kwargs.pop('update_modified', getattr(self, 'update_modified', True))
+        super(TimeStampedModel, self).save(**kwargs)
+
     class Meta:
         get_latest_by = 'modified'
         ordering = ('-modified', '-created',)
diff --git a/django_extensions/jobs/__init__.py b/django_extensions/jobs/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/__init__.py
+++ b/django_extensions/jobs/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/daily/__init__.py b/django_extensions/jobs/daily/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/daily/__init__.py
+++ b/django_extensions/jobs/daily/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/daily/cache_cleanup.py b/django_extensions/jobs/daily/cache_cleanup.py
index 5ec0bc0..ddb9d8d 100644
--- a/django_extensions/jobs/daily/cache_cleanup.py
+++ b/django_extensions/jobs/daily/cache_cleanup.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 Daily cleanup job.
 
diff --git a/django_extensions/jobs/daily/daily_cleanup.py b/django_extensions/jobs/daily/daily_cleanup.py
index 614e9ec..006656f 100644
--- a/django_extensions/jobs/daily/daily_cleanup.py
+++ b/django_extensions/jobs/daily/daily_cleanup.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 Daily cleanup job.
 
diff --git a/django_extensions/jobs/hourly/__init__.py b/django_extensions/jobs/hourly/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/hourly/__init__.py
+++ b/django_extensions/jobs/hourly/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/minutely/__init__.py b/django_extensions/jobs/minutely/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/minutely/__init__.py
+++ b/django_extensions/jobs/minutely/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/monthly/__init__.py b/django_extensions/jobs/monthly/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/monthly/__init__.py
+++ b/django_extensions/jobs/monthly/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/weekly/__init__.py b/django_extensions/jobs/weekly/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/weekly/__init__.py
+++ b/django_extensions/jobs/weekly/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/jobs/yearly/__init__.py b/django_extensions/jobs/yearly/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/jobs/yearly/__init__.py
+++ b/django_extensions/jobs/yearly/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/logging/__init__.py b/django_extensions/logging/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/logging/__init__.py
+++ b/django_extensions/logging/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/logging/filters.py b/django_extensions/logging/filters.py
index 8fb039b..531d317 100644
--- a/django_extensions/logging/filters.py
+++ b/django_extensions/logging/filters.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 import time
 import logging
 from hashlib import md5
diff --git a/django_extensions/management/__init__.py b/django_extensions/management/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/management/__init__.py
+++ b/django_extensions/management/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/management/base.py b/django_extensions/management/base.py
index a558b02..c163267 100644
--- a/django_extensions/management/base.py
+++ b/django_extensions/management/base.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 import sys
 
 from django.core.management.base import BaseCommand
diff --git a/django_extensions/management/color.py b/django_extensions/management/color.py
index 26ea7fc..0fc3098 100644
--- a/django_extensions/management/color.py
+++ b/django_extensions/management/color.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 """
 Sets up the terminal color scheme.
 """
diff --git a/django_extensions/management/commands/__init__.py b/django_extensions/management/commands/__init__.py
index e69de29..9bad579 100644
--- a/django_extensions/management/commands/__init__.py
+++ b/django_extensions/management/commands/__init__.py
@@ -0,0 +1 @@
+# coding=utf-8
diff --git a/django_extensions/management/commands/admin_generator.py b/django_extensions/management/commands/admin_generator.py
index ed89f63..c566f2a 100644
--- a/django_extensions/management/commands/admin_generator.py
+++ b/django_extensions/management/commands/admin_generator.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-'''
+"""
 The Django Admin Generator is a project which can automatically generate
 (scaffold) a Django Admin for you. By doing this it will introspect your
 models and automatically generate an Admin with properties like:
@@ -13,19 +13,18 @@ models and automatically generate an Admin with properties like:
 
 The original source and latest version can be found here:
 https://github.com/WoLpH/django-admin-generator/
-'''
+"""
 
-import optparse
 import re
 import sys
 
... 4493 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django-extensions.git



More information about the Python-modules-commits mailing list