From 8e821f5ca1ab83b28ad61f86287b62721f69b35f Mon Sep 17 00:00:00 2001 From: sbussetti Date: Tue, 14 Oct 2014 15:28:11 -0400 Subject: [PATCH 01/14] django 1.6+ compat --- admincommand/admin.py | 12 ++++++------ example/urls.py | 5 ++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/admincommand/admin.py b/admincommand/admin.py index 5d124a7..7de3ea7 100644 --- a/admincommand/admin.py +++ b/admincommand/admin.py @@ -2,12 +2,12 @@ from django.contrib import admin from django.shortcuts import render from django.contrib.admin.options import csrf_protect_m -from django.http import HttpResponse, HttpResponseRedirect -from django.shortcuts import redirect -from django.conf.urls.defaults import url +from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse -from django.http import HttpResponseBadRequest -from django.conf.urls.defaults import patterns +try: + from django.conf.urls import url, patterns +except ImportError: + from django.conf.urls.defaults import url, patterns from django.utils.encoding import force_unicode from django.utils.functional import update_wrapper from django.http import HttpResponseForbidden @@ -27,7 +27,7 @@ class AdminCommandAdmin(SneakAdmin): def queryset(self, request): # user current user to construct the queryset - # so that only commands the user can execute + # so that only commands the user can execute # will be visible return CommandQuerySet(request.user) diff --git a/example/urls.py b/example/urls.py index faf7e29..a36b9ed 100644 --- a/example/urls.py +++ b/example/urls.py @@ -1,4 +1,7 @@ -from django.conf.urls.defaults import patterns, include, url +try: + from django.conf.urls import url, patterns, include +except ImportError: + from django.conf.urls.defaults import url, patterns, include # Uncomment the next two lines to enable the admin: from django.contrib import admin From 6ff12e48a30dd8a65a2364f9c0ba51a8032f35bf Mon Sep 17 00:00:00 2001 From: sbussetti Date: Tue, 14 Oct 2014 15:30:40 -0400 Subject: [PATCH 02/14] django 1.6+ compat --- admincommand/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/admincommand/admin.py b/admincommand/admin.py index 7de3ea7..cb0274b 100644 --- a/admincommand/admin.py +++ b/admincommand/admin.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from functools import update_wrapper + from django.contrib import admin from django.shortcuts import render from django.contrib.admin.options import csrf_protect_m @@ -9,7 +11,6 @@ except ImportError: from django.conf.urls.defaults import url, patterns from django.utils.encoding import force_unicode -from django.utils.functional import update_wrapper from django.http import HttpResponseForbidden from django.utils.safestring import mark_safe from django.contrib import messages From c1666346674a264f49428f8527e09a336c65582c Mon Sep 17 00:00:00 2001 From: sbussetti Date: Thu, 4 Dec 2014 11:39:42 -0500 Subject: [PATCH 03/14] fixed packaging --- .gitignore | 6 +++++- MANIFEST.in | 3 +++ setup.py | 9 ++++----- 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 MANIFEST.in diff --git a/.gitignore b/.gitignore index 3afb01e..0d8962c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ *.pyc *~ -example/db.sqlite \ No newline at end of file +example/db.sqlite +django_admincommand.egg-info +.ropeproject +build/ +dist/ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..0f46a76 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include README.rst + +recursive-include admincommand/templates * diff --git a/setup.py b/setup.py index 7b8c72b..8178b3f 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python import os -from distutils.core import setup +from setuptools import setup, find_packages def read(fname): @@ -15,8 +15,7 @@ def read(fname): author='Djaz Team', author_email='devweb@liberation.fr', url='https://github.com/liberation/django-admincommand', - packages=['admincommand'], - data_files=[('admincommand/templates/admincommand', [ - 'admincommand/templates/admincommand/output.html', - 'admincommand/templates/admincommand/run.html'])] + packages=find_packages(), + include_package_data=True, + zip_safe=False ) From d5f2ef8c627e58a3bf42c256453b173f45ebed3d Mon Sep 17 00:00:00 2001 From: sbussetti Date: Thu, 16 Apr 2015 17:50:08 -0400 Subject: [PATCH 04/14] 1.8+ compat --- admincommand/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admincommand/admin.py b/admincommand/admin.py index cb0274b..e9abf13 100644 --- a/admincommand/admin.py +++ b/admincommand/admin.py @@ -26,7 +26,7 @@ class AdminCommandAdmin(SneakAdmin): list_display = ('command_name',) - def queryset(self, request): + def get_queryset(self, request): # user current user to construct the queryset # so that only commands the user can execute # will be visible From ceed10d36cbb47e04ec62e91d0b2a1e863f1f120 Mon Sep 17 00:00:00 2001 From: sbussetti Date: Thu, 10 Sep 2015 13:58:44 -0400 Subject: [PATCH 05/14] adding Django 1.7 + migrations --- admincommand/migrations/0001_initial.py | 22 ++++++++++++++++++++++ admincommand/migrations/__init__.py | 0 2 files changed, 22 insertions(+) create mode 100644 admincommand/migrations/0001_initial.py create mode 100644 admincommand/migrations/__init__.py diff --git a/admincommand/migrations/0001_initial.py b/admincommand/migrations/0001_initial.py new file mode 100644 index 0000000..400c509 --- /dev/null +++ b/admincommand/migrations/0001_initial.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='AdminCommand', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/admincommand/migrations/__init__.py b/admincommand/migrations/__init__.py new file mode 100644 index 0000000..e69de29 From 941b08a049e61a6b76d188440a6e4a98dfd4810d Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Fri, 28 Apr 2017 19:00:10 -0700 Subject: [PATCH 06/14] Fixed broken import --- admincommand/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/admincommand/core.py b/admincommand/core.py index 568d993..f1eab10 100644 --- a/admincommand/core.py +++ b/admincommand/core.py @@ -1,10 +1,11 @@ from StringIO import StringIO +from importlib import import_module + from django.conf import settings from django.core import management from django.core.management import get_commands from django.core.management import load_command_class -from django.utils.importlib import import_module from django.core.management.base import BaseCommand from django.contrib.auth.models import User from async import schedule From 2184b57e62e917d9dfc6a02247abbd6ab931f0c6 Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Fri, 28 Apr 2017 19:00:17 -0700 Subject: [PATCH 07/14] Changed french button --- admincommand/templates/admincommand/run.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admincommand/templates/admincommand/run.html b/admincommand/templates/admincommand/run.html index c2c8dbf..3d3e008 100644 --- a/admincommand/templates/admincommand/run.html +++ b/admincommand/templates/admincommand/run.html @@ -22,6 +22,6 @@

