From 06d822e124d4cb323d5dff8d0f1815305c14a9d6 Mon Sep 17 00:00:00 2001 From: Ali Karbassi Date: Wed, 9 May 2018 19:05:06 -0500 Subject: [PATCH 1/7] Fixed on_delete missing error in django 2.x --- .travis.yml | 74 ++++++++++++------------------------ tos/middleware.py | 11 +++++- tos/models.py | 4 +- tos/tests/test_middleware.py | 7 +++- tos/tests/test_views.py | 11 ++++-- 5 files changed, 49 insertions(+), 58 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82bb89f..3f9b227 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,71 +1,45 @@ language: python +cache: pip + python: - - "2.6" - "2.7" - "3.4" - "3.5" - "3.6" -install: - - pip install coveralls coverage - - pip install $DJANGO -script: - - coverage run runtests.py - - coverage report -m -after_script: - - coverage combine - - coveralls + +sudo: false + env: - - DJANGO="Django>=1.4,<1.5" - - DJANGO="Django>=1.5,<1.6" - - DJANGO="Django>=1.6,<1.7" - - DJANGO="Django>=1.7,<1.8" - DJANGO="Django>=1.8,<1.9" - DJANGO="Django>=1.9,<1.10" - DJANGO="Django>=1.10,<1.11" - DJANGO="Django>=1.11,<2.0" + - DJANGO="Django>=2.0,<2.1" - DJANGO="https://github.com/django/django/archive/master.tar.gz" + matrix: + fast_finish: true exclude: - # Python 2.6 support has been dropped in Django 1.7 - - python: "2.6" - env: DJANGO="Django>=1.7,<1.8" - - python: "2.6" - env: DJANGO="Django>=1.8,<1.9" - - python: "2.6" - env: DJANGO="Django>=1.9,<1.10" - - python: "2.6" - env: DJANGO="Django>=1.10,<1.11" - - python: "2.6" - env: DJANGO="Django>=1.11,<2.0" - - python: "2.6" - env: DJANGO="https://github.com/django/django/archive/master.tar.gz" + - python: "2.7" + env: DJANGO="Django>=2.0,<2.1" - python: "2.7" env: DJANGO="https://github.com/django/django/archive/master.tar.gz" - - python: "3.4" - env: DJANGO="Django>=1.4,<1.5" - python: "3.4" env: DJANGO="https://github.com/django/django/archive/master.tar.gz" - - python: "3.5" - env: DJANGO="Django>=1.4,<1.5" - - python: "3.5" - env: DJANGO="Django>=1.5,<1.6" - - python: "3.5" - env: DJANGO="Django>=1.6,<1.7" - - python: "3.5" - env: DJANGO="Django>=1.7,<1.8" - python: "3.6" - env: DJANGO="Django>=1.4,<1.5" - - python: "3.6" - env: DJANGO="Django>=1.5,<1.6" - - python: "3.6" - env: DJANGO="Django>=1.6,<1.7" - - python: "3.6" - env: DJANGO="Django>=1.7,<1.8" - - python: "3.6" - env: DJANGO="Django>=1.8,<1.9" - - python: "3.6" - env: DJANGO="Django>=1.9,<1.10" - - python: "3.6" - env: DJANGO="Django>=1.10,<1.11" + env: DJANGO="Django>=1.8,<1.11" + allow_failures: - env: DJANGO="https://github.com/django/django/archive/master.tar.gz" + +install: + - pip install coveralls coverage + - pip install $DJANGO + +script: + - coverage run runtests.py + - coverage report -m + +after_script: + - coverage combine + - coveralls diff --git a/tos/middleware.py b/tos/middleware.py index fbadb82..c3142e2 100644 --- a/tos/middleware.py +++ b/tos/middleware.py @@ -1,7 +1,7 @@ from django import VERSION as DJANGO_VERSION from django.conf import settings -from django.contrib.auth import REDIRECT_FIELD_NAME, SESSION_KEY as session_key -from django.core.urlresolvers import reverse +from django.contrib.auth import SESSION_KEY as session_key +from django.contrib.auth import REDIRECT_FIELD_NAME from django.http import HttpResponseRedirect from django.utils import deprecation from django.utils.cache import add_never_cache_headers @@ -9,6 +9,12 @@ from django.utils.cache import add_never_cache_headers from .compat import get_cache from .models import UserAgreement +if DJANGO_VERSION >= (1, 10, 0): + from django.urls import reverse +else: + from django.core.urlresolvers import reverse + + cache = get_cache(getattr(settings, 'TOS_CACHE_NAME', 'default')) tos_check_url = reverse('tos_check_tos') @@ -17,6 +23,7 @@ class UserAgreementMiddleware(deprecation.MiddlewareMixin if DJANGO_VERSION >= ( """ Some middleware to check if users have agreed to the latest TOS """ + def process_request(self, request): # Don't get in the way of any mutating requests if request.method != 'GET': diff --git a/tos/models.py b/tos/models.py index 1174b7a..baf34d4 100644 --- a/tos/models.py +++ b/tos/models.py @@ -68,8 +68,8 @@ class TermsOfService(BaseModel): class UserAgreement(BaseModel): - terms_of_service = models.ForeignKey(TermsOfService, related_name='terms') - user = models.ForeignKey(get_fk_user_model(), related_name='user_agreement') + terms_of_service = models.ForeignKey(TermsOfService, related_name='terms', on_delete=models.DO_NOTHING) + user = models.ForeignKey(get_fk_user_model(), related_name='user_agreement', on_delete=models.DO_NOTHING) def __unicode__(self): return u'%s agreed to TOS: %s' % (self.user.username, diff --git a/tos/tests/test_middleware.py b/tos/tests/test_middleware.py index fb4c601..4481a1a 100644 --- a/tos/tests/test_middleware.py +++ b/tos/tests/test_middleware.py @@ -1,6 +1,6 @@ +from django import VERSION as DJANGO_VERSION from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME -from django.core.urlresolvers import reverse from django.test import TestCase from django.test.utils import override_settings @@ -9,6 +9,11 @@ from tos.middleware import UserAgreementMiddleware from tos.models import TermsOfService, UserAgreement from tos.signal_handlers import invalidate_cached_agreements +if DJANGO_VERSION >= (1, 10, 0): + from django.urls import reverse +else: + from django.core.urlresolvers import reverse + @override_settings( MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES + [ diff --git a/tos/tests/test_views.py b/tos/tests/test_views.py index 82caa86..2bcdd05 100644 --- a/tos/tests/test_views.py +++ b/tos/tests/test_views.py @@ -1,10 +1,15 @@ +from django import VERSION as DJANGO_VERSION from django.conf import settings -from django.core.urlresolvers import reverse from django.test import TestCase from tos.compat import get_runtime_user_model from tos.models import TermsOfService, UserAgreement, has_user_agreed_latest_tos +if DJANGO_VERSION >= (1, 10, 0): + from django.urls import reverse +else: + from django.core.urlresolvers import reverse + class TestViews(TestCase): @@ -80,14 +85,14 @@ class TestViews(TestCase): self.assertTrue(has_user_agreed_latest_tos(self.user1)) response = self.client.post(self.login_url, dict(username='user1', - password='user1pass')) + password='user1pass')) self.assertEqual(302, response.status_code) def test_redirect_security(self): """ redirect to outside url not allowed, should redirect to login url""" response = self.client.post(self.login_url, dict(username='user1', - password='user1pass', next='http://example.com')) + password='user1pass', next='http://example.com')) self.assertEqual(302, response.status_code) self.assertIn(settings.LOGIN_REDIRECT_URL, response._headers['location'][1]) From 9d312c869712b06a6c3a7c7d619904c18459a6c0 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 3 Apr 2020 22:41:55 -0400 Subject: [PATCH 2/7] Django 2.0 compat --- .gitignore | 2 ++ requirements.txt | 1 - runtests.py | 58 +++++++++++++++++++++++++----------- tos/apps.py | 6 +++- tos/compat.py | 20 +++++++++++++ tos/middleware.py | 13 ++------ tos/tests/test_middleware.py | 32 ++++++++++---------- tos/tests/test_views.py | 8 +---- 8 files changed, 87 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 8aa07c2..d796ad2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.pyc .coverage htmlcov/ +venv +.python-version diff --git a/requirements.txt b/requirements.txt index 03490d0..4ebc8ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ -Django>=1.4 coverage diff --git a/runtests.py b/runtests.py index 3e56770..b566ecd 100755 --- a/runtests.py +++ b/runtests.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import logging import sys import django @@ -6,15 +7,20 @@ import django from django.conf import settings from django.core.management import execute_from_command_line +from tos.compat import get_middleware_settings_key + + +middleware_settings_key = get_middleware_settings_key() + if not settings.configured: - settings.configure( - DATABASES={ + django_settings = { + 'DATABASES': { 'default': { 'ENGINE': 'django.db.backends.sqlite3', } }, - INSTALLED_APPS=[ + 'INSTALLED_APPS': [ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', @@ -23,14 +29,7 @@ if not settings.configured: 'tos', 'tos.tests' ], - MIDDLEWARE_CLASSES=[ - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - ], - TEMPLATES=[ + 'TEMPLATES': [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], @@ -45,10 +44,10 @@ if not settings.configured: }, }, ], - ROOT_URLCONF='tos.tests.test_urls', - LOGIN_URL='/login/', - SITE_ID='1', - CACHES = { + 'ROOT_URLCONF': 'tos.tests.test_urls', + 'LOGIN_URL': '/login/', + 'SITE_ID': '1', + 'CACHES': { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', }, @@ -56,11 +55,34 @@ if not settings.configured: 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } }, - TOS_CACHE_NAME = 'tos' - ) + 'TOS_CACHE_NAME': 'tos' + } + + if django.VERSION >= (1, 10, 0): + django_settings[middleware_settings_key] = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + ] + else: + django_settings[middleware_settings_key] = [ + 'django.middleware.security.SecurityMiddleware', + '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', + ] + + settings.configure(**django_settings) -import logging logging.basicConfig( level = logging.DEBUG, format = '%(asctime)s %(levelname)s %(message)s', diff --git a/tos/apps.py b/tos/apps.py index b797327..4491b41 100644 --- a/tos/apps.py +++ b/tos/apps.py @@ -4,7 +4,11 @@ from django.db.models.signals import pre_save from .signal_handlers import invalidate_cached_agreements -MIDDLEWARES = getattr(settings, 'MIDDLEWARE_CLASSES', []) +from .compat import get_middleware_settings_key + + +middleware_settings_key = get_middleware_settings_key() +MIDDLEWARES = getattr(settings, middleware_settings_key, []) class TOSConfig(AppConfig): diff --git a/tos/compat.py b/tos/compat.py index bfb690e..1d9b160 100644 --- a/tos/compat.py +++ b/tos/compat.py @@ -1,5 +1,6 @@ import django from django.conf import settings +from django.utils import deprecation def patterns(mod, *urls): @@ -50,7 +51,26 @@ def get_cache(cache_name): return get_cache(cache_name) +def get_middleware_mixin(): + if django.VERSION >= (1, 10, 0): + return deprecation.MiddlewareMixin + else: + return object + + +def get_middleware_settings_key(): + if django.VERSION >= (1, 10, 0): + return 'MIDDLEWARE' + else: + return 'MIDDLEWARE_CLASSES' + + if django.VERSION < (1, 5): from django.templatetags.future import url else: from django.template.defaulttags import url + +if django.VERSION >= (1, 10, 0): + from django.urls import reverse +else: + from django.core.urlresolvers import reverse diff --git a/tos/middleware.py b/tos/middleware.py index c3142e2..a10bea1 100644 --- a/tos/middleware.py +++ b/tos/middleware.py @@ -1,25 +1,18 @@ -from django import VERSION as DJANGO_VERSION from django.conf import settings from django.contrib.auth import SESSION_KEY as session_key from django.contrib.auth import REDIRECT_FIELD_NAME from django.http import HttpResponseRedirect -from django.utils import deprecation from django.utils.cache import add_never_cache_headers -from .compat import get_cache +from .compat import get_cache, get_middleware_mixin, reverse from .models import UserAgreement -if DJANGO_VERSION >= (1, 10, 0): - from django.urls import reverse -else: - from django.core.urlresolvers import reverse - cache = get_cache(getattr(settings, 'TOS_CACHE_NAME', 'default')) tos_check_url = reverse('tos_check_tos') +middleware_mixin = get_middleware_mixin() - -class UserAgreementMiddleware(deprecation.MiddlewareMixin if DJANGO_VERSION >= (1, 10, 0) else object): +class UserAgreementMiddleware(middleware_mixin): """ Some middleware to check if users have agreed to the latest TOS """ diff --git a/tos/tests/test_middleware.py b/tos/tests/test_middleware.py index 4481a1a..7979ddb 100644 --- a/tos/tests/test_middleware.py +++ b/tos/tests/test_middleware.py @@ -1,24 +1,21 @@ -from django import VERSION as DJANGO_VERSION from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.test import TestCase -from django.test.utils import override_settings +from django.test.utils import modify_settings -from tos.compat import get_cache, get_runtime_user_model +from tos.compat import get_cache, get_runtime_user_model, reverse from tos.middleware import UserAgreementMiddleware from tos.models import TermsOfService, UserAgreement from tos.signal_handlers import invalidate_cached_agreements -if DJANGO_VERSION >= (1, 10, 0): - from django.urls import reverse -else: - from django.core.urlresolvers import reverse - -@override_settings( - MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES + [ - 'tos.middleware.UserAgreementMiddleware', - ] +@modify_settings( + MIDDLEWARE_CLASSES={ + 'append': 'tos.middleware.UserAgreementMiddleware', + }, + MIDDLEWARE={ + 'append': 'tos.middleware.UserAgreementMiddleware', + }, ) class TestMiddleware(TestCase): @@ -91,10 +88,13 @@ class TestMiddleware(TestCase): self.assertEqual(response.url.replace('http://testserver', ''), str(reverse('index'))) -@override_settings( - MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES + [ - 'tos.middleware.UserAgreementMiddleware', - ] +@modify_settings( + MIDDLEWARE_CLASSES={ + 'append': 'tos.middleware.UserAgreementMiddleware', + }, + MIDDLEWARE={ + 'append': 'tos.middleware.UserAgreementMiddleware', + }, ) class BumpCoverage(TestCase): diff --git a/tos/tests/test_views.py b/tos/tests/test_views.py index 2bcdd05..1813885 100644 --- a/tos/tests/test_views.py +++ b/tos/tests/test_views.py @@ -1,15 +1,9 @@ -from django import VERSION as DJANGO_VERSION from django.conf import settings from django.test import TestCase -from tos.compat import get_runtime_user_model +from tos.compat import get_runtime_user_model, reverse from tos.models import TermsOfService, UserAgreement, has_user_agreed_latest_tos -if DJANGO_VERSION >= (1, 10, 0): - from django.urls import reverse -else: - from django.core.urlresolvers import reverse - class TestViews(TestCase): From deda669daa43955ed8cc48ea9936ae3d7d3bf51a Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 3 Apr 2020 22:44:19 -0400 Subject: [PATCH 3/7] Put these back to cascade --- tos/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tos/models.py b/tos/models.py index baf34d4..9bd33f5 100644 --- a/tos/models.py +++ b/tos/models.py @@ -68,8 +68,8 @@ class TermsOfService(BaseModel): class UserAgreement(BaseModel): - terms_of_service = models.ForeignKey(TermsOfService, related_name='terms', on_delete=models.DO_NOTHING) - user = models.ForeignKey(get_fk_user_model(), related_name='user_agreement', on_delete=models.DO_NOTHING) + terms_of_service = models.ForeignKey(TermsOfService, related_name='terms', on_delete=models.CASCADE) + user = models.ForeignKey(get_fk_user_model(), related_name='user_agreement', on_delete=models.CASCADE) def __unicode__(self): return u'%s agreed to TOS: %s' % (self.user.username, From cf666a6063864527b8f67c94b99e5adb4ff6de6f Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 3 Apr 2020 22:45:44 -0400 Subject: [PATCH 4/7] Test Django 2.2.12 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3f9b227..16efa16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ env: - DJANGO="Django>=1.10,<1.11" - DJANGO="Django>=1.11,<2.0" - DJANGO="Django>=2.0,<2.1" + - DJANGO="Django==2.2.12" - DJANGO="https://github.com/django/django/archive/master.tar.gz" matrix: From e300c2bdb76864051b5186d3b94129654d0772a5 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 3 Apr 2020 22:48:30 -0400 Subject: [PATCH 5/7] 3.6 and 3.7 only --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 16efa16..a9cc054 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,8 @@ cache: pip python: - "2.7" - - "3.4" - - "3.5" - "3.6" + - "3.7" sudo: false From 505f4f1ede6e7ad083c1663246c274594892b2f7 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 3 Apr 2020 22:49:57 -0400 Subject: [PATCH 6/7] Exclude --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index a9cc054..a066dc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: exclude: - python: "2.7" env: DJANGO="Django>=2.0,<2.1" + - python: "2.7" + env: DJANGO="Django==2.2.12" - python: "2.7" env: DJANGO="https://github.com/django/django/archive/master.tar.gz" - python: "3.4" From 9250f2d945d1b1792f8d3736f31d03cd8e6b0b07 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 10 Apr 2020 12:05:36 -0400 Subject: [PATCH 7/7] 0.8.0 --- tos/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tos/__init__.py b/tos/__init__.py index b1cd446..2baceb4 100644 --- a/tos/__init__.py +++ b/tos/__init__.py @@ -1,3 +1,3 @@ default_app_config = 'tos.apps.TOSConfig' -VERSION = (0, 7, 2) +VERSION = (0, 8, 0)