From c1c88a76729a2d88bf581533ca9f2b85a693b992 Mon Sep 17 00:00:00 2001 From: AZtheAsian Date: Sun, 3 Dec 2017 21:41:01 -0700 Subject: [PATCH] Added compatibility with django 2.0 --- README.rst | 3 +- conftest.py | 3 +- docs/getting_started.rst | 2 +- example/accounts/migrations/0001_initial.py | 69 ------------------ example/vendors/migrations/0001_initial.py | 72 ------------------- manage.py | 4 +- organizations/abstract.py | 6 +- organizations/backends/defaults.py | 15 +++- organizations/base.py | 15 ++-- organizations/migrations/0001_initial.py | 40 ++++++----- organizations/migrations/0002_model_update.py | 3 +- organizations/views.py | 15 +++- requirements-test.txt | 1 - test_abstract/migrations/0001_initial.py | 21 ++---- test_accounts/migrations/0001_initial.py | 28 ++++---- test_custom/migrations/0001_initial.py | 14 ++-- test_vendors/migrations/0001_initial.py | 35 ++++----- tests/test_backends.py | 7 +- tests/test_migrations.py | 19 +++-- tests/urls.py | 2 +- tox.ini | 5 +- 21 files changed, 138 insertions(+), 241 deletions(-) delete mode 100644 example/accounts/migrations/0001_initial.py delete mode 100644 example/vendors/migrations/0001_initial.py diff --git a/README.rst b/README.rst index 20d2a453..b442f352 100644 --- a/README.rst +++ b/README.rst @@ -108,7 +108,7 @@ django-extensions, but you can configure your own in settings. The default:: ORGS_SLUGFIELD = 'django_extensions.db.fields.AutoSlugField' -Alternative:: +Alternative (note: this is not compatible with Django 2.0):: ORGS_SLUGFIELD = 'autoslug.fields.AutoSlugField' @@ -205,6 +205,7 @@ The codebase is targeted and tested against: * Django 1.9.x against Python 2.7, 3.4, 3.5, and PyPy * Django 1.10.x against Python 2.7, 3.4, 3.5, 3.6, and PyPy * Django 1.11.x against Python 2.7, 3.4, 3.5, 3.6, and PyPy +* Django 2.0.x against Python 3.6 To run the tests against all target environments, install `tox `_ and then execute the command:: diff --git a/conftest.py b/conftest.py index 15d25acc..dd09e140 100644 --- a/conftest.py +++ b/conftest.py @@ -3,6 +3,7 @@ """ import django +import os.path def pytest_configure(): @@ -33,7 +34,7 @@ def pytest_configure(): MIDDLEWARE_CLASSES=[], SITE_ID=1, FIXTURE_DIRS=['tests/fixtures'], - ORGS_SLUGFIELD='autoslug.AutoSlugField', + ORGS_SLUGFIELD='django_extensions.db.fields.AutoSlugField', ROOT_URLCONF="tests.urls", TEMPLATES = [ { diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 667e5e2c..12ac1930 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -85,7 +85,7 @@ URLs defined by that backend. You can do the same with the Auto slug field --------------- -Historically Django-Organizations relied on `django-extensions +Django-Organizations relies on `django-extensions `_ for the base `AutoSlugField `_. diff --git a/example/accounts/migrations/0001_initial.py b/example/accounts/migrations/0001_initial.py deleted file mode 100644 index 4e27029e..00000000 --- a/example/accounts/migrations/0001_initial.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import organizations.base -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Account', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(help_text='The name of the organization', max_length=200)), - ('is_active', models.BooleanField(default=True)), - ('monthly_subscription', models.IntegerField(default=1000)), - ], - options={ - 'ordering': ['name'], - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.CreateModel( - name='AccountOwner', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('organization', models.OneToOneField(related_name='owner', to='accounts.Account')), - ], - options={ - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.CreateModel( - name='AccountUser', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('user_type', models.CharField(default=b'', max_length=1)), - ('organization', models.ForeignKey(related_name='organization_users', to='accounts.Account')), - ('user', models.ForeignKey(related_name='accounts_accountuser', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ['organization', 'user'], - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.AddField( - model_name='accountowner', - name='organization_user', - field=models.OneToOneField(to='accounts.AccountUser'), - ), - migrations.AddField( - model_name='account', - name='users', - field=models.ManyToManyField(related_name='accounts_account', through='accounts.AccountUser', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterUniqueTogether( - name='accountuser', - unique_together=set([('user', 'organization')]), - ), - ] diff --git a/example/vendors/migrations/0001_initial.py b/example/vendors/migrations/0001_initial.py deleted file mode 100644 index 98807b28..00000000 --- a/example/vendors/migrations/0001_initial.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import organizations.base -from django.conf import settings - - -class Migration(migrations.Migration): - - dependencies = [ - ('auth', '0006_require_contenttypes_0002'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='Vendor', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(help_text='The name of the organization', max_length=200)), - ('is_active', models.BooleanField(default=True)), - ('street_address', models.CharField(default=b'', max_length=100)), - ('city', models.CharField(default=b'', max_length=100)), - ], - options={ - 'ordering': ['name'], - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.CreateModel( - name='VendorOwner', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('organization', models.OneToOneField(related_name='owner', to='vendors.Vendor')), - ], - options={ - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.CreateModel( - name='VendorUser', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('user_type', models.CharField(default=b'', max_length=1)), - ('organization', models.ForeignKey(related_name='organization_users', to='vendors.Vendor')), - ('permissions', models.ManyToManyField(to='auth.Permission', blank=True)), - ('user', models.ForeignKey(related_name='vendors_vendoruser', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ['organization', 'user'], - 'abstract': False, - }, - bases=(organizations.base.UnicodeMixin, models.Model), - ), - migrations.AddField( - model_name='vendorowner', - name='organization_user', - field=models.OneToOneField(to='vendors.VendorUser'), - ), - migrations.AddField( - model_name='vendor', - name='users', - field=models.ManyToManyField(related_name='vendors_vendor', through='vendors.VendorUser', to=settings.AUTH_USER_MODEL), - ), - migrations.AlterUniqueTogether( - name='vendoruser', - unique_together=set([('user', 'organization')]), - ), - ] diff --git a/manage.py b/manage.py index 7dff6ac6..9422c6cc 100755 --- a/manage.py +++ b/manage.py @@ -30,13 +30,13 @@ DATABASES={ "default": { "ENGINE": "django.db.backends.sqlite3", + "NAME": "test.sqlite3", } }, MIDDLEWARE_CLASSES=(), # Silence Django 1.7 warnings SITE_ID=1, FIXTURE_DIRS=['tests/fixtures'], - ORGS_SLUGFIELD='autoslug.AutoSlugField', - # ORGS_SLUGFIELD='django_extensions.db.fields.AutoSlugField', + ORGS_SLUGFIELD='django_extensions.db.fields.AutoSlugField', INSTALLED_APPS=INSTALLED_APPS, ROOT_URLCONF="tests.urls", ) diff --git a/organizations/abstract.py b/organizations/abstract.py index a9890d7b..7a34cd9c 100644 --- a/organizations/abstract.py +++ b/organizations/abstract.py @@ -26,7 +26,11 @@ import warnings from django.conf import settings -from django.core.urlresolvers import reverse + +try: + from django.core.urlresolvers import reverse +except ImportError: + from django.urls import reverse from django.db import models from django.utils.translation import ugettext_lazy as _ diff --git a/organizations/backends/defaults.py b/organizations/backends/defaults.py index 2685e78f..3f361a36 100644 --- a/organizations/backends/defaults.py +++ b/organizations/backends/defaults.py @@ -36,7 +36,12 @@ from django.contrib.auth import get_user_model from django.contrib.auth import login from django.core.mail import EmailMessage -from django.core.urlresolvers import reverse + +try: + from django.core.urlresolvers import reverse +except ImportError: + from django.urls import reverse + from django.http import Http404 from django.shortcuts import redirect from django.shortcuts import render @@ -217,8 +222,12 @@ def create_view(self, request): """ Initiates the organization and user account creation process """ - if request.user.is_authenticated(): - return redirect("organization_add") + try: + if request.user.is_authenticated(): + return redirect("organization_add") + except TypeError: + if request.user.is_authenticated: + return redirect("organization_add") form = org_registration_form(self.org_model)(request.POST or None) if form.is_valid(): try: diff --git a/organizations/base.py b/organizations/base.py index f06f2cdd..557e3da8 100644 --- a/organizations/base.py +++ b/organizations/base.py @@ -26,7 +26,8 @@ from django.conf import settings from django.db import models from django.db.models.base import ModelBase -from django.db.models.fields import FieldDoesNotExist +# from django.db.models.fields import FieldDoesNotExist +from django.core.exceptions import FieldDoesNotExist try: import six @@ -48,7 +49,7 @@ def __str__(self): if six.PY3: return self.__unicode__() else: - return unicode(self).encode('utf-8') + return unicode(self).encode('utf-8') # noqa class OrgMeta(ModelBase): @@ -123,13 +124,14 @@ def update_org_users(cls, module): cls.module_registry[module]['OrgUserModel']._meta.get_field("user") except FieldDoesNotExist: cls.module_registry[module]['OrgUserModel'].add_to_class("user", - models.ForeignKey(USER_MODEL, related_name="%(app_label)s_%(class)s")) + models.ForeignKey(USER_MODEL, related_name="%(app_label)s_%(class)s", + on_delete=models.CASCADE)) try: cls.module_registry[module]['OrgUserModel']._meta.get_field("organization") except FieldDoesNotExist: cls.module_registry[module]['OrgUserModel'].add_to_class("organization", models.ForeignKey(cls.module_registry[module]['OrgModel'], - related_name="organization_users")) + related_name="organization_users", on_delete=models.CASCADE)) def update_org_owner(cls, module): """ @@ -139,13 +141,14 @@ def update_org_owner(cls, module): cls.module_registry[module]['OrgOwnerModel']._meta.get_field("organization_user") except FieldDoesNotExist: cls.module_registry[module]['OrgOwnerModel'].add_to_class("organization_user", - models.OneToOneField(cls.module_registry[module]['OrgUserModel'])) + models.OneToOneField(cls.module_registry[module]['OrgUserModel'], + on_delete=models.CASCADE)) try: cls.module_registry[module]['OrgOwnerModel']._meta.get_field("organization") except FieldDoesNotExist: cls.module_registry[module]['OrgOwnerModel'].add_to_class("organization", models.OneToOneField(cls.module_registry[module]['OrgModel'], - related_name="owner")) + related_name="owner", on_delete=models.CASCADE)) class AbstractBaseOrganization(UnicodeMixin, models.Model): diff --git a/organizations/migrations/0001_initial.py b/organizations/migrations/0001_initial.py index 83e4ba48..4b678c7b 100644 --- a/organizations/migrations/0001_initial.py +++ b/organizations/migrations/0001_initial.py @@ -1,15 +1,16 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 2.0 on 2017-12-05 00:17 +from django.conf import settings from django.db import migrations, models -import organizations.fields -import organizations.base +import django.db.models.deletion import django.utils.timezone -from django.conf import settings - +import organizations.base +import organizations.fields class Migration(migrations.Migration): + initial = True + dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] @@ -18,57 +19,58 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Organization', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='The name of the organization', max_length=200)), ('is_active', models.BooleanField(default=True)), ('created', organizations.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False)), ('modified', organizations.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False)), - ('slug', organizations.fields.SlugField(populate_from=b'name', editable=True, max_length=200, help_text='The name in all lowercase, suitable for URL identification', unique=True)), + ('slug', organizations.fields.SlugField(editable=True, help_text='The name in all lowercase, suitable for URL identification', max_length=200, populate_from='name', unique=True)), ], options={ - 'ordering': ['name'], - 'abstract': False, 'verbose_name': 'organization', 'verbose_name_plural': 'organizations', + 'ordering': ['name'], + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), migrations.CreateModel( name='OrganizationOwner', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created', organizations.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False)), ('modified', organizations.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False)), - ('organization', models.OneToOneField(related_name='owner', to='organizations.Organization')), + ('organization', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to='organizations.Organization')), ], options={ 'verbose_name': 'organization owner', 'verbose_name_plural': 'organization owners', + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), migrations.CreateModel( name='OrganizationUser', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created', organizations.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False)), ('modified', organizations.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False)), ('is_admin', models.BooleanField(default=False)), - ('organization', models.ForeignKey(related_name='organization_users', to='organizations.Organization')), - ('user', models.ForeignKey(related_name='organizations_organizationuser', to=settings.AUTH_USER_MODEL)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organization_users', to='organizations.Organization')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organizations_organizationuser', to=settings.AUTH_USER_MODEL)), ], options={ - 'ordering': ['organization', 'user'], - 'abstract': False, 'verbose_name': 'organization user', 'verbose_name_plural': 'organization users', + 'ordering': ['organization', 'user'], + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), migrations.AddField( model_name='organizationowner', name='organization_user', - field=models.OneToOneField(to='organizations.OrganizationUser'), + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='organizations.OrganizationUser'), ), migrations.AddField( model_name='organization', @@ -77,6 +79,6 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='organizationuser', - unique_together=set([('user', 'organization')]), + unique_together={('user', 'organization')}, ), ] diff --git a/organizations/migrations/0002_model_update.py b/organizations/migrations/0002_model_update.py index 3f9fc351..92eccc1c 100644 --- a/organizations/migrations/0002_model_update.py +++ b/organizations/migrations/0002_model_update.py @@ -4,7 +4,6 @@ from django.db import migrations, models import organizations.fields - class Migration(migrations.Migration): dependencies = [ @@ -15,6 +14,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='organization', name='slug', - field=organizations.fields.SlugField(help_text='The name in all lowercase, suitable for URL identification', unique=True, populate_from='name', max_length=200, editable=True), + field=organizations.fields.SlugField(blank=True, editable=False, help_text='The name in all lowercase, suitable for URL identification', max_length=200, populate_from=('name',), unique=True), ), ] diff --git a/organizations/views.py b/organizations/views.py index 11937596..49c6bee3 100644 --- a/organizations/views.py +++ b/organizations/views.py @@ -24,7 +24,12 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from django.contrib.sites.shortcuts import get_current_site -from django.core.urlresolvers import reverse + +try: + from django.core.urlresolvers import reverse +except ImportError: + from django.urls import reverse + from django.http import HttpResponseBadRequest from django.shortcuts import redirect from django.shortcuts import render @@ -177,8 +182,12 @@ class OrganizationSignup(FormView): backend = registration_backend() def dispatch(self, request, *args, **kwargs): - if request.user.is_authenticated(): - return redirect('organization_add') + try: + if request.user.is_authenticated(): + return redirect('organization_add') + except TypeError: + if request.user.is_authenticated: + return redirect('organization_add') return super(OrganizationSignup, self).dispatch(request, *args, **kwargs) diff --git a/requirements-test.txt b/requirements-test.txt index dff3bdb0..3f4f6ad5 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -7,7 +7,6 @@ flake8>=2.4.1 # Required to test default models django-extensions>=1.6.0 -django-autoslug>=1.9.0 # Required for mocking signals mock-django==0.6.9 diff --git a/test_abstract/migrations/0001_initial.py b/test_abstract/migrations/0001_initial.py index 7005979f..d1248a81 100644 --- a/test_abstract/migrations/0001_initial.py +++ b/test_abstract/migrations/0001_initial.py @@ -1,8 +1,5 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2017-02-07 15:57 -from __future__ import unicode_literals +# Generated by Django 2.0 on 2017-12-07 03:11 -import django from django.conf import settings from django.db import migrations, models import django.db.models.deletion @@ -17,7 +14,6 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), - # more dependencies may be added dinamically ] operations = [ @@ -34,10 +30,10 @@ class Migration(migrations.Migration): ('city', models.CharField(default='', max_length=100)), ], options={ - 'abstract': False, 'verbose_name': 'organization', - 'ordering': ['name'], 'verbose_name_plural': 'organizations', + 'ordering': ['name'], + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), @@ -50,9 +46,9 @@ class Migration(migrations.Migration): ('organization', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to='test_abstract.CustomOrganization')), ], options={ - 'abstract': False, 'verbose_name': 'organization owner', 'verbose_name_plural': 'organization owners', + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), @@ -69,10 +65,10 @@ class Migration(migrations.Migration): ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='test_abstract_customuser', to=settings.AUTH_USER_MODEL)), ], options={ - 'verbose_name_plural': 'organization users', - 'abstract': False, 'verbose_name': 'organization user', + 'verbose_name_plural': 'organization users', 'ordering': ['organization', 'user'], + 'abstract': False, }, bases=(organizations.base.UnicodeMixin, models.Model), ), @@ -88,9 +84,6 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='customuser', - unique_together=set([('user', 'organization')]), + unique_together={('user', 'organization')}, ), ] - -if django.VERSION >= (1, 10): - Migration.dependencies.append(('auth', '0008_alter_user_username_max_length')) diff --git a/test_accounts/migrations/0001_initial.py b/test_accounts/migrations/0001_initial.py index 7713c572..a55c1dbe 100644 --- a/test_accounts/migrations/0001_initial.py +++ b/test_accounts/migrations/0001_initial.py @@ -1,13 +1,15 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 2.0 on 2017-12-05 00:17 -from django.db import models, migrations -import organizations.base from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import organizations.base class Migration(migrations.Migration): + initial = True + dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] @@ -16,7 +18,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Account', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='The name of the organization', max_length=200)), ('is_active', models.BooleanField(default=True)), ('monthly_subscription', models.IntegerField(default=1000)), @@ -30,8 +32,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='AccountOwner', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('organization', models.OneToOneField(related_name='owner', to='test_accounts.Account')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('organization', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to='test_accounts.Account')), ], options={ 'abstract': False, @@ -41,10 +43,10 @@ class Migration(migrations.Migration): migrations.CreateModel( name='AccountUser', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('user_type', models.CharField(default=b'', max_length=1)), - ('organization', models.ForeignKey(related_name='organization_users', to='test_accounts.Account')), - ('user', models.ForeignKey(related_name='test_accounts_accountuser', to=settings.AUTH_USER_MODEL)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_type', models.CharField(default='', max_length=1)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organization_users', to='test_accounts.Account')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='test_accounts_accountuser', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['organization', 'user'], @@ -55,7 +57,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='accountowner', name='organization_user', - field=models.OneToOneField(to='test_accounts.AccountUser'), + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='test_accounts.AccountUser'), ), migrations.AddField( model_name='account', @@ -64,6 +66,6 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='accountuser', - unique_together=set([('user', 'organization')]), + unique_together={('user', 'organization')}, ), ] diff --git a/test_custom/migrations/0001_initial.py b/test_custom/migrations/0001_initial.py index 86dbe3f8..7c0765b7 100644 --- a/test_custom/migrations/0001_initial.py +++ b/test_custom/migrations/0001_initial.py @@ -1,11 +1,13 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 2.0 on 2017-12-05 00:17 -from django.db import models, migrations +from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): + initial = True + dependencies = [ ('organizations', '0001_initial'), ] @@ -14,10 +16,12 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Team', fields=[ - ('organization_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='organizations.Organization')), - ('sport', models.CharField(max_length=100, null=True, blank=True)), + ('organization_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='organizations.Organization')), + ('sport', models.CharField(blank=True, max_length=100, null=True)), ], options={ + 'verbose_name': 'organization', + 'verbose_name_plural': 'organizations', 'ordering': ['name'], 'abstract': False, }, diff --git a/test_vendors/migrations/0001_initial.py b/test_vendors/migrations/0001_initial.py index 17322a5d..7752a316 100644 --- a/test_vendors/migrations/0001_initial.py +++ b/test_vendors/migrations/0001_initial.py @@ -1,15 +1,16 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 2.0 on 2017-12-05 00:17 -from django.db import models, migrations -import organizations.base from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import organizations.base class Migration(migrations.Migration): + initial = True + dependencies = [ - # ('auth', '0006_require_contenttypes_0002'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] @@ -17,11 +18,11 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Vendor', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='The name of the organization', max_length=200)), ('is_active', models.BooleanField(default=True)), - ('street_address', models.CharField(default=b'', max_length=100)), - ('city', models.CharField(default=b'', max_length=100)), + ('street_address', models.CharField(default='', max_length=100)), + ('city', models.CharField(default='', max_length=100)), ], options={ 'ordering': ['name'], @@ -32,8 +33,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='VendorOwner', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('organization', models.OneToOneField(related_name='owner', to='test_vendors.Vendor')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('organization', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to='test_vendors.Vendor')), ], options={ 'abstract': False, @@ -43,11 +44,11 @@ class Migration(migrations.Migration): migrations.CreateModel( name='VendorUser', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('user_type', models.CharField(default=b'', max_length=1)), - ('organization', models.ForeignKey(related_name='organization_users', to='test_vendors.Vendor')), - ('permissions', models.ManyToManyField(to='auth.Permission', blank=True)), - ('user', models.ForeignKey(related_name='test_vendors_vendoruser', to=settings.AUTH_USER_MODEL)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user_type', models.CharField(default='', max_length=1)), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organization_users', to='test_vendors.Vendor')), + ('permissions', models.ManyToManyField(blank=True, to='auth.Permission')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='test_vendors_vendoruser', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['organization', 'user'], @@ -58,7 +59,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='vendorowner', name='organization_user', - field=models.OneToOneField(to='test_vendors.VendorUser'), + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='test_vendors.VendorUser'), ), migrations.AddField( model_name='vendor', @@ -67,6 +68,6 @@ class Migration(migrations.Migration): ), migrations.AlterUniqueTogether( name='vendoruser', - unique_together=set([('user', 'organization')]), + unique_together={('user', 'organization')}, ), ] diff --git a/tests/test_backends.py b/tests/test_backends.py index bd130b31..830ca37b 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -1,6 +1,11 @@ from django.contrib.auth.models import User from django.core import mail -from django.core.urlresolvers import reverse + +try: + from django.core.urlresolvers import reverse +except ImportError: + from django.urls import reverse + from django.http import Http404 from django.http import QueryDict from django.test import TestCase diff --git a/tests/test_migrations.py b/tests/test_migrations.py index 15e4ad04..4c128473 100644 --- a/tests/test_migrations.py +++ b/tests/test_migrations.py @@ -10,7 +10,7 @@ import pytest from django.core.management import call_command - +from django.conf import settings @pytest.mark.django_db def test_no_missing_migrations(): @@ -18,9 +18,14 @@ def test_no_missing_migrations(): Pulled from mozilla/treeherder #dd53914, subject to MPL """ - with pytest.raises(SystemExit) as e: - # Replace with `check_changes=True` once we're using a Django version that includes: - # https://code.djangoproject.com/ticket/25604 - # https://github.com/django/django/pull/5453 - call_command('makemigrations', interactive=False, dry_run=True, exit_code=True) - assert str(e.value) == '1' + try: + with pytest.raises(SystemExit) as e: + # Replace with `check_changes=True` once we're using a Django version that includes: + # https://code.djangoproject.com/ticket/25604 + # https://github.com/django/django/pull/5453 + call_command('makemigrations', interactive=False, dry_run=True, exit_code=True) + assert str(e.value) == '1' + except TypeError: + out = StringIO() + call_command('makemigrations', interactive=False, dry_run=True, check=True, stdout=out) + assert str(out.getvalue()) == 'No changes detected\n' diff --git a/tests/urls.py b/tests/urls.py index 272c2b4e..c46b73f4 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -7,7 +7,7 @@ urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), url(r'^organizations/', include('organizations.urls')), url(r'^invite/', include(invitation_backend().get_urls())), url(r'^register/', include(registration_backend().get_urls())), diff --git a/tox.ini b/tox.ini index d08536db..988510b2 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = flake8, py{27,34,35}-django{18,19,110,111}, - py{36}-django{110,111}, + py{36}-django{110,111,2}, pypy-django{18,19,110,111} [testenv] @@ -22,10 +22,11 @@ deps = django19: Django>=1.9,<1.10 django110: Django>=1.10,<1.11 django111: Django>=1.11,<2 + django2: Django>=2,<2.1 -r{toxinidir}/requirements-test.txt [testenv:flake8] -basepython=python +basepython=python3 deps=flake8 commands= flake8 organizations