mirror of
https://github.com/jazzband/django-admin2.git
synced 2026-03-16 22:20:24 +00:00
many fixes to django-admin2 with py3
and django 1.7 compatybility
This commit is contained in:
parent
d12f82d241
commit
b341d763f0
54 changed files with 94 additions and 401 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
from test_models import *
|
||||
from test_views import *
|
||||
|
|
@ -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('<p>Are you sure you want to delete the selected poll? All of the following items will be deleted:</p>', response.content)
|
||||
self.assertInHTML('<p>Are you sure you want to delete the selected poll? The following item will be deleted:</p>', response.content)
|
||||
|
||||
def test_delete_selected_poll_confirmation(self):
|
||||
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
|
||||
|
|
@ -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
|
||||
|
|
@ -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")),
|
||||
)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
45
runtests.py
45
runtests.py
|
|
@ -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()
|
||||
33
setup.py
33
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,
|
||||
)
|
||||
|
||||
|
|
|
|||
29
tox.ini
29
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue