diff --git a/.gitignore b/.gitignore index ec828ad..671e2b8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.un~ /build /dist +venv diff --git a/.travis.yml b/.travis.yml index 1e07009..ca36cb4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,17 @@ language: python -addons: - postgresql: "9.3" +services: + - postgresql + - mysql matrix: include: - python: 2.7 - env: DJANGO_VERSION=1.11.12 DB=postgres + env: DJANGO_VERSION=1.11.25 DB=postgres - python: 2.7 - env: DJANGO_VERSION=1.11.12 DB=sqlite + env: DJANGO_VERSION=1.11.25 DB=sqlite - python: 2.7 - env: DJANGO_VERSION=1.11.12 DB=mysql + env: DJANGO_VERSION=1.11.25 DB=mysql - python: 2.7 env: DJANGO_VERSION=1.7.11 DB=postgres @@ -27,11 +28,18 @@ matrix: env: DJANGO_VERSION=1.6.11 DB=mysql - python: 3.5 - env: DJANGO_VERSION=2.0.4 DB=postgres + env: DJANGO_VERSION=2.0.13 DB=postgres + - python: 3.5 + env: DJANGO_VERSION=2.0.13 DB=mysql + - python: 3.5 + env: DJANGO_VERSION=2.0.13 DB=sqlite + + - python: 3.5 + env: DJANGO_VERSION=2.2.6 DB=postgres - python: 3.5 - env: DJANGO_VERSION=2.0.4 DB=mysql + env: DJANGO_VERSION=2.2.6 DB=mysql - python: 3.5 - env: DJANGO_VERSION=2.0.4 DB=sqlite + env: DJANGO_VERSION=2.2.6 DB=sqlite - python: 3.5 env: DJANGO_VERSION=1.11.12 DB=postgres @@ -41,28 +49,35 @@ matrix: env: DJANGO_VERSION=1.11.12 DB=mysql - python: 3.6 - env: DJANGO_VERSION=2.0.4 DB=postgres + env: DJANGO_VERSION=2.0.13 DB=postgres - python: 3.6 - env: DJANGO_VERSION=2.0.4 DB=mysql + env: DJANGO_VERSION=2.0.13 DB=mysql - python: 3.6 - env: DJANGO_VERSION=2.0.4 DB=sqlite + env: DJANGO_VERSION=2.0.13 DB=sqlite - python: 3.6 - env: DJANGO_VERSION=1.11.12 DB=postgres + env: DJANGO_VERSION=2.2.6 DB=postgres - python: 3.6 - env: DJANGO_VERSION=1.11.12 DB=sqlite + env: DJANGO_VERSION=2.2.6 DB=mysql - python: 3.6 - env: DJANGO_VERSION=1.11.12 DB=mysql + env: DJANGO_VERSION=2.2.6 DB=sqlite + + - python: 3.6 + env: DJANGO_VERSION=1.11.25 DB=postgres + - python: 3.6 + env: DJANGO_VERSION=1.11.25 DB=sqlite + - python: 3.6 + env: DJANGO_VERSION=1.11.25 DB=mysql # command to install dependencies install: - "pip install -q Django==$DJANGO_VERSION" - "if [[ $DB == mysql ]]; then pip install -q mysqlclient; fi" - - "if [[ $DB == postgres ]]; then pip install -q psycopg2; fi" + - "if [[ $DB == postgres ]]; then pip install -q psycopg2-binary; fi" before_script: - psql -c 'create database django_positions;' -U postgres - mysql -e 'create database django_positions;' # command to run tests -script: python manage.py test --settings examples.ci_settings_$DB examples +script: python manage.py test --settings examples.ci_settings examples diff --git a/examples/settings.py b/examples/base_settings.py similarity index 95% rename from examples/settings.py rename to examples/base_settings.py index 7013f6c..919fc0c 100644 --- a/examples/settings.py +++ b/examples/base_settings.py @@ -89,9 +89,6 @@ 'version': 1, 'disable_existing_loggers': False, 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s %(funcName)s %(process)d %(thread)d %(message)s' - }, 'simple': { 'format': '%(levelname)s %(message)s' }, @@ -116,7 +113,7 @@ 'class': 'logging.handlers.RotatingFileHandler', 'filename': 'debug.log', 'maxBytes': 1024*1024*5, - 'formatter': 'verbose' + 'formatter': 'simple' }, }, 'loggers': { diff --git a/examples/base_settings_2.py b/examples/base_settings_2.py new file mode 100644 index 0000000..35e08da --- /dev/null +++ b/examples/base_settings_2.py @@ -0,0 +1,152 @@ +""" +Django settings for local project. + +For more information on this file, see +https://docs.djangoproject.com/en/1.7/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.7/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'wg2_iar76ne7o@uf7op87=4tqtnwch_civ79b1j%)=#i0q1*8p' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +TEMPLATE_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', + 'examples.todo', + 'examples.lists', + 'examples.nodes', + 'examples.photos', + 'examples.restaurants', + 'examples.school', + 'examples.store', + 'examples.migration' +) + +MIDDLEWARE = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +) + + +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', + ], + }, + }, +] + +# Database +# https://docs.djangoproject.com/en/1.7/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': 'mydb', + } +} + +# Internationalization +# https://docs.djangoproject.com/en/1.7/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.7/howto/static-files/ + +STATIC_URL = '/static/' +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'simple': { + 'format': '%(levelname)s %(message)s' + }, + }, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + }, + 'require_debug_true': { + '()': 'django.utils.log.RequireDebugTrue' + } + }, + 'handlers': { + 'console':{ + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple' + }, + 'debug_log_file':{ + 'level': 'DEBUG', + 'filters': ['require_debug_true'], + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': 'debug.log', + 'maxBytes': 1024*1024*5, + 'formatter': 'simple' + }, + }, + 'loggers': { + 'django.request': { + 'handlers': ['debug_log_file'], + 'level': 'INFO', + 'propagate': True, + }, + 'django.db.backends': { + 'handlers': ['debug_log_file'], + 'level': 'DEBUG', + 'propagate': False, + }, + '': { + 'handlers': ['debug_log_file', 'console'], + 'level': 'DEBUG', + 'propagate': True, + }, + }, +} \ No newline at end of file diff --git a/examples/ci_settings.py b/examples/ci_settings.py new file mode 100644 index 0000000..ad805e4 --- /dev/null +++ b/examples/ci_settings.py @@ -0,0 +1,30 @@ +import os + +db = os.environ['DB'] +v = tuple(map(int, os.environ['DJANGO_VERSION'].strip().split('.'))) + + +_DB_ENGINES = { + 'mysql': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'django_positions', + 'USER': 'root', + 'PASSWORD': '', + }, + 'postgres': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'django_positions', + 'USER': 'postgres', + 'PASSWORD': '', + 'HOST': '127.0.0.1', + 'PORT': '5432', + } +} + +if v > (2, 0, 0): + from .base_settings_2 import * +else: + from .base_settings import * + +if db in DATABASES: + DATABASES['default'] = _DB_ENGINES[db] diff --git a/examples/ci_settings_mysql.py b/examples/ci_settings_mysql.py deleted file mode 100644 index c0dab5d..0000000 --- a/examples/ci_settings_mysql.py +++ /dev/null @@ -1,3 +0,0 @@ -from .settings_mysql import * - -DATABASES['default'].update({'USER': 'root', 'PASSWORD': ''}) diff --git a/examples/ci_settings_postgres.py b/examples/ci_settings_postgres.py deleted file mode 100644 index 9c85978..0000000 --- a/examples/ci_settings_postgres.py +++ /dev/null @@ -1,3 +0,0 @@ -from .settings_postgres import * - -DATABASES['default'].update({'USER': 'postgres', 'PASSWORD': ''}) diff --git a/examples/ci_settings_sqlite.py b/examples/ci_settings_sqlite.py deleted file mode 100644 index 6315748..0000000 --- a/examples/ci_settings_sqlite.py +++ /dev/null @@ -1 +0,0 @@ -from .settings_sqlite import * diff --git a/examples/nodes/admin.py b/examples/nodes/admin.py new file mode 100644 index 0000000..9c84ef9 --- /dev/null +++ b/examples/nodes/admin.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from .models import Node + +class NodeAdmin(admin.ModelAdmin): + ''' + Test for SystemCheckError when using the position field in the Admin. + ''' + list_display = ('position', 'name') + list_display_links = ('name',) + list_filter = ('parent',) + search_fields = ('name',) + +admin.site.register(Node, NodeAdmin) diff --git a/examples/settings_mysql.py b/examples/settings_mysql.py deleted file mode 100644 index f6c4f39..0000000 --- a/examples/settings_mysql.py +++ /dev/null @@ -1,12 +0,0 @@ -from .settings import * - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': 'django_positions', - 'USER': 'django_positions', - 'PASSWORD': 'django_positions', - } -} - -LOGGING['handlers']['debug_log_file']['formatter'] = 'simple' diff --git a/examples/settings_postgres.py b/examples/settings_postgres.py deleted file mode 100644 index a7a8324..0000000 --- a/examples/settings_postgres.py +++ /dev/null @@ -1,12 +0,0 @@ -from .settings import * - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'django_positions', - 'USER': 'django_positions', - 'PASSWORD': 'django_positions', - 'HOST': '127.0.0.1', - 'PORT': '5432', - } -} diff --git a/examples/settings_sqlite.py b/examples/settings_sqlite.py deleted file mode 100644 index 7d7765a..0000000 --- a/examples/settings_sqlite.py +++ /dev/null @@ -1 +0,0 @@ -from .settings import * diff --git a/positions/fields.py b/positions/fields.py index e18b58f..7d72bd7 100644 --- a/positions/fields.py +++ b/positions/fields.py @@ -141,13 +141,13 @@ def pre_save(self, model_instance, add): def __get__(self, instance, owner): if instance is None: - raise AttributeError("%s must be accessed via instance." % self.name) + return self current, updated = getattr(instance, self.get_cache_name()) return current if updated is None else updated def __set__(self, instance, value): if instance is None: - raise AttributeError("%s must be accessed via instance." % self.name) + return self if value is None: value = self.default cache_name = self.get_cache_name() diff --git a/requirements.txt b/requirements.txt index d4ef6ee..6452448 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -Django==1.7.4 -psycopg2==2.6 +Django==2.2.2 +psycopg2-binary==2.7.7