From b341d763f0eb0ace99a00c6582241a0ad13c2cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Ga=C5=82uszka?= Date: Mon, 22 Sep 2014 04:14:02 +0200 Subject: [PATCH] many fixes to django-admin2 with py3 and django 1.7 compatybility --- .travis.yml | 5 +- djadmin2/actions.py | 2 +- djadmin2/core.py | 10 +- djadmin2/permissions.py | 6 +- djadmin2/tests/__init__.py | 8 - djadmin2/tests/test_core.py | 20 +- djadmin2/tests/test_types.py | 4 +- djadmin2/types.py | 2 +- djadmin2/utils.py | 5 +- djadmin2/views.py | 29 ++- example/blog/tests/__init__.py | 11 - example/blog/tests/test_apiviews.py | 2 +- example/blog/tests/test_filters.py | 1 - example/example/settings.py | 24 +-- example/files/tests/__init__.py | 2 - example/{ => polls}/__init__.py | 0 {example2 => example}/polls/admin.py | 0 {example2 => example}/polls/admin2.py | 0 .../polls/locale/de/LC_MESSAGES/django.mo | Bin .../polls/locale/de/LC_MESSAGES/django.po | 0 .../polls/locale/en/LC_MESSAGES/django.mo | Bin .../polls/locale/en/LC_MESSAGES/django.po | 0 .../polls/locale/fr/LC_MESSAGES/django.mo | Bin .../polls/locale/fr/LC_MESSAGES/django.po | 0 .../polls/locale/it/LC_MESSAGES/django.mo | Bin .../polls/locale/it/LC_MESSAGES/django.po | 0 .../polls/locale/nl/LC_MESSAGES/django.mo | Bin .../polls/locale/nl/LC_MESSAGES/django.po | 0 .../polls/locale/pl_PL/LC_MESSAGES/django.mo | Bin .../polls/locale/pl_PL/LC_MESSAGES/django.po | 0 .../polls/locale/pt_BR/LC_MESSAGES/django.mo | Bin .../polls/locale/pt_BR/LC_MESSAGES/django.po | 0 .../polls/locale/sk/LC_MESSAGES/django.mo | Bin .../polls/locale/sk/LC_MESSAGES/django.po | 0 .../polls/locale/tl_PH/LC_MESSAGES/django.mo | Bin .../polls/locale/tl_PH/LC_MESSAGES/django.po | 0 .../polls/locale/zh/LC_MESSAGES/django.mo | Bin .../polls/locale/zh/LC_MESSAGES/django.po | 0 {example2 => example}/polls/models.py | 0 .../polls/templates/home.html | 0 {example2 => example}/polls/tests/__init__.py | 0 .../polls/tests/test_models.py | 0 .../polls/tests/test_views.py | 2 +- {example2 => example}/polls/views.py | 0 example2/example2/__init__.py | 0 example2/example2/settings.py | 188 ------------------ example2/example2/urls.py | 15 -- example2/example2/wsgi.py | 32 --- example2/manage.py | 10 - example2/polls/__init__.py | 0 requirements.txt | 10 - runtests.py | 45 ----- setup.py | 33 ++- tox.ini | 29 +-- 54 files changed, 94 insertions(+), 401 deletions(-) rename example/{ => polls}/__init__.py (100%) rename {example2 => example}/polls/admin.py (100%) rename {example2 => example}/polls/admin2.py (100%) rename {example2 => example}/polls/locale/de/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/de/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/en/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/en/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/fr/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/fr/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/it/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/it/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/nl/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/nl/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/pl_PL/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/pl_PL/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/pt_BR/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/pt_BR/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/sk/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/sk/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/tl_PH/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/tl_PH/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/locale/zh/LC_MESSAGES/django.mo (100%) rename {example2 => example}/polls/locale/zh/LC_MESSAGES/django.po (100%) rename {example2 => example}/polls/models.py (100%) rename {example2 => example}/polls/templates/home.html (100%) rename {example2 => example}/polls/tests/__init__.py (100%) rename {example2 => example}/polls/tests/test_models.py (100%) rename {example2 => example}/polls/tests/test_views.py (98%) rename {example2 => example}/polls/views.py (100%) delete mode 100644 example2/example2/__init__.py delete mode 100644 example2/example2/settings.py delete mode 100644 example2/example2/urls.py delete mode 100644 example2/example2/wsgi.py delete mode 100755 example2/manage.py delete mode 100644 example2/polls/__init__.py delete mode 100644 requirements.txt delete mode 100755 runtests.py diff --git a/.travis.yml b/.travis.yml index 340effd..b08c34d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: python python: "2.7" env: matrix: - - TOX_ENV=py27-dj1.4.x - - TOX_ENV=py27-dj1.5.x - TOX_ENV=py27-dj1.6.x - TOX_ENV=py27-dj1.7.x - TOX_ENV=py33-dj1.6.x @@ -16,7 +14,8 @@ install: - pip install tox script: - tox -e $TOX_ENV -#for now commented +# for now commented. We have to figure which version use for coverage +# and coveralls #after_success: # - coverage report # - pip install --quiet python-coveralls diff --git a/djadmin2/actions.py b/djadmin2/actions.py index d63848c..edf5c39 100644 --- a/djadmin2/actions.py +++ b/djadmin2/actions.py @@ -49,7 +49,7 @@ class BaseListAction(AdminModel2Mixin, TemplateView): objects_name = options.verbose_name else: objects_name = options.verbose_name_plural - self.objects_name = unicode(objects_name) + self.objects_name = force_text(objects_name) super(BaseListAction, self).__init__(*args, **kwargs) diff --git a/djadmin2/core.py b/djadmin2/core.py index 35ff81e..9774995 100644 --- a/djadmin2/core.py +++ b/djadmin2/core.py @@ -8,7 +8,8 @@ from __future__ import division, absolute_import, unicode_literals from django.conf.urls import patterns, include, url from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils.importlib import import_module + +from importlib import import_module from . import apiviews @@ -122,7 +123,9 @@ class Admin2(object): try: import_module("%s.admin2" % app_name) except ImportError as e: - if str(e) == "No module named admin2": + + if str(e) == "No module named admin2" \ + or str(e) == "No module named '%s.admin2'" % (app_name): continue raise e @@ -188,7 +191,7 @@ class Admin2(object): name='api_index' ), ) - for model, model_admin in self.registry.iteritems(): + for model, model_admin in self.registry.items(): model_options = utils.model_options(model) urlpatterns += patterns( '', @@ -207,3 +210,4 @@ class Admin2(object): def urls(self): # We set the application and instance namespace here return self.get_urls(), self.name, self.name + diff --git a/djadmin2/permissions.py b/djadmin2/permissions.py index 4c4d4c8..9e11a75 100644 --- a/djadmin2/permissions.py +++ b/djadmin2/permissions.py @@ -26,6 +26,7 @@ from django.db.models import get_models from django.utils import six from . import utils +from django.utils.encoding import python_2_unicode_compatible, force_text logger = logging.getLogger('djadmin2') @@ -185,6 +186,7 @@ class ModelDeletePermission(BasePermission): permissions = (model_permission('{app_label}.delete_{model_name}'),) +@python_2_unicode_compatible class TemplatePermissionChecker(object): ''' Can be used in the template like: @@ -349,10 +351,10 @@ class TemplatePermissionChecker(object): else: return self._view.has_permission(self._obj) - def __unicode__(self): + def __str__(self): if self._view is None: return '' - return unicode(bool(self)) + return force_text(bool(self)) def create_view_permissions(app, created_models, verbosity, **kwargs): diff --git a/djadmin2/tests/__init__.py b/djadmin2/tests/__init__.py index f0a8411..e69de29 100644 --- a/djadmin2/tests/__init__.py +++ b/djadmin2/tests/__init__.py @@ -1,8 +0,0 @@ -from test_admin2tags import * -from test_types import * -from test_utils import * -from test_views import * -from test_core import * -from test_actions import * -from test_auth_admin import * -from test_renderers import * diff --git a/djadmin2/tests/test_core.py b/djadmin2/tests/test_core.py index ab97c86..fe091cd 100644 --- a/djadmin2/tests/test_core.py +++ b/djadmin2/tests/test_core.py @@ -9,7 +9,7 @@ from ..types import ModelAdmin2 from ..core import Admin2 -class Thing(models.Model): +class SmallThing(models.Model): pass @@ -21,20 +21,20 @@ class Admin2Test(TestCase): self.admin2 = Admin2() def test_register(self): - self.admin2.register(Thing) - self.assertTrue(isinstance(self.admin2.registry[Thing], ModelAdmin2)) + self.admin2.register(SmallThing) + self.assertTrue(isinstance(self.admin2.registry[SmallThing], ModelAdmin2)) def test_register_error(self): - self.admin2.register(Thing) - self.assertRaises(ImproperlyConfigured, self.admin2.register, Thing) + self.admin2.register(SmallThing) + self.assertRaises(ImproperlyConfigured, self.admin2.register, SmallThing) def test_deregister(self): - self.admin2.register(Thing) - self.admin2.deregister(Thing) - self.assertTrue(Thing not in self.admin2.registry) + self.admin2.register(SmallThing) + self.admin2.deregister(SmallThing) + self.assertTrue(SmallThing not in self.admin2.registry) def test_deregister_error(self): - self.assertRaises(ImproperlyConfigured, self.admin2.deregister, Thing) + self.assertRaises(ImproperlyConfigured, self.admin2.deregister, SmallThing) def test_register_app_verbose_name(self): self.admin2.register_app_verbose_name(APP_LABEL, APP_VERBOSE_NAME) @@ -65,7 +65,7 @@ class Admin2Test(TestCase): ) def test_get_urls(self): - self.admin2.register(Thing) + self.admin2.register(SmallThing) self.assertEquals(8, len(self.admin2.get_urls())) def test_default_entries(self): diff --git a/djadmin2/tests/test_types.py b/djadmin2/tests/test_types.py index 288fd97..e36ac2e 100644 --- a/djadmin2/tests/test_types.py +++ b/djadmin2/tests/test_types.py @@ -40,7 +40,7 @@ class ImmutableAdminFactoryTests(TestCase): self.immutable_admin.d -class Thing(models.Model): +class BigThing(models.Model): pass @@ -59,7 +59,7 @@ class ModelAdminTest(TestCase): ) def test_get_index_kwargs(self): - admin_instance = ModelAdmin2(Thing, Admin2) + admin_instance = ModelAdmin2(BigThing, Admin2) self.assertIn( 'paginate_by', admin_instance.get_index_kwargs().keys() diff --git a/djadmin2/types.py b/djadmin2/types.py index fc15e98..766e2aa 100644 --- a/djadmin2/types.py +++ b/djadmin2/types.py @@ -224,7 +224,7 @@ class ModelAdmin2(with_metaclass(ModelAdminBase2)): 'Cannot instantiate admin view "{}.{}". ' 'The error that got raised was: {}'.format( self.__class__.__name__, admin_view.name, e)) - raise new_exception, None, trace + raise (new_exception, None, trace) pattern_list.append( url( regex=admin_view.url, diff --git a/djadmin2/utils.py b/djadmin2/utils.py index 8823f78..40e6aeb 100644 --- a/djadmin2/utils.py +++ b/djadmin2/utils.py @@ -89,7 +89,10 @@ def get_attr(obj, attr): and the __str__ attribute. """ if attr == '__str__': - value = unicode(obj) + if six.PY2: + value = unicode(obj) + else: + value = str(obj) else: attribute = getattr(obj, attr) value = attribute() if callable(attribute) else attribute diff --git a/djadmin2/views.py b/djadmin2/views.py index c50e09a..f6e2790 100644 --- a/djadmin2/views.py +++ b/djadmin2/views.py @@ -4,7 +4,7 @@ from __future__ import division, absolute_import, unicode_literals import operator from datetime import datetime -from django.contrib.auth import get_user_model +from django.conf import settings from django.contrib.auth.forms import (PasswordChangeForm, AdminPasswordChangeForm) from django.contrib.auth.views import (logout as auth_logout, @@ -19,17 +19,14 @@ from django.utils.encoding import force_text from django.utils.text import capfirst from django.utils.translation import ugettext_lazy from django.views import generic - import extra_views from . import permissions, utils from .forms import AdminAuthenticationForm -from .models import LogEntry from .viewmixins import Admin2Mixin, AdminModel2Mixin, Admin2ModelFormMixin from .filters import build_list_filter, build_date_filter - class AdminView(object): def __init__(self, url, view, name=None): @@ -292,14 +289,14 @@ class ModelListView(AdminModel2Mixin, generic.ListView): return context def _format_years(self, context): - years = context['object_list'].dates('published_date', 'year') + years = self._qs_date_or_datetime(context['object_list'], 'year') if len(years) == 1: return self._format_months(context) else: return [ (("?year=%s" % year.strftime("%Y")), year.strftime("%Y")) for year in - context['object_list'].dates('published_date', 'year') + self._qs_date_or_datetime(context['object_list'], 'year') ] def _format_months(self, context): @@ -310,7 +307,7 @@ class ModelListView(AdminModel2Mixin, generic.ListView): ), date.strftime("%B %Y") ) for date in - context["object_list"].dates('published_date', 'month') + self._qs_date_or_datetime(context['object_list'], 'month') ] def _format_days(self, context): @@ -323,9 +320,16 @@ class ModelListView(AdminModel2Mixin, generic.ListView): ), date.strftime("%B %d") ) for date in - context["object_list"].dates('published_date', 'day') + self._qs_date_or_datetime(context['object_list'], 'day') ] + def _qs_date_or_datetime(self, object_list, type): + if isinstance(self.model._meta.get_field(self.model_admin.date_hierarchy), models.DateTimeField): + qs = object_list.datetimes(self.model_admin.date_hierarchy, type) + else: + qs = object_list.dates(self.model_admin.date_hierarchy, type) + return qs + def get_success_url(self): view_name = 'admin2:{}_{}_index'.format( self.app_label, self.model_name) @@ -384,6 +388,7 @@ class ModelEditFormView(AdminModel2Mixin, Admin2ModelFormMixin, def forms_valid(self, form, inlines): response = super(ModelEditFormView, self).forms_valid(form, inlines) + from .models import LogEntry LogEntry.objects.log_action( self.request.user.id, self.object, @@ -420,6 +425,7 @@ class ModelAddFormView(AdminModel2Mixin, Admin2ModelFormMixin, def forms_valid(self, form, inlines): response = super(ModelAddFormView, self).forms_valid(form, inlines) + from .models import LogEntry LogEntry.objects.log_action( self.request.user.id, self.object, @@ -463,6 +469,7 @@ class ModelDeleteView(AdminModel2Mixin, generic.DeleteView): return context def delete(self, request, *args, **kwargs): + from .models import LogEntry LogEntry.objects.log_action( request.user.id, self.get_object(), @@ -500,6 +507,7 @@ class ModelHistoryView(AdminModel2Mixin, generic.ListView): def get_queryset(self): content_type = ContentType.objects.get_for_model(self.get_object()) + from .models import LogEntry return LogEntry.objects.filter( content_type=content_type, object_id=self.get_object().id @@ -511,7 +519,7 @@ class PasswordChangeView(Admin2Mixin, generic.UpdateView): default_template_name = 'auth/password_change_form.html' form_class = AdminPasswordChangeForm admin_form_class = PasswordChangeForm - model = get_user_model() + model = settings.AUTH_USER_MODEL success_url = reverse_lazy('admin2:password_change_done') def get_form_kwargs(self, **kwargs): @@ -529,6 +537,9 @@ class PasswordChangeView(Admin2Mixin, generic.UpdateView): return self.admin_form_class return super(PasswordChangeView, self).get_form_class() + def get_queryset(self): + from django.contrib.auth import get_user_model + return get_user_model()._default_manager.all() class PasswordChangeDoneView(Admin2Mixin, generic.TemplateView): diff --git a/example/blog/tests/__init__.py b/example/blog/tests/__init__.py index 8a7bd1e..e69de29 100644 --- a/example/blog/tests/__init__.py +++ b/example/blog/tests/__init__.py @@ -1,11 +0,0 @@ -# make sure that everything is setup for tests. Django 1.6 doesn't necessarily -# load the urls.py before the tests are run. -import example.urls - -from test_apiviews import * -from test_builtin_api_resources import * -from test_permissions import * -from test_modelforms import * -from test_views import * -from test_nestedobjects import * -from test_filters import * diff --git a/example/blog/tests/test_apiviews.py b/example/blog/tests/test_apiviews.py index 2f3cbe2..52bdbbe 100644 --- a/example/blog/tests/test_apiviews.py +++ b/example/blog/tests/test_apiviews.py @@ -3,7 +3,7 @@ from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.test import TestCase from django.test.client import RequestFactory -from django.utils import simplejson as json +import json from djadmin2 import apiviews diff --git a/example/blog/tests/test_filters.py b/example/blog/tests/test_filters.py index 0896543..6735ab3 100644 --- a/example/blog/tests/test_filters.py +++ b/example/blog/tests/test_filters.py @@ -2,7 +2,6 @@ # vim:fenc=utf-8 from django.test import TestCase -from django.contrib.auth import get_user_model from django.test.client import RequestFactory from django.core.urlresolvers import reverse diff --git a/example/example/settings.py b/example/example/settings.py index 161a76f..7768d08 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -130,6 +130,7 @@ INSTALLED_APPS = ( 'djadmin2.themes.djadmin2theme_default', 'blog', 'files', + 'polls' ) # A sample logging configuration. The only tangible logging @@ -162,25 +163,4 @@ LOGGING = { } -ADMIN2_THEME_DIRECTORY = "djadmin2theme_default" - - -########## TOOLBAR CONFIGURATION -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -INSTALLED_APPS += ( - 'debug_toolbar', -) - -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -INTERNAL_IPS = ('127.0.0.1',) - -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -MIDDLEWARE_CLASSES += ( - 'debug_toolbar.middleware.DebugToolbarMiddleware', -) - -DEBUG_TOOLBAR_CONFIG = { - 'INTERCEPT_REDIRECTS': False, - 'SHOW_TEMPLATE_CONTEXT': True, -} -########## END TOOLBAR CONFIGURATION +ADMIN2_THEME_DIRECTORY = "djadmin2theme_default" \ No newline at end of file diff --git a/example/files/tests/__init__.py b/example/files/tests/__init__.py index efb306e..e69de29 100644 --- a/example/files/tests/__init__.py +++ b/example/files/tests/__init__.py @@ -1,2 +0,0 @@ -from test_models import * -from test_views import * diff --git a/example/__init__.py b/example/polls/__init__.py similarity index 100% rename from example/__init__.py rename to example/polls/__init__.py diff --git a/example2/polls/admin.py b/example/polls/admin.py similarity index 100% rename from example2/polls/admin.py rename to example/polls/admin.py diff --git a/example2/polls/admin2.py b/example/polls/admin2.py similarity index 100% rename from example2/polls/admin2.py rename to example/polls/admin2.py diff --git a/example2/polls/locale/de/LC_MESSAGES/django.mo b/example/polls/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/de/LC_MESSAGES/django.mo rename to example/polls/locale/de/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/de/LC_MESSAGES/django.po b/example/polls/locale/de/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/de/LC_MESSAGES/django.po rename to example/polls/locale/de/LC_MESSAGES/django.po diff --git a/example2/polls/locale/en/LC_MESSAGES/django.mo b/example/polls/locale/en/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/en/LC_MESSAGES/django.mo rename to example/polls/locale/en/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/en/LC_MESSAGES/django.po b/example/polls/locale/en/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/en/LC_MESSAGES/django.po rename to example/polls/locale/en/LC_MESSAGES/django.po diff --git a/example2/polls/locale/fr/LC_MESSAGES/django.mo b/example/polls/locale/fr/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/fr/LC_MESSAGES/django.mo rename to example/polls/locale/fr/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/fr/LC_MESSAGES/django.po b/example/polls/locale/fr/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/fr/LC_MESSAGES/django.po rename to example/polls/locale/fr/LC_MESSAGES/django.po diff --git a/example2/polls/locale/it/LC_MESSAGES/django.mo b/example/polls/locale/it/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/it/LC_MESSAGES/django.mo rename to example/polls/locale/it/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/it/LC_MESSAGES/django.po b/example/polls/locale/it/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/it/LC_MESSAGES/django.po rename to example/polls/locale/it/LC_MESSAGES/django.po diff --git a/example2/polls/locale/nl/LC_MESSAGES/django.mo b/example/polls/locale/nl/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/nl/LC_MESSAGES/django.mo rename to example/polls/locale/nl/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/nl/LC_MESSAGES/django.po b/example/polls/locale/nl/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/nl/LC_MESSAGES/django.po rename to example/polls/locale/nl/LC_MESSAGES/django.po diff --git a/example2/polls/locale/pl_PL/LC_MESSAGES/django.mo b/example/polls/locale/pl_PL/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/pl_PL/LC_MESSAGES/django.mo rename to example/polls/locale/pl_PL/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/pl_PL/LC_MESSAGES/django.po b/example/polls/locale/pl_PL/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/pl_PL/LC_MESSAGES/django.po rename to example/polls/locale/pl_PL/LC_MESSAGES/django.po diff --git a/example2/polls/locale/pt_BR/LC_MESSAGES/django.mo b/example/polls/locale/pt_BR/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/pt_BR/LC_MESSAGES/django.mo rename to example/polls/locale/pt_BR/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/pt_BR/LC_MESSAGES/django.po b/example/polls/locale/pt_BR/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/pt_BR/LC_MESSAGES/django.po rename to example/polls/locale/pt_BR/LC_MESSAGES/django.po diff --git a/example2/polls/locale/sk/LC_MESSAGES/django.mo b/example/polls/locale/sk/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/sk/LC_MESSAGES/django.mo rename to example/polls/locale/sk/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/sk/LC_MESSAGES/django.po b/example/polls/locale/sk/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/sk/LC_MESSAGES/django.po rename to example/polls/locale/sk/LC_MESSAGES/django.po diff --git a/example2/polls/locale/tl_PH/LC_MESSAGES/django.mo b/example/polls/locale/tl_PH/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/tl_PH/LC_MESSAGES/django.mo rename to example/polls/locale/tl_PH/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/tl_PH/LC_MESSAGES/django.po b/example/polls/locale/tl_PH/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/tl_PH/LC_MESSAGES/django.po rename to example/polls/locale/tl_PH/LC_MESSAGES/django.po diff --git a/example2/polls/locale/zh/LC_MESSAGES/django.mo b/example/polls/locale/zh/LC_MESSAGES/django.mo similarity index 100% rename from example2/polls/locale/zh/LC_MESSAGES/django.mo rename to example/polls/locale/zh/LC_MESSAGES/django.mo diff --git a/example2/polls/locale/zh/LC_MESSAGES/django.po b/example/polls/locale/zh/LC_MESSAGES/django.po similarity index 100% rename from example2/polls/locale/zh/LC_MESSAGES/django.po rename to example/polls/locale/zh/LC_MESSAGES/django.po diff --git a/example2/polls/models.py b/example/polls/models.py similarity index 100% rename from example2/polls/models.py rename to example/polls/models.py diff --git a/example2/polls/templates/home.html b/example/polls/templates/home.html similarity index 100% rename from example2/polls/templates/home.html rename to example/polls/templates/home.html diff --git a/example2/polls/tests/__init__.py b/example/polls/tests/__init__.py similarity index 100% rename from example2/polls/tests/__init__.py rename to example/polls/tests/__init__.py diff --git a/example2/polls/tests/test_models.py b/example/polls/tests/test_models.py similarity index 100% rename from example2/polls/tests/test_models.py rename to example/polls/tests/test_models.py diff --git a/example2/polls/tests/test_views.py b/example/polls/tests/test_views.py similarity index 98% rename from example2/polls/tests/test_views.py rename to example/polls/tests/test_views.py index 05ea30e..c212a3f 100644 --- a/example2/polls/tests/test_views.py +++ b/example/polls/tests/test_views.py @@ -39,7 +39,7 @@ class PollListTest(BaseIntegrationTest): poll = Poll.objects.create(question="some question", pub_date=timezone.now()) params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(poll.pk)} response = self.client.post(reverse("admin2:polls_poll_index"), params) - self.assertInHTML('

Are you sure you want to delete the selected poll? All of the following items will be deleted:

', response.content) + self.assertInHTML('

Are you sure you want to delete the selected poll? The following item will be deleted:

', response.content) def test_delete_selected_poll_confirmation(self): poll = Poll.objects.create(question="some question", pub_date=timezone.now()) diff --git a/example2/polls/views.py b/example/polls/views.py similarity index 100% rename from example2/polls/views.py rename to example/polls/views.py diff --git a/example2/example2/__init__.py b/example2/example2/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/example2/example2/settings.py b/example2/example2/settings.py deleted file mode 100644 index c59a247..0000000 --- a/example2/example2/settings.py +++ /dev/null @@ -1,188 +0,0 @@ -# Django settings for example2 project. - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@example.com'), -) - -MANAGERS = ADMINS - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'example2.db', - } -} - -# Hosts/domain names that are valid for this site; required if DEBUG is False -# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts -ALLOWED_HOSTS = [] - -# 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. -# In a Windows environment this must be set to 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 - -# If you set this to False, Django will not use timezone-aware datetimes. -USE_TZ = True - -# Absolute filesystem path to the directory that will hold user-uploaded files. -# Example: "/var/www/example.com/media/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash. -# Examples: "http://example.com/media/", "http://media.example.com/" -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: "/var/www/example.com/static/" -STATIC_ROOT = '' - -# URL prefix for static files. -# Example: "http://example.com/static/", "http://static.example.com/" -STATIC_URL = '/static/' - -# 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 = 'vid$84s%19vhcss+(n$*pbc=nad2oab@^2s532_iesz2f6q=(z' - -# 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.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.locale.LocaleMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - # Uncomment the next line for simple clickjacking protection: - # 'django.middleware.clickjacking.XFrameOptionsMiddleware', -) - -ROOT_URLCONF = 'example2.urls' - -# Python dotted path to the WSGI application used by Django's runserver. -WSGI_APPLICATION = 'example2.wsgi.application' - -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', - 'django.contrib.admin', - # Uncomment the next line to enable admin documentation: - # 'django.contrib.admindocs', - 'floppyforms', - 'rest_framework', - 'djadmin2', - 'djadmin2.themes.djadmin2theme_default', - 'crispy_forms', - 'polls', -) - -try: - import django_extensions - INSTALLED_APPS += ( - 'django_extensions', - ) -except ImportError: - pass - -# 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 when DEBUG=False. -# 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, - 'filters': { - 'require_debug_false': { - '()': 'django.utils.log.RequireDebugFalse' - } - }, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'filters': ['require_debug_false'], - 'class': 'django.utils.log.AdminEmailHandler' - } - }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': True, - }, - } -} - - -ADMIN2_THEME_DIRECTORY = "djadmin2theme_default" - -########## TOOLBAR CONFIGURATION -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -INSTALLED_APPS += ( - 'debug_toolbar', -) - -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -INTERNAL_IPS = ('127.0.0.1',) - -# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation -MIDDLEWARE_CLASSES += ( - 'debug_toolbar.middleware.DebugToolbarMiddleware', -) - -DEBUG_TOOLBAR_CONFIG = { - 'INTERCEPT_REDIRECTS': False, - 'SHOW_TEMPLATE_CONTEXT': True, -} -########## END TOOLBAR CONFIGURATION diff --git a/example2/example2/urls.py b/example2/example2/urls.py deleted file mode 100644 index fe81b34..0000000 --- a/example2/example2/urls.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.conf.urls import patterns, include, url -from django.contrib import admin -from django.views.generic import TemplateView - -admin.autodiscover() - -import djadmin2 - -djadmin2.default.autodiscover() - -urlpatterns = patterns('', - url(r'^admin2/', include(djadmin2.default.urls)), - url(r'^admin/', include(admin.site.urls)), - url(r'^$', TemplateView.as_view(template_name="home.html")), -) diff --git a/example2/example2/wsgi.py b/example2/example2/wsgi.py deleted file mode 100644 index 9a01d4d..0000000 --- a/example2/example2/wsgi.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -WSGI config for example2 project. - -This module contains the WSGI application used by Django's development server -and any production WSGI deployments. It should expose a module-level variable -named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover -this application via the ``WSGI_APPLICATION`` setting. - -Usually you will have the standard Django WSGI application here, but it also -might make sense to replace the whole Django WSGI application with a custom one -that later delegates to the Django one. For example, you could introduce WSGI -middleware here, or combine a Django application with an application of another -framework. - -""" -import os - -# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks -# if running multiple sites in the same mod_wsgi process. To fix this, use -# mod_wsgi daemon mode with each site in its own daemon process, or use -# os.environ["DJANGO_SETTINGS_MODULE"] = "example2.settings" -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example2.settings") - -# This application object is used by any WSGI server configured to use this -# file. This includes Django's development server, if the WSGI_APPLICATION -# setting points here. -from django.core.wsgi import get_wsgi_application -application = get_wsgi_application() - -# Apply WSGI middleware here. -# from helloworld.wsgi import HelloWorldApplication -# application = HelloWorldApplication(application) diff --git a/example2/manage.py b/example2/manage.py deleted file mode 100755 index c13d5ca..0000000 --- a/example2/manage.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example2.settings") - - from django.core.management import execute_from_command_line - - execute_from_command_line(sys.argv) diff --git a/example2/polls/__init__.py b/example2/polls/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 305bdc0..0000000 --- a/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -django>=1.5.0 -django-braces>=1.0.0 -djangorestframework>=2.3.3 -django-debug-toolbar>=0.9.4 -coverage>=3.6 -django-extra-views>=0.6.2 -django-floppyforms>=1.1 -Sphinx>=1.2b1 -django-filter>=0.6 -django-crispy-forms>=1.3.2 diff --git a/runtests.py b/runtests.py deleted file mode 100755 index 3e58b51..0000000 --- a/runtests.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python -import os -import sys - -os.environ['DJANGO_SETTINGS_MODULE'] = 'example.settings' -exampleproject_dir = os.path.join(os.path.dirname(__file__), 'example') -sys.path.insert(0, exampleproject_dir) - -from django.test.utils import get_runner -from django.conf import settings - - -def runtests(tests=('blog', 'files', 'djadmin2')): - ''' - Takes a list as first argument, enumerating the apps and specific testcases - that should be executed. The syntax is the same as for what you would pass - to the ``django-admin.py test`` command. - - Examples:: - - # run the default test suite - runtests() - - # only run the tests from application ``blog`` - runtests(['blog']) - - # only run testcase class ``Admin2Test`` from app ``djadmin2`` - runtests(['djadmin2.Admin2Test']) - - # run all tests from application ``blog`` and the test named - # ``test_register`` on the ``djadmin2.Admin2Test`` testcase. - runtests(['djadmin2.Admin2Test.test_register', 'blog']) - ''' - TestRunner = get_runner(settings) - test_runner = TestRunner(verbosity=1, interactive=True) - failures = test_runner.run_tests(tests) - sys.exit(bool(failures)) - - -if __name__ == '__main__': - if len(sys.argv) > 1: - tests = sys.argv[1:] - runtests(tests) - else: - runtests() diff --git a/setup.py b/setup.py index 0152e3c..18f318e 100644 --- a/setup.py +++ b/setup.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- from setuptools import setup +from setuptools.command.test import test as TestCommand import re import os import sys @@ -80,6 +81,25 @@ if sys.argv[-1] == 'publish': LONG_DESCRIPTION = remove_screenshots(open('README.rst').read()) HISTORY = open('HISTORY.rst').read() +class PyTest(TestCommand): + user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] + + def initialize_options(self): + TestCommand.initialize_options(self) + self.pytest_args = [] + + def finalize_options(self): + TestCommand.finalize_options(self) + self.test_args = [] + self.test_suite = True + + def run_tests(self): + #import here, cause outside the eggs aren't loaded + sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'example')) + import pytest + errno = pytest.main(self.pytest_args) + sys.exit(errno) + setup( name='django-admin2', version=version, @@ -105,16 +125,21 @@ setup( license='MIT', packages=get_packages('djadmin2'), include_package_data=True, - test_suite='runtests.runtests', + #test_suite='runtests.runtests', install_requires=[ 'django>=1.5.0', - 'django-braces>=1.0.0', - 'django-extra-views>=0.6.2', + 'django-extra-views>=0.6.5', + 'django-braces>=1.3.0', 'djangorestframework>=2.3.3', 'django-floppyforms>=1.1', 'django-filter>=0.6', - 'django-crispy-forms>=1.3.2' + 'django-crispy-forms>=1.3.2', + 'pytz==2014.7' ], + extras_require={ + 'testing': ['pytest', 'pytest-django', 'pytest-ipdb'], + }, + cmdclass = {'test': PyTest}, zip_safe=False, ) diff --git a/tox.ini b/tox.ini index 501ac46..27e9087 100644 --- a/tox.ini +++ b/tox.ini @@ -1,35 +1,26 @@ [tox] # for py 3.x we are using only django 1.6.x as 1.5.x had only "experimental py3 support" -envlist = py27-dj1.4.x, py27-dj1.5.x, py27-dj1.6.x, py27-dj1.7.x, - py33-dj1.6.x, py34-dj1.6.x, py33-dj1.7.x, py34-dj1.7.x, - pypy-dj1.6.x, pypy3-dj1.6.x, +envlist = py27-dj1.6.x, py27-dj1.7.x, py33-dj1.6.x, py34-dj1.6.x, + py33-dj1.7.x, py34-dj1.7.x, pypy-dj1.6.x, pypy3-dj1.6.x, skipsdist = True [testenv] -commands = python runtests.py +commands = python setup.py test deps = - django-braces>=1.0.0 - django-extra-views>=0.6.2 + django-extra-views>=0.6.5 + django-braces>=1.3.0 djangorestframework>=2.3.3 django-floppyforms>=1.1 django-filter>=0.6 django-crispy-forms>=1.3.2 django-debug-toolbar>=0.9.4 - -[testenv:py27-dj1.4.x] -basepython=python2.7 -deps = - Django>=1.4,<1.5 - {[testenv]deps} - -[testenv:py27-dj1.5.x] -basepython=python2.7 -deps = - Django>=1.5,<1.6 - {[testenv]deps} + pytest + pytest-django +setenv= + DJANGO_SETTINGS_MODULE=example.settings + PYTHONPATH={toxinidir} [testenv:py27-dj1.6.x] -commands = coverage run runtests.py basepython=python2.7 deps = Django>=1.6,<1.7