{{ help }}

{% csrf_token %} {{ form.as_ul }} - +
{% endblock %} From 20b7d1348dfb26672b9d44b97a30156b1786955d Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Fri, 28 Apr 2017 19:02:38 -0700 Subject: [PATCH 08/14] Updated readme --- README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index e2ac7dc..d00036d 100644 --- a/README.rst +++ b/README.rst @@ -46,7 +46,7 @@ Then you will have to create a configuration class for the command:: # ./music/admincommands.py - from admincommands.models import AdminCommand + from admincommand.models import AdminCommand class Lyrics(AdminCommand): @@ -57,6 +57,8 @@ Then you will have to create a configuration class for the command:: def get_command_arguments(self, forms_data): return [forms_data['title']], {} +*NOTE*: This all works based on naming conventions. The file with the form must be called `admincommands` and the form class name must be the same as the management command file name (with camel case converted to underscore notation). + And all is well, the new admin command will be available under the «Admin Command» area of the administration of the default admin site. From c71590c50b48cda3e4c988af8784c9d386627b8a Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Fri, 28 Apr 2017 19:31:13 -0700 Subject: [PATCH 09/14] Now passing user object to command generators --- admincommand/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admincommand/core.py b/admincommand/core.py index f1eab10..49e031b 100644 --- a/admincommand/core.py +++ b/admincommand/core.py @@ -60,7 +60,7 @@ def call_command(command_name, user_pk, args=None, kwargs=None): def run_command(command_config, cleaned_data, user): if hasattr(command_config, 'get_command_arguments'): - args, kwargs = command_config.get_command_arguments(cleaned_data) + args, kwargs = command_config.get_command_arguments(cleaned_data, user) else: args, kwargs = list(), dict() if command_config.asynchronous: From e8b53841b0debfc01812771455717b9e99bd55a4 Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Fri, 28 Apr 2017 23:48:25 -0700 Subject: [PATCH 10/14] Fixed another case of broken imports --- admincommand/management.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/admincommand/management.py b/admincommand/management.py index 3e4d8f0..b9e5da6 100644 --- a/admincommand/management.py +++ b/admincommand/management.py @@ -1,8 +1,9 @@ +from importlib import import_module + from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import Permission from django.db.models import signals -from django.utils.importlib import import_module import admincommand From ccd048dceb1fe629d5037d16fe7d562fbc81718f Mon Sep 17 00:00:00 2001 From: Ben Holmes Date: Sat, 29 Apr 2017 02:59:14 -0700 Subject: [PATCH 11/14] Fixed change of method name in Django > 1.6 --- admincommand/management.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/admincommand/management.py b/admincommand/management.py index b9e5da6..725d7b7 100644 --- a/admincommand/management.py +++ b/admincommand/management.py @@ -1,5 +1,6 @@ from importlib import import_module +import django from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.contrib.auth.models import Permission @@ -32,4 +33,8 @@ def sync_db_callback(verbosity=0, interactive=False, signal=None, **kwargs): content_type=ct, name='Can run %s' % subclass.command_name(), ) -signals.post_syncdb.connect(sync_db_callback, sender=admincommand.models) + +if django.VERSION >= (1, 7): + signals.post_migrate.connect(sync_db_callback, sender=admincommand.models) +else: + signals.post_syncdb.connect(sync_db_callback, sender=admincommand.models) From a3f82c7f0c674a4ebe8b51b21d4c9371249ca3ae Mon Sep 17 00:00:00 2001 From: Martin Gaitan Date: Fri, 11 Aug 2017 11:45:37 -0300 Subject: [PATCH 12/14] update example with recent django project layout --- example/admincommand | 1 - example/{ => example}/__init__.py | 0 example/example/settings.py | 123 +++++++++++++++ example/example/urls.py | 21 +++ example/example/wsgi.py | 16 ++ example/exampleapp/admin.py | 3 + example/exampleapp/admincommands.py | 4 +- example/exampleapp/apps.py | 5 + .../management/commands/fibonnaci.py | 10 +- example/exampleapp/management/commands/pi.py | 8 +- example/exampleapp/migrations/__init__.py | 0 example/exampleapp/tests.py | 15 +- example/manage.py | 33 ++-- example/settings.py | 148 ------------------ example/urls.py | 20 --- 15 files changed, 203 insertions(+), 204 deletions(-) delete mode 120000 example/admincommand rename example/{ => example}/__init__.py (100%) create mode 100644 example/example/settings.py create mode 100644 example/example/urls.py create mode 100644 example/example/wsgi.py create mode 100644 example/exampleapp/admin.py create mode 100644 example/exampleapp/apps.py create mode 100644 example/exampleapp/migrations/__init__.py delete mode 100644 example/settings.py delete mode 100644 example/urls.py diff --git a/example/admincommand b/example/admincommand deleted file mode 120000 index 65e0f6b..0000000 --- a/example/admincommand +++ /dev/null @@ -1 +0,0 @@ -../admincommand \ No newline at end of file diff --git a/example/__init__.py b/example/example/__init__.py similarity index 100% rename from example/__init__.py rename to example/example/__init__.py diff --git a/example/example/settings.py b/example/example/settings.py new file mode 100644 index 0000000..bc963c9 --- /dev/null +++ b/example/example/settings.py @@ -0,0 +1,123 @@ +""" +Django settings for example project. + +Generated by 'django-admin startproject' using Django 1.11.3. + +For more information on this file, see +https://docs.djangoproject.com/en/1.11/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.11/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '!5os-5fccaf-c)c#&&(z1h@=n9i@!jbm4k*f^3$9ps&%fc9fga' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'admincommand', + 'exampleapp', + 'async', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'example.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'example.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.11/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/1.11/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.11/howto/static-files/ + +STATIC_URL = '/static/' diff --git a/example/example/urls.py b/example/example/urls.py new file mode 100644 index 0000000..0988fcb --- /dev/null +++ b/example/example/urls.py @@ -0,0 +1,21 @@ +"""example URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.11/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.conf.urls import url, include + 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) +""" +from django.conf.urls import url +from django.contrib import admin + +urlpatterns = [ + url(r'^admin/', admin.site.urls), +] diff --git a/example/example/wsgi.py b/example/example/wsgi.py new file mode 100644 index 0000000..c33c08a --- /dev/null +++ b/example/example/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for example project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") + +application = get_wsgi_application() diff --git a/example/exampleapp/admin.py b/example/exampleapp/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/example/exampleapp/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/example/exampleapp/admincommands.py b/example/exampleapp/admincommands.py index 8fdc64a..4cef293 100644 --- a/example/exampleapp/admincommands.py +++ b/example/exampleapp/admincommands.py @@ -8,7 +8,7 @@ class Fibonnaci(AdminCommand): class form(forms.Form): x = forms.IntegerField() - def get_command_arguments(self, forms_data): + def get_command_arguments(self, forms_data, user): return [forms_data['x']], {} @@ -19,5 +19,5 @@ class Pi(AdminCommand): class form(forms.Form): digits = forms.IntegerField() - def get_command_arguments(self, forms_data): + def get_command_arguments(self, forms_data, user): return [forms_data['digits']], {} diff --git a/example/exampleapp/apps.py b/example/exampleapp/apps.py new file mode 100644 index 0000000..fd64821 --- /dev/null +++ b/example/exampleapp/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ExampleappConfig(AppConfig): + name = 'exampleapp' diff --git a/example/exampleapp/management/commands/fibonnaci.py b/example/exampleapp/management/commands/fibonnaci.py index 8d8748b..0f42dd7 100644 --- a/example/exampleapp/management/commands/fibonnaci.py +++ b/example/exampleapp/management/commands/fibonnaci.py @@ -12,6 +12,12 @@ def fibonnaci(x): class Command(BaseCommand): help = "Compute fibonnaci number" + + def add_arguments(self, parser): + parser.add_argument('argument') + + def handle(self, *args, **options): - r = fibonnaci(int(args[0])) - self.stdout.write('fibonnaci(%s) = %s' % (args[0],r)) + arg = options['argument'] + r = fibonnaci(int(arg)) + self.stdout.write('fibonnaci(%s) = %s' % (arg, r)) diff --git a/example/exampleapp/management/commands/pi.py b/example/exampleapp/management/commands/pi.py index 9cee060..75e05d1 100644 --- a/example/exampleapp/management/commands/pi.py +++ b/example/exampleapp/management/commands/pi.py @@ -26,7 +26,11 @@ def pi(digits): class Command(BaseCommand): help = "Compute pi number" + def add_arguments(self, parser): + parser.add_argument('argument') + def handle(self, *args, **options): - r = str(pi(int(args[0]))) + arg = options['argument'] + r = str(pi(int(arg))) r = r[0] + '.' + r[1:] - self.stdout.write('pi(%s) = %s' % (args[0],r)) + self.stdout.write('pi(%s) = %s' % (arg,r)) diff --git a/example/exampleapp/migrations/__init__.py b/example/exampleapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/example/exampleapp/tests.py b/example/exampleapp/tests.py index 501deb7..7ce503c 100644 --- a/example/exampleapp/tests.py +++ b/example/exampleapp/tests.py @@ -1,16 +1,3 @@ -""" -This file demonstrates writing tests using the unittest module. These will pass -when you run "manage.py test". - -Replace this with more appropriate tests for your application. -""" - from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.assertEqual(1 + 1, 2) +# Create your tests here. diff --git a/example/manage.py b/example/manage.py index 10cc16e..72c4bb0 100755 --- a/example/manage.py +++ b/example/manage.py @@ -1,19 +1,22 @@ #!/usr/bin/env python -import sys import os -from django.core.management import execute_manager - -sys.path.insert(0, os.path.dirname(__file__)) - -import imp -try: - imp.find_module('settings') # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) - sys.exit(1) - -import settings +import sys if __name__ == "__main__": - execute_manager(settings) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings") + try: + from django.core.management import execute_from_command_line + except ImportError: + # The above import may fail for some other reason. Ensure that the + # issue is really that Django is missing to avoid masking other + # exceptions on Python 2. + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) + raise + execute_from_command_line(sys.argv) diff --git a/example/settings.py b/example/settings.py deleted file mode 100644 index 522f14b..0000000 --- a/example/settings.py +++ /dev/null @@ -1,148 +0,0 @@ -# Django settings for example_project project. - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@example.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'db.sqlite', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute filesystem path to the directory that will hold user-uploaded files. -# Example: "/home/media/media.lawrence.com/media/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash. -# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" -MEDIA_URL = '' - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = '' - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = '/static/' - -# URL prefix for admin static files -- CSS, JavaScript and images. -# Make sure to use a trailing slash. -# Examples: "http://foo.com/static/admin/", "/static/admin/". -ADMIN_MEDIA_PREFIX = '/static/admin/' - -# Additional locations of static files -STATICFILES_DIRS = ( - # Put strings here, like "/home/html/static" or "C:/www/django/static". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) - -# Make this unique, and don't share it with anybody. -SECRET_KEY = '4aw$kmj_8ti8@0c3!z1$umqz4-@(9$(#85(8%d%f60fme#m=%7' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', -) - -ROOT_URLCONF = 'example.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.messages', - 'django.contrib.staticfiles', - # Uncomment the next line to enable the admin: - 'django.contrib.admin', - 'admincommand', - 'exampleapp', - 'async', - # Uncomment the next line to enable admin documentation: - # 'django.contrib.admindocs', -) - -# A sample logging configuration. The only tangible logging -# performed by this configuration is to send an email to -# the site admins on every HTTP 500 error. -# See http://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler' - } - }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': True, - }, - } -} diff --git a/example/urls.py b/example/urls.py deleted file mode 100644 index a36b9ed..0000000 --- a/example/urls.py +++ /dev/null @@ -1,20 +0,0 @@ -try: - from django.conf.urls import url, patterns, include -except ImportError: - from django.conf.urls.defaults import url, patterns, include - -# Uncomment the next two lines to enable the admin: -from django.contrib import admin -admin.autodiscover() - -urlpatterns = patterns('', - # Examples: - # url(r'^$', 'example_project.views.home', name='home'), - # url(r'^example_project/', include('example_project.foo.urls')), - - # Uncomment the admin/doc line below to enable admin documentation: - # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), - - # Uncomment the next line to enable the admin: - url(r'^admin/', include(admin.site.urls)), -) From d13be1d5c670490c789201db8cf82a4a43769fde Mon Sep 17 00:00:00 2001 From: Martin Gaitan Date: Fri, 11 Aug 2017 11:46:04 -0300 Subject: [PATCH 13/14] add compatibility with django 1.11 --- admincommand/admin.py | 14 +++++--------- admincommand/core.py | 13 ++++++++++--- admincommand/models.py | 4 ++-- admincommand/templates/admincommand/output.html | 6 +----- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/admincommand/admin.py b/admincommand/admin.py index e9abf13..34d75e8 100644 --- a/admincommand/admin.py +++ b/admincommand/admin.py @@ -6,11 +6,8 @@ from django.contrib.admin.options import csrf_protect_m from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse -try: - from django.conf.urls import url, patterns -except ImportError: - from django.conf.urls.defaults import url, patterns -from django.utils.encoding import force_unicode +from django.conf.urls import url +from django.utils.encoding import force_text from django.http import HttpResponseForbidden from django.utils.safestring import mark_safe from django.contrib import messages @@ -38,13 +35,12 @@ def wrapper(*args, **kwargs): return self.admin_site.admin_view(view)(*args, **kwargs) return update_wrapper(wrapper, view) - urlpatterns = patterns( - '', + urlpatterns = [ url( r'^run/([\w_]+)', wrap(self.run_command_view), ) - ) + ] return urlpatterns + super(AdminCommandAdmin, self).get_urls() def run_command_view(self, request, url_name): @@ -61,7 +57,7 @@ def run_command_view(self, request, url_name): ctx = { # original needed ``change_form.html`` context variables - 'module_name': force_unicode(opts.verbose_name_plural), + 'module_name': force_text(opts.verbose_name_plural), 'title': admin_command.name(), 'is_popup': False, 'root_path': None, diff --git a/admincommand/core.py b/admincommand/core.py index 49e031b..0940d0b 100644 --- a/admincommand/core.py +++ b/admincommand/core.py @@ -1,4 +1,4 @@ -from StringIO import StringIO +from six import StringIO from importlib import import_module @@ -8,12 +8,15 @@ from django.core.management import load_command_class from django.core.management.base import BaseCommand from django.contrib.auth.models import User -from async import schedule +try: + from async import schedule +except ImportError: + schedule = None from admincommand.models import AdminCommand -# Cache variable to store runnable commands configuration +# Cache variable to store runnable commands configuration _command_configs = {} @@ -58,17 +61,21 @@ def call_command(command_name, user_pk, args=None, kwargs=None): management.call_command(command_name, *args, **kwargs) return output.getvalue() + def run_command(command_config, cleaned_data, user): if hasattr(command_config, 'get_command_arguments'): args, kwargs = command_config.get_command_arguments(cleaned_data, user) else: args, kwargs = list(), dict() if command_config.asynchronous: + if not callable(schedule): + return 'This task is asynchronous but django-async is not installed' task = schedule(call_command, [command_config.command_name(), user.pk, args, kwargs]) return task else: # Change stdout to a StringIO to be able to retrieve output and # display it to the user + import ipdb; ipdb.set_trace() output = StringIO() kwargs['stdout'] = output management.call_command(command_config.command_name(), *args, **kwargs) diff --git a/admincommand/models.py b/admincommand/models.py index 50443b3..1d5e765 100644 --- a/admincommand/models.py +++ b/admincommand/models.py @@ -33,7 +33,7 @@ def get_help(self): def command(self): """Getter of the management command import core""" - import core + from . import core command = core.get_command(self.command_name()) return command @@ -53,6 +53,6 @@ def permission_codename(cls): @classmethod def all(cls): - import core + from . import core for runnable_command in core.get_admin_commands().values(): yield runnable_command diff --git a/admincommand/templates/admincommand/output.html b/admincommand/templates/admincommand/output.html index 8f350dc..f91507e 100644 --- a/admincommand/templates/admincommand/output.html +++ b/admincommand/templates/admincommand/output.html @@ -1,11 +1,7 @@ {% extends "admin/change_form.html" %} -{% load i18n %} -{% block extrahead %} - {{ block.super }} - -{% endblock %} +{% load i18n %} {% block breadcrumbs %}