many fixes to django-admin2 with py3

and django 1.7 compatybility
This commit is contained in:
Kamil Gałuszka 2014-09-22 04:14:02 +02:00 committed by montiniz
parent d12f82d241
commit b341d763f0
54 changed files with 94 additions and 401 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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):

View file

@ -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 *

View file

@ -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):

View file

@ -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()

View file

@ -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,

View file

@ -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

View file

@ -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):

View file

@ -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 *

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -1,2 +0,0 @@
from test_models import *
from test_views import *

View file

@ -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())

View file

@ -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

View file

@ -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")),
)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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()

View file

@ -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
View file

@ -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