From 973efdc3c0e768f0aa4a111ff9d1b22e7b571e03 Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Wed, 25 Oct 2017 16:30:19 -0400 Subject: [PATCH 1/6] Support Django 1.11 --- file_picker/sites.py | 2 -- file_picker/views.py | 3 +++ sample_project/sample_project/runner.py | 9 +++++++++ sample_project/sample_project/settings.py | 2 ++ tox.ini | 9 +++++---- 5 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 sample_project/sample_project/runner.py diff --git a/file_picker/sites.py b/file_picker/sites.py index 7806efb..8c7a251 100644 --- a/file_picker/sites.py +++ b/file_picker/sites.py @@ -28,8 +28,6 @@ def guess_default(self, model): return file_picker.FilePickerBase def register(self, model_or_iterable, class_=None, name=None, **options): - # if not class_: - # class_ = file_picker.FilePickerBase if isinstance(model_or_iterable, ModelBase): model_or_iterable = [model_or_iterable] for model in model_or_iterable: diff --git a/file_picker/views.py b/file_picker/views.py index 4fabeda..cfd48b5 100644 --- a/file_picker/views.py +++ b/file_picker/views.py @@ -121,6 +121,9 @@ def get_queryset(self, search): queryset = self.model.objects.all() if self.ordering: queryset = queryset.order_by(self.ordering) + else: + # Need to default to some kind of ordering since we paginate + queryset = queryset.order_by('-pk') return queryset def upload_file(self, request): diff --git a/sample_project/sample_project/runner.py b/sample_project/sample_project/runner.py new file mode 100644 index 0000000..1658433 --- /dev/null +++ b/sample_project/sample_project/runner.py @@ -0,0 +1,9 @@ +from django.test.runner import DiscoverRunner + + +class NoChecksRunner(DiscoverRunner): + # Django 1.11 runs checks before running tests, which causes our urls.py to be loaded before we + # register our file pickers. This turns that functionality off. + + def run_checks(self): + pass diff --git a/sample_project/sample_project/settings.py b/sample_project/sample_project/settings.py index 966f8d0..3f1666f 100644 --- a/sample_project/sample_project/settings.py +++ b/sample_project/sample_project/settings.py @@ -109,3 +109,5 @@ MEDIA_URL = '/media/' MEDIA_ROOT = '%s/media/' % BASE_DIR ADMIN_MEDIA_PREFIX = '/static/admin/' + +TEST_RUNNER = 'sample_project.runner.NoChecksRunner' diff --git a/tox.ini b/tox.ini index ca5394a..802e082 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-django{1.8,1.9,1.10},flake8,coverage,docs +envlist = py27-django{1.8,1.9,1.10,1.11},flake8,coverage,docs [testenv] basepython = @@ -9,10 +9,11 @@ deps = django1.8: django<1.9 django1.9: django<1.10 django1.10: django<1.11 + django1.11: django<2.0 setenv = PYTHONPATH={toxinidir} DJANGO_SETTINGS_MODULE=sample_project.settings -commands = {envpython} sample_project/manage.py test +commands = {envpython} sample_project/manage.py test --keepdb [testenv:flake8] basepython = python2.7 @@ -23,9 +24,9 @@ commands = flake8 . basepython = python2.7 commands = coverage run sample_project/manage.py test - coverage report -m --fail-under 70 + coverage report -m --fail-under 80 deps = - Django<1.11 + Django<2.0 coverage>=3.7.1 [testenv:docs] From 628ebf7871b2a143b410ecad477901990ebf4065 Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Thu, 26 Oct 2017 16:32:27 -0400 Subject: [PATCH 2/6] More cleanup (mostly docs and rearranging imports) --- README.rst | 10 +-- docs/motivation.rst | 4 +- docs/picker_config.rst | 74 +++++++++++++---------- docs/sample.rst | 4 +- docs/setup.rst | 8 +-- docs/uploads.rst | 6 +- docs/wymeditor.rst | 7 +-- file_picker/admin.py | 0 file_picker/forms.py | 7 +-- file_picker/sites.py | 5 +- file_picker/tests.py | 5 +- file_picker/uploads/admin.py | 1 + file_picker/views.py | 14 ++--- sample_project/sample_project/settings.py | 18 +++--- sample_project/sample_project/urls.py | 6 +- 15 files changed, 86 insertions(+), 83 deletions(-) delete mode 100644 file_picker/admin.py diff --git a/README.rst b/README.rst index bd36b53..24c0c12 100644 --- a/README.rst +++ b/README.rst @@ -4,12 +4,12 @@ django-file-picker django-file-picker is a pluggable Django application used for uploading, browsing, and inserting various forms of media into HTML form fields. -Using jQuery Tools, file_picker integrates seamlessly into pre-existing pages by +Using jQuery Tools, django-file-picker integrates seamlessly into pre-existing pages by installing an overlay that lists file details and, when applicable, image thumbnails. New files can also be uploaded from within the overlay (via AJAX Upload). -``file_picker`` provides a few optional extensions to help get started, +django-file-picker provides a few optional extensions to help get started, including ``file_picker.uploads``, an app with pre-built Image and File models, and ``file_picker.wymeditor``, an app that integrates with `WYMeditor `_, a web-based @@ -24,7 +24,7 @@ Dependencies Required ```````` * Python 2.7 (**note**: Python 3 is not yet supported) -* `Django 1.8 to 1.10 (inclusive) `_ +* `Django 1.8 to 1.11 (inclusive) `_ * sorl-thumbnail==12.4a1 * `jQuery 1.4.x `_ * `jQuery Tools 1.2.x `_ @@ -38,7 +38,7 @@ Optional If you are using ``django.contrib.staticfiles``, then add ``file_picker`` to your INSTALLED_APPS to include the related css/js. - Otherwise make sure to include the contents of the static folder in your projects + Otherwise make sure to include the contents of the static folder in your project's media folder. .. _installation: @@ -67,4 +67,4 @@ Basic Installation # ... ] -Development sponsored by `Caktus Consulting Group, LLC. `_. +Development sponsored by `Caktus Consulting Group, LLC. `_. diff --git a/docs/motivation.rst b/docs/motivation.rst index e6e690a..415d3f7 100644 --- a/docs/motivation.rst +++ b/docs/motivation.rst @@ -5,5 +5,5 @@ The deep concern while building a file picker has been flexibility. Too many projects focus on wrapping everything together so that they can make deep connections. -Our main goal has been to build a application that facilitates connections, -that can be attached across multiple applications and models. +Our main goal has been to build an application that is easy to plug into a +wide variety of applications and models. diff --git a/docs/picker_config.rst b/docs/picker_config.rst index fddee89..925aac0 100644 --- a/docs/picker_config.rst +++ b/docs/picker_config.rst @@ -34,33 +34,35 @@ Each picker can take a set of attributes for easy customization.:: None of these attributes are required and they all have sane defaults. -* *form*- If left blank is created by building a *ModelForm* from the model defined - in the register function. It is used to build the form on the Upload tab. +* *form*- If not set, a *ModelForm* is created using the model defined + in the register function. This is used to build the form on the Upload tab. * *link_headers*- Defines the headers for the first set of columns which are used - to insert content into the textbox or WYSIWYG of your choice. By default it - converts _ to ' ' and capitalizes first letter of the fields name. + to insert content into the textbox or WYSIWYG widget of your choice. By default, it + converts _ to ' ' and capitalizes the first letter of the field's name. * *columns*- Defines the fields you want to be included on the listing page and their ordering. -* *extra_headers*- The list is used to define the headers for the columns - and needs to be in the same order as columns. -* *ordering*- Defines the order of items on the listing page in - to be used as ``query_set.order_by('-date')``. +* *extra_headers*- This list is used to display the headers for the columns + and needs to be in the same order as *columns*. +* *ordering*- Defines the order of items on the listing page. In this example, + the code would run ``query_set.order_by('-date')``. If no ordering is + provided, we'll order by ``-pk``. + Methods ------- -The three main methods consist of *append*, *list*, and *upload_file*. List and upload_file -take in the request object and act as views while append takes in an model item and helps -build the JSON output for list. Other methods are available but typically do not -need to be modified. +The three main methods consist of *append*, *list*, and *upload_file*. *List* +and *upload_file* take a request object and act as views, while *append* takes +a model instance and builds the JSON output for list. Other methods are +available but typically do not need to be modified. append(obj) ^^^^^^^^^^^ -This method takes in *obj* which is a item from the model and outputs a dictionary -to be used by list. This dictoinary is of the form.:: +This method takes *obj* which is a model instance and returns a dictionary +to be used by *list*. This dictionary is of the form:: { 'name': 'Name for the object.', @@ -69,39 +71,45 @@ to be used by list. This dictoinary is of the form.:: 'column_name_1': 'value', 'column_name_2': 'value', }, - 'insert': ['string/html to insert if first link is clicked', 'for second link',], - 'link_content': ['string to show on first insert link', 'for second link',], + 'insert': [ + 'text or html to insert if first link is clicked', + 'text or html to insert if second link is clicked', + ], + 'link_content': [ + 'string to show on first insert link', + 'string to show on second insert link', + ], } -As a note the *link_content* list and insert list must be the same length, as well as -the extra dictionary and the *link_headers* attribute. +The *link_content* list, *insert* list, and *extra* dictionary must all be the +same length, and must match the length of the *link_headers* of your custom FilePicker. list(request) ^^^^^^^^^^^^^ -This takes in a *request* object and outputs.:: +This takes a *request* object and returns:: { - 'page': Integer of current, + 'page': 1-based integer representing current page number, 'pages': List of pages, 'search': The current search term, - 'result': List returned from , - 'has_next': Lets the paginator know whether to hide/show the next button., - 'has_previous': Same as above for previous button., - 'link_headers': List of link headers either generated or defined by the attribute., - 'extra_headers': List of the extra headers made in the same we as above., - 'columns': List of column names to be included(same as the columns attribute.), + 'result': List returned from *append*, + 'has_next': Boolean telling paginator whether to show the next button, + 'has_previous': Boolean telling paginator whether to show the previous button., + 'link_headers': List of link headers defined by the Picker attribute (or generated if not defined), + 'extra_headers': List of the extra_headers specified by the Picker attribute, + 'columns': List of column names specified by the Picker attribute, } upload_file(request) ^^^^^^^^^^^^^^^^^^^^ -Builds the upload file form and is used to upload files in two steps, -file first then the other form parameters. +This takes a *request* object and builds the upload file form, which is used +to upload files in two steps: first the file, and then the other form parameters. -If called without a POST it returns a JSON dictionary with the key form -with an html block for the form. +If called without POST data it returns a JSON dictionary with the key ``form`` +containing the HTML representation of the form. -If called with a file and then with the post, it's a two step process. If the form -passed on the second step it returns the result of append for the object which -was just created. +If called with a file and then with the POST data, it performs a two step +process. If the form validates successfully on the second step it returns the +result of *append* for the object which was just created. diff --git a/docs/sample.rst b/docs/sample.rst index c67961a..72923ed 100644 --- a/docs/sample.rst +++ b/docs/sample.rst @@ -3,8 +3,8 @@ Running the Sample Project django-file-picker includes a sample project to use as an example. You can run the sample project like so:: - ~$ mkvirtualenv --distribute filepicker-sample - (filepicker-sample)~$ pip install "django>=1.8,<1.11" + ~$ mkvirtualenv filepicker-sample + (filepicker-sample)~$ pip install "django>=1.8,<2.0" (filepicker-sample)~$ git clone git://github.com/caktus/django-file-picker.git (filepicker-sample)~$ cd django-file-picker/ (filepicker-sample)~/django-file-picker$ python setup.py develop diff --git a/docs/setup.rst b/docs/setup.rst index 1bdfa49..8f4f5ec 100644 --- a/docs/setup.rst +++ b/docs/setup.rst @@ -7,7 +7,7 @@ Basic Setup we will use the models in ``file_picker.uploads``: Image and File. #. Use or create another model to contain the text field(s) to be inserted - by the picker. Here we will use the Post model from the ``sample_project.article``. + by the picker. Here we will use the Post model from ``sample_project.article``. It has two text fields, Body and Teaser. #. To use the pickers on both the teaser and body fields use a *formfield_override* @@ -39,7 +39,5 @@ Simple File Picker Widget .. class:: file_picker.widgets.SimpleFilePickerWidget To use the simple file picker widget, override the desired form field's widget. -It takes in a dictionary with expected keys `"image"` and/or `"file"` these -define which link to use "Add Image" and/or "Add File". - -For an example of usage look at the. +It takes a dictionary with expected keys `"image"` and/or `"file"` which +define which link to use, i.e. "Add Image" and/or "Add File". diff --git a/docs/uploads.rst b/docs/uploads.rst index fa546ae..5db8ecf 100644 --- a/docs/uploads.rst +++ b/docs/uploads.rst @@ -14,7 +14,7 @@ FilePicker .. class:: file_picker.uploads.file_pickers.FilePicker -Is a simple class based off of the ``file_picker.FilePickerBase`` +This is a subclass of ``file_picker.FilePickerBase`` which is connected to the *File* model and can be found in the Uploads admin section. @@ -23,7 +23,7 @@ ImagePicker .. class:: file_picker.uploads.file_pickers.ImagePicker -Is a simple class based off of the ``file_picker.ImagePickerBase`` +This is a subclass of ``file_picker.ImagePickerBase`` which is connected to the *Image* model and can be found in the Uploads admin section. @@ -39,6 +39,6 @@ on a single text field:: 'image': "images", })) -Where the `"file"` and `"image"` keywords add classes to the inputs, so that the links +The `"file"` and `"image"` keywords add classes to the inputs, so that the links for the overlay can be added. They can also be added to all fields in a form by using the *formfield_overrides* as in:ref:`setup`. diff --git a/docs/wymeditor.rst b/docs/wymeditor.rst index 1d78706..ac9eb27 100644 --- a/docs/wymeditor.rst +++ b/docs/wymeditor.rst @@ -12,15 +12,14 @@ WYMeditorWidget .. class:: file_picker.wymeditor.widgets.WYMeditorWidget To use the WYMeditorWidget, override the desired form field's widget. It takes in a -dictionary with expected keys `"image"` and/or `"file"` these define which button +dictionary with expected keys `"image"` and/or `"file"` which define which button is used to call the overlay, either an image or a paper clip icon respectively. Example TextField Override ************************** -An example using a *formfield_override* in an admin class use WYMeditor and -File Picker for each `TextField` in the form. -:: +An example using a *formfield_override* in an admin class using WYMeditor and +a File Picker for each `TextField` in the form:: class PostAdmin(admin.ModelAdmin): formfield_overrides = { diff --git a/file_picker/admin.py b/file_picker/admin.py deleted file mode 100644 index e69de29..0000000 diff --git a/file_picker/forms.py b/file_picker/forms.py index 3ecc2e4..08e1a17 100644 --- a/file_picker/forms.py +++ b/file_picker/forms.py @@ -1,11 +1,10 @@ import os from django import forms +from django.core.files.base import ContentFile from django.db import models from django.db.models.base import FieldDoesNotExist -from django.core.files.base import ContentFile - class QueryForm(forms.Form): page = forms.IntegerField(min_value=0, required=False) @@ -15,9 +14,7 @@ class QueryForm(forms.Form): def clean_page(self): page = self.cleaned_data.get('page') - if not page: - page = 1 - return page + return page or 1 FIELD_EXCLUDES = (models.ImageField, models.FileField) diff --git a/file_picker/sites.py b/file_picker/sites.py index 8c7a251..845de15 100644 --- a/file_picker/sites.py +++ b/file_picker/sites.py @@ -1,12 +1,11 @@ import json -from django.conf.urls import include, url +from django.conf.urls import url from django.core.urlresolvers import reverse, NoReverseMatch from django.db import models from django.db.models.base import ModelBase, FieldDoesNotExist from django.http import HttpResponse - import file_picker @@ -46,7 +45,7 @@ def get_urls(self): url(r'^$', self.primary, name='index'), ] for p in self._registry: - urlpatterns += url(r'^%s/' % p['name'], include(p['picker'].urls)), + urlpatterns += url(r'^%s/' % p['name'], p['picker'].urls), return (urlpatterns, None, "filepicker") urls = property(get_urls) diff --git a/file_picker/tests.py b/file_picker/tests.py index c9144f3..59b22d6 100644 --- a/file_picker/tests.py +++ b/file_picker/tests.py @@ -1,15 +1,16 @@ import os -import file_picker import datetime import json from tempfile import NamedTemporaryFile from django.db import models -from django.test import TestCase from django.core.files import File from django.core.urlresolvers import reverse +from django.test import TestCase from django.utils.text import capfirst +import file_picker + class Image(models.Model): """ diff --git a/file_picker/uploads/admin.py b/file_picker/uploads/admin.py index 721458e..d7637a9 100644 --- a/file_picker/uploads/admin.py +++ b/file_picker/uploads/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from file_picker.uploads import models as upload_models admin.site.register(upload_models.Image) diff --git a/file_picker/views.py b/file_picker/views.py index cfd48b5..ebc614c 100644 --- a/file_picker/views.py +++ b/file_picker/views.py @@ -1,17 +1,17 @@ -import os -import logging -import traceback -import tempfile import datetime import json +import logging +import os +import tempfile +import traceback from django.conf.urls import url +from django.core.paginator import Paginator, EmptyPage +from django.core.urlresolvers import reverse from django.db import models from django.db.models import Q -from django.utils.text import capfirst from django.http import HttpResponse, HttpResponseServerError -from django.core.paginator import Paginator, EmptyPage -from django.core.urlresolvers import reverse +from django.utils.text import capfirst from sorl.thumbnail.helpers import ThumbnailError from sorl.thumbnail import get_thumbnail diff --git a/sample_project/sample_project/settings.py b/sample_project/sample_project/settings.py index 3f1666f..d2e4f6b 100644 --- a/sample_project/sample_project/settings.py +++ b/sample_project/sample_project/settings.py @@ -1,22 +1,23 @@ """ Django settings for sample_project project. -Generated by 'django-admin startproject' using Django 1.8.17. +Generated by 'django-admin startproject' using Django 1.11.6. For more information on this file, see -https://docs.djangoproject.com/en/1.8/topics/settings/ +https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.8/ref/settings/ +https://docs.djangoproject.com/en/1.11/ref/settings/ """ -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ +# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'i=&zivfdelm9y^7^v@o98!z^tl222=a%&@s-8k%dvzrzvd(trn' @@ -43,16 +44,15 @@ 'sorl.thumbnail', ) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = [ + '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', - 'django.middleware.security.SecurityMiddleware', -) +] ROOT_URLCONF = 'sample_project.urls' diff --git a/sample_project/sample_project/urls.py b/sample_project/sample_project/urls.py index 046dfee..0efe6c3 100755 --- a/sample_project/sample_project/urls.py +++ b/sample_project/sample_project/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import include, url +from django.conf.urls import url from django.contrib import admin from django.conf import settings from django.views.static import serve @@ -6,8 +6,8 @@ import file_picker urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'^file-picker/', include(file_picker.site.urls)), + url(r'^admin/', admin.site.urls), + url(r'^file-picker/', file_picker.site.urls), url(r'^%s(?P.*)' % settings.MEDIA_URL.lstrip('/'), serve, From c87cc74369e3c9389577d168ad7bb093e89acbaf Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Thu, 26 Oct 2017 16:33:12 -0400 Subject: [PATCH 3/6] Silence all Django2.0 warnings and drop support for <1.10 --- file_picker/sites.py | 2 +- file_picker/tests.py | 2 +- file_picker/uploads/migrations/0001_initial.py | 8 ++++---- file_picker/uploads/models.py | 4 ++-- file_picker/views.py | 2 +- tox.ini | 6 ++---- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/file_picker/sites.py b/file_picker/sites.py index 845de15..9c27b0f 100644 --- a/file_picker/sites.py +++ b/file_picker/sites.py @@ -1,7 +1,7 @@ import json from django.conf.urls import url -from django.core.urlresolvers import reverse, NoReverseMatch +from django.urls import reverse, NoReverseMatch from django.db import models from django.db.models.base import ModelBase, FieldDoesNotExist from django.http import HttpResponse diff --git a/file_picker/tests.py b/file_picker/tests.py index 59b22d6..ffc890e 100644 --- a/file_picker/tests.py +++ b/file_picker/tests.py @@ -5,7 +5,7 @@ from django.db import models from django.core.files import File -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.utils.text import capfirst diff --git a/file_picker/uploads/migrations/0001_initial.py b/file_picker/uploads/migrations/0001_initial.py index f3eca64..d582e8f 100644 --- a/file_picker/uploads/migrations/0001_initial.py +++ b/file_picker/uploads/migrations/0001_initial.py @@ -23,8 +23,8 @@ class Migration(migrations.Migration): ('date_created', models.DateTimeField()), ('date_modified', models.DateTimeField()), ('file', models.FileField(upload_to=b'uploads/files/')), - ('created_by', models.ForeignKey(related_name=b'uploads_file_created', blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ('modified_by', models.ForeignKey(related_name=b'uploads_file_modified', blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('created_by', models.ForeignKey(related_name=b'uploads_file_created', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ('modified_by', models.ForeignKey(related_name=b'uploads_file_modified', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], options={ 'ordering': ('-date_modified',), @@ -43,8 +43,8 @@ class Migration(migrations.Migration): ('date_created', models.DateTimeField()), ('date_modified', models.DateTimeField()), ('file', models.ImageField(upload_to=b'uploads/images/')), - ('created_by', models.ForeignKey(related_name=b'uploads_image_created', blank=True, to=settings.AUTH_USER_MODEL, null=True)), - ('modified_by', models.ForeignKey(related_name=b'uploads_image_modified', blank=True, to=settings.AUTH_USER_MODEL, null=True)), + ('created_by', models.ForeignKey(related_name=b'uploads_image_created', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), + ('modified_by', models.ForeignKey(related_name=b'uploads_image_modified', blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)), ], options={ 'ordering': ('-date_modified',), diff --git a/file_picker/uploads/models.py b/file_picker/uploads/models.py index e764c5f..01c3dfa 100644 --- a/file_picker/uploads/models.py +++ b/file_picker/uploads/models.py @@ -15,9 +15,9 @@ class BaseFileModel(models.Model): date_created = models.DateTimeField() date_modified = models.DateTimeField() created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="%(app_label)s_%(class)s_created", - null=True, blank=True) + null=True, blank=True, on_delete=models.CASCADE) modified_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="%(app_label)s_%(class)s_modified", - null=True, blank=True) + null=True, blank=True, on_delete=models.CASCADE) class Meta: abstract = True diff --git a/file_picker/views.py b/file_picker/views.py index ebc614c..5b9459a 100644 --- a/file_picker/views.py +++ b/file_picker/views.py @@ -7,7 +7,7 @@ from django.conf.urls import url from django.core.paginator import Paginator, EmptyPage -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.db.models import Q from django.http import HttpResponse, HttpResponseServerError diff --git a/tox.ini b/tox.ini index 802e082..624f2cd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,19 +1,17 @@ [tox] -envlist = py27-django{1.8,1.9,1.10,1.11},flake8,coverage,docs +envlist = py27-django{1.10,1.11},flake8,coverage,docs [testenv] basepython = py27: python2.7 py33: python3.3 deps = - django1.8: django<1.9 - django1.9: django<1.10 django1.10: django<1.11 django1.11: django<2.0 setenv = PYTHONPATH={toxinidir} DJANGO_SETTINGS_MODULE=sample_project.settings -commands = {envpython} sample_project/manage.py test --keepdb +commands = {envpython} -Werror sample_project/manage.py test --keepdb [testenv:flake8] basepython = python2.7 From daf7f90dcba012b4220206d403cc5f28ba1bab9d Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Thu, 26 Oct 2017 17:27:00 -0400 Subject: [PATCH 4/6] Oops, committed '-Werr' --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 624f2cd..350f618 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ deps = setenv = PYTHONPATH={toxinidir} DJANGO_SETTINGS_MODULE=sample_project.settings -commands = {envpython} -Werror sample_project/manage.py test --keepdb +commands = {envpython} sample_project/manage.py test --keepdb [testenv:flake8] basepython = python2.7 From 05b601fe45f3d4569780812a432e247ea3041c1b Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Thu, 26 Oct 2017 17:33:50 -0400 Subject: [PATCH 5/6] Drop 1.8 and 1.9 support --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 24c0c12..cf194f6 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ Dependencies Required ```````` * Python 2.7 (**note**: Python 3 is not yet supported) -* `Django 1.8 to 1.11 (inclusive) `_ +* `Django 1.10 to 1.11 (inclusive) `_ * sorl-thumbnail==12.4a1 * `jQuery 1.4.x `_ * `jQuery Tools 1.2.x `_ From 1c42e7009905f555e015284b79f5d7fd3a09f4f2 Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Fri, 27 Oct 2017 07:38:10 -0400 Subject: [PATCH 6/6] Bring back 1.8 and 1.9 support --- README.rst | 2 +- file_picker/sites.py | 2 +- file_picker/tests.py | 2 +- file_picker/views.py | 2 +- sample_project/sample_project/settings.py | 6 +++--- tox.ini | 4 +++- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index cf194f6..24c0c12 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ Dependencies Required ```````` * Python 2.7 (**note**: Python 3 is not yet supported) -* `Django 1.10 to 1.11 (inclusive) `_ +* `Django 1.8 to 1.11 (inclusive) `_ * sorl-thumbnail==12.4a1 * `jQuery 1.4.x `_ * `jQuery Tools 1.2.x `_ diff --git a/file_picker/sites.py b/file_picker/sites.py index 9c27b0f..845de15 100644 --- a/file_picker/sites.py +++ b/file_picker/sites.py @@ -1,7 +1,7 @@ import json from django.conf.urls import url -from django.urls import reverse, NoReverseMatch +from django.core.urlresolvers import reverse, NoReverseMatch from django.db import models from django.db.models.base import ModelBase, FieldDoesNotExist from django.http import HttpResponse diff --git a/file_picker/tests.py b/file_picker/tests.py index ffc890e..59b22d6 100644 --- a/file_picker/tests.py +++ b/file_picker/tests.py @@ -5,7 +5,7 @@ from django.db import models from django.core.files import File -from django.urls import reverse +from django.core.urlresolvers import reverse from django.test import TestCase from django.utils.text import capfirst diff --git a/file_picker/views.py b/file_picker/views.py index 5b9459a..ebc614c 100644 --- a/file_picker/views.py +++ b/file_picker/views.py @@ -7,7 +7,7 @@ from django.conf.urls import url from django.core.paginator import Paginator, EmptyPage -from django.urls import reverse +from django.core.urlresolvers import reverse from django.db import models from django.db.models import Q from django.http import HttpResponse, HttpResponseServerError diff --git a/sample_project/sample_project/settings.py b/sample_project/sample_project/settings.py index d2e4f6b..f2e3a54 100644 --- a/sample_project/sample_project/settings.py +++ b/sample_project/sample_project/settings.py @@ -4,10 +4,10 @@ Generated by 'django-admin startproject' using Django 1.11.6. For more information on this file, see -https://docs.djangoproject.com/en/1.11/topics/settings/ +https://docs.djangoproject.com/en/stable/topics/settings/ For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.11/ref/settings/ +https://docs.djangoproject.com/en/stable/ref/settings/ """ import os @@ -17,7 +17,7 @@ # Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ +# See https://docs.djangoproject.com/en/stable/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'i=&zivfdelm9y^7^v@o98!z^tl222=a%&@s-8k%dvzrzvd(trn' diff --git a/tox.ini b/tox.ini index 350f618..e5e4447 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,13 @@ [tox] -envlist = py27-django{1.10,1.11},flake8,coverage,docs +envlist = py27-django{1.8,1.9,1.10,1.11},flake8,coverage,docs [testenv] basepython = py27: python2.7 py33: python3.3 deps = + django1.8: django<1.19 + django1.9: django<1.10 django1.10: django<1.11 django1.11: django<2.0 setenv =