From 1ffdc77c8ddc18e03167af1889f577ce52e1ffdd Mon Sep 17 00:00:00 2001
From: Chris Sattinger
Date: Tue, 10 Dec 2019 17:07:00 +0100
Subject: [PATCH 1/6] fix travis tests: explicitly install pyenv version
Also updates from 3.6 to 3.7
---
.travis.yml | 22 ++++++++++++++--------
tox.ini | 8 ++++----
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 8d19292a92..8eaf2c4af9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,26 @@
language: python
+cache:
+ directories:
+ - $HOME/.cache/pip
+ - /opt/python
sudo: false
env:
- TOX_ENV=py27-flake8
- - TOX_ENV=py36-flake8
+ - TOX_ENV=py37-flake8
- TOX_ENV=py27-dj18
- TOX_ENV=py27-dj19
- TOX_ENV=py27-dj110
- TOX_ENV=py27-dj111
- - TOX_ENV=py36-dj18
- - TOX_ENV=py36-dj19
- - TOX_ENV=py36-dj110
- - TOX_ENV=py36-dj111
- - TOX_ENV=py36-dj20
- - TOX_ENV=py36-dj21
+ - TOX_ENV=py37-dj18
+ - TOX_ENV=py37-dj19
+ - TOX_ENV=py37-dj110
+ - TOX_ENV=py37-dj111
+ - TOX_ENV=py37-dj20
+ - TOX_ENV=py37-dj21
before_install:
- - pyenv global system 3.6
+ - pyenv install 2.7 --skip-existing
+ - pyenv install 3.7 --skip-existing
+ - pyenv global system 3.7
install:
- pip install -r requirements-test.txt
script:
diff --git a/tox.ini b/tox.ini
index 3f99a3405e..834538efba 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,9 +6,9 @@
;
[tox]
envlist =
- {py27,py36}-flake8,
- {py27,py36}-{dj18,dj19,dj110,dj111}
- py36-{dj20,dj21}
+ {py27,py37}-flake8,
+ {py27,py37}-{dj18,dj19,dj110,dj111}
+ py37-{dj20,dj21}
[testenv]
setenv =
@@ -29,7 +29,7 @@ deps =
flake8
commands = flake8 ajax_select tests example
-[testenv:py36-flake8]
+[testenv:py37-flake8]
deps =
flake8
commands = flake8 ajax_select tests example
From 66fc329523f0beb544742420226024ae3184c053 Mon Sep 17 00:00:00 2001
From: Ryan Jarvis
Date: Sun, 15 Dec 2019 14:25:09 -0800
Subject: [PATCH 2/6] Apply Django2.2 fix from jsm296
---
ajax_select/fields.py | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/ajax_select/fields.py b/ajax_select/fields.py
index 57e82a28b6..908d206ba6 100644
--- a/ajax_select/fields.py
+++ b/ajax_select/fields.py
@@ -28,17 +28,16 @@
def _media(self):
- # unless AJAX_SELECT_BOOTSTRAP == False
- # then load jquery and jquery ui + default css
- # where needed
- js = ('ajax_select/js/bootstrap.js', 'ajax_select/js/ajax_select.js')
- try:
- if not settings.AJAX_SELECT_BOOTSTRAP:
- js = ('ajax_select/js/ajax_select.js',)
- except AttributeError:
- pass
- return forms.Media(css={'all': ('ajax_select/css/ajax_select.css',)}, js=js)
+ js = ['admin/js/jquery.init.js']
+
+ # Unless AJAX_SELECT_BOOTSTRAP == False
+ # then load include bootstrap which will load jquery and jquery ui + default css as needed
+ if getattr(settings, "AJAX_SELECT_BOOTSTRAP", True):
+ js.append('ajax_select/js/bootstrap.js')
+ js.append('ajax_select/js/ajax_select.js')
+
+ return forms.Media(css={'all': ('ajax_select/css/ajax_select.css',)}, js=js)
json_encoder = import_string(getattr(settings, 'AJAX_SELECT_JSON_ENCODER',
'django.core.serializers.json.DjangoJSONEncoder'))
@@ -476,4 +475,4 @@ def pack_ids(ids):
# |pk|pk| of current
return "|" + "|".join(str(pk) for pk in ids) + "|"
else:
- return "|"
+ return "|"
\ No newline at end of file
From 9bda7fc933233e99fecfcc54cbc09f156ed22b42 Mon Sep 17 00:00:00 2001
From: Ryan Jarvis
Date: Sat, 21 Dec 2019 13:56:30 -0800
Subject: [PATCH 3/6] Flake8 fixes
---
ajax_select/fields.py | 46 +++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 26 deletions(-)
diff --git a/ajax_select/fields.py b/ajax_select/fields.py
index 908d206ba6..78157060a3 100644
--- a/ajax_select/fields.py
+++ b/ajax_select/fields.py
@@ -1,7 +1,6 @@
from __future__ import unicode_literals
import json
-
from django import forms
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
@@ -10,10 +9,10 @@
from django.template.defaultfilters import force_escape
from django.template.loader import render_to_string
from django.utils.encoding import force_text
+from django.utils.module_loading import import_string
from django.utils.safestring import mark_safe
from django.utils.six import text_type
from django.utils.translation import ugettext as _
-from django.utils.module_loading import import_string
from ajax_select.registry import registry
@@ -23,7 +22,6 @@
# < django 1.10
from django.core.urlresolvers import reverse
-
as_default_help = 'Enter text to search.'
@@ -39,6 +37,7 @@ def _media(self):
return forms.Media(css={'all': ('ajax_select/css/ajax_select.css',)}, js=js)
+
json_encoder = import_string(getattr(settings, 'AJAX_SELECT_JSON_ENCODER',
'django.core.serializers.json.DjangoJSONEncoder'))
@@ -47,7 +46,6 @@ def _media(self):
class AutoCompleteSelectWidget(forms.widgets.TextInput):
-
"""
Widget to search for a model and return it as text for use in a CharField.
"""
@@ -105,7 +103,7 @@ def render(self, name, value, attrs=None, renderer=None, **_kwargs):
'add_link': self.add_link,
}
context.update(
- make_plugin_options(lookup, self.channel, self.plugin_options, initial))
+ make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = (
'ajax_select/autocompleteselect_%s.html' % self.channel,
'ajax_select/autocompleteselect.html')
@@ -120,7 +118,6 @@ def id_for_label(self, id_):
class AutoCompleteSelectField(forms.fields.CharField):
-
"""Form field to select a Model for a ForeignKey db field."""
channel = None
@@ -129,15 +126,15 @@ def __init__(self, channel, *args, **kwargs):
self.channel = channel
widget_kwargs = dict(
- channel=channel,
- help_text=kwargs.get('help_text', _(as_default_help)),
- show_help_text=kwargs.pop('show_help_text', True),
- plugin_options=kwargs.pop('plugin_options', {})
+ channel=channel,
+ help_text=kwargs.get('help_text', _(as_default_help)),
+ show_help_text=kwargs.pop('show_help_text', True),
+ plugin_options=kwargs.pop('plugin_options', {})
)
widget_kwargs.update(kwargs.pop('widget_options', {}))
kwargs["widget"] = AutoCompleteSelectWidget(**widget_kwargs)
super(AutoCompleteSelectField, self).__init__(
- max_length=255, *args, **kwargs)
+ max_length=255, *args, **kwargs)
def clean(self, value):
if value:
@@ -149,7 +146,7 @@ def clean(self, value):
# out of the scope of this field to do anything more than
# tell you it doesn't exist
raise forms.ValidationError(
- "%s cannot find object: %s" % (lookup, value))
+ "%s cannot find object: %s" % (lookup, value))
return objs[0]
else:
if self.required:
@@ -170,7 +167,6 @@ def has_changed(self, initial, data):
class AutoCompleteSelectMultipleWidget(forms.widgets.SelectMultiple):
-
"""
Widget to select multiple models for a ManyToMany db field.
"""
@@ -230,7 +226,7 @@ def render(self, name, value, attrs=None, renderer=None, **_kwargs):
'current': value,
'current_ids': current_ids,
'current_reprs': mark_safe(
- json.dumps(initial, cls=json_encoder)
+ json.dumps(initial, cls=json_encoder)
),
'help_text': help_text,
'extra_attrs': mark_safe(flatatt(final_attrs)),
@@ -238,7 +234,7 @@ def render(self, name, value, attrs=None, renderer=None, **_kwargs):
'add_link': self.add_link,
}
context.update(
- make_plugin_options(lookup, self.channel, self.plugin_options, initial))
+ make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = ('ajax_select/autocompleteselectmultiple_%s.html' % self.channel,
'ajax_select/autocompleteselectmultiple.html')
out = render_to_string(templates, context)
@@ -253,7 +249,6 @@ def id_for_label(self, id_):
class AutoCompleteSelectMultipleField(forms.fields.CharField):
-
"""
Form field to select multiple models for a ManyToMany db field.
"""
@@ -285,7 +280,7 @@ def __init__(self, channel, *args, **kwargs):
django_default_help = _(dh).translate(settings.LANGUAGE_CODE)
if django_default_help in translated:
cleaned_help = translated.replace(
- django_default_help, '').strip()
+ django_default_help, '').strip()
# probably will not show up in translations
if cleaned_help:
help_text = cleaned_help
@@ -326,11 +321,11 @@ def has_changed(self, initial_value, data_value):
dvs = [text_type(v) for v in (data_value or [])]
return ivs != dvs
+
###############################################################################
class AutoCompleteWidget(forms.TextInput):
-
"""
Widget to select a search result and enter the result as raw text in the
text input field. The user may also simply enter text and ignore any
@@ -375,14 +370,13 @@ def render(self, name, value, attrs=None, renderer=None, **_kwargs):
'func_slug': self.html_id.replace("-", ""),
}
context.update(
- make_plugin_options(lookup, self.channel, self.plugin_options, initial))
+ make_plugin_options(lookup, self.channel, self.plugin_options, initial))
templates = ('ajax_select/autocomplete_%s.html' % self.channel,
'ajax_select/autocomplete.html')
return mark_safe(render_to_string(templates, context))
class AutoCompleteField(forms.CharField):
-
"""
A CharField that uses an AutoCompleteWidget to lookup matching
and stores the result as plain text.
@@ -393,9 +387,9 @@ def __init__(self, channel, *args, **kwargs):
self.channel = channel
widget_kwargs = dict(
- help_text=kwargs.get('help_text', _(as_default_help)),
- show_help_text=kwargs.pop('show_help_text', True),
- plugin_options=kwargs.pop('plugin_options', {})
+ help_text=kwargs.get('help_text', _(as_default_help)),
+ show_help_text=kwargs.pop('show_help_text', True),
+ plugin_options=kwargs.pop('plugin_options', {})
)
widget_kwargs.update(kwargs.pop('widget_options', {}))
if 'attrs' in kwargs:
@@ -430,7 +424,7 @@ def _check_can_add(self, user, related_model):
app_label = related_model._meta.app_label
model = related_model._meta.object_name.lower()
self.widget.add_link = reverse(
- 'admin:%s_%s_add' % (app_label, model)) + '?_popup=1'
+ 'admin:%s_%s_add' % (app_label, model)) + '?_popup=1'
def autoselect_fields_check_can_add(form, model, user):
@@ -465,7 +459,7 @@ def make_plugin_options(lookup, channel_name, widget_plugin_options, initial):
return {
'plugin_options': mark_safe(json.dumps(po, cls=json_encoder)),
'data_plugin_options': force_escape(
- json.dumps(po, cls=json_encoder)
+ json.dumps(po, cls=json_encoder)
)
}
@@ -475,4 +469,4 @@ def pack_ids(ids):
# |pk|pk| of current
return "|" + "|".join(str(pk) for pk in ids) + "|"
else:
- return "|"
\ No newline at end of file
+ return "|"
From bd70103f011ba18b96a4ce3cf60393f86283552d Mon Sep 17 00:00:00 2001
From: Ryan Jarvis
Date: Sun, 22 Dec 2019 12:56:09 -0800
Subject: [PATCH 4/6] General Flake8 fixes
---
ajax_select/admin.py | 2 +-
ajax_select/apps.py | 1 -
ajax_select/helpers.py | 12 ++---
ajax_select/lookup_channel.py | 1 -
ajax_select/registry.py | 4 +-
ajax_select/urls.py | 1 +
ajax_select/views.py | 2 +-
docs/source/conf.py | 41 +++++++++--------
example/example/admin.py | 22 ++++-----
example/example/forms.py | 5 ++-
example/example/lookups.py | 12 +++--
example/example/models.py | 16 +++----
example/example/settings.py | 11 ++---
example/example/urls.py | 18 ++++----
example/example/views.py | 13 +++---
example/templates/search_form.html | 30 +++++++------
requirements.txt | 2 +-
setup.py | 72 +++++++++++++++---------------
tests/admin.py | 4 +-
tests/lookups.py | 5 ---
tests/models.py | 5 ---
tests/other_lookups.py | 1 -
tests/test_fields.py | 1 +
tests/test_integration.py | 11 +++--
tests/test_lookups.py | 1 -
tests/test_registry.py | 4 +-
tests/test_views.py | 7 ++-
tests/urls.py | 13 +++---
28 files changed, 141 insertions(+), 176 deletions(-)
diff --git a/ajax_select/admin.py b/ajax_select/admin.py
index 31f0468577..4960cf4999 100644
--- a/ajax_select/admin.py
+++ b/ajax_select/admin.py
@@ -1,9 +1,9 @@
from django.contrib import admin
+
from ajax_select.fields import autoselect_fields_check_can_add
class AjaxSelectAdmin(admin.ModelAdmin):
-
""" in order to get + popup functions subclass this or do the same hook inside of your get_form """
def get_form(self, request, obj=None, **kwargs):
diff --git a/ajax_select/apps.py b/ajax_select/apps.py
index f0f28b2bbc..a76725b056 100644
--- a/ajax_select/apps.py
+++ b/ajax_select/apps.py
@@ -2,7 +2,6 @@
class AjaxSelectConfig(AppConfig):
-
"""
Django 1.7+ enables initializing installed applications
and autodiscovering modules.
diff --git a/ajax_select/helpers.py b/ajax_select/helpers.py
index d456b64aad..727d9def01 100644
--- a/ajax_select/helpers.py
+++ b/ajax_select/helpers.py
@@ -99,14 +99,14 @@ def make_ajax_field(related_model, fieldname_on_model, channel, show_help_text=F
kwargs['show_help_text'] = show_help_text
if isinstance(field, ManyToManyField):
f = AutoCompleteSelectMultipleField(
- channel,
- **kwargs)
+ channel,
+ **kwargs)
elif isinstance(field, ForeignKey):
f = AutoCompleteSelectField(
- channel,
- **kwargs)
+ channel,
+ **kwargs)
else:
f = AutoCompleteField(
- channel,
- **kwargs)
+ channel,
+ **kwargs)
return f
diff --git a/ajax_select/lookup_channel.py b/ajax_select/lookup_channel.py
index a32063c001..c855e0da02 100644
--- a/ajax_select/lookup_channel.py
+++ b/ajax_select/lookup_channel.py
@@ -4,7 +4,6 @@
class LookupChannel(object):
-
"""
Subclass this, setting the model and implementing methods to taste.
diff --git a/ajax_select/registry.py b/ajax_select/registry.py
index b69486b71e..40f23048a7 100644
--- a/ajax_select/registry.py
+++ b/ajax_select/registry.py
@@ -5,7 +5,6 @@
class LookupChannelRegistry(object):
-
"""
Registry for LookupChannels activated for your django project.
@@ -57,7 +56,7 @@ def get(self, channel):
lookup_spec = self._registry[channel]
except KeyError:
raise ImproperlyConfigured(
- "No ajax_select LookupChannel named %(channel)r is registered." % {'channel': channel})
+ "No ajax_select LookupChannel named %(channel)r is registered." % {'channel': channel})
if (type(lookup_spec) is type) and issubclass(lookup_spec, LookupChannel):
return lookup_spec()
@@ -96,7 +95,6 @@ def make_channel(self, app_model, arg_search_field):
app_label, model_name = app_model.split(".")
class MadeLookupChannel(LookupChannel):
-
model = get_model(app_label, model_name)
search_field = arg_search_field
diff --git a/ajax_select/urls.py b/ajax_select/urls.py
index e810267889..cb30b2d196 100644
--- a/ajax_select/urls.py
+++ b/ajax_select/urls.py
@@ -1,4 +1,5 @@
from django.conf.urls import url
+
from ajax_select import views
urlpatterns = [
diff --git a/ajax_select/views.py b/ajax_select/views.py
index 8716b13661..90ae258cdc 100644
--- a/ajax_select/views.py
+++ b/ajax_select/views.py
@@ -1,11 +1,11 @@
import json
from django.http import HttpResponse
from django.utils.encoding import force_text
+
from ajax_select import registry
def ajax_lookup(request, channel):
-
"""Load the named lookup channel and lookup matching models.
GET or POST should contain 'term'
diff --git a/docs/source/conf.py b/docs/source/conf.py
index e09619366e..e2f4b29c9c 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -172,40 +172,39 @@
# html_use_index = True
# If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'django-ajax-selectsdoc'
-
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
- #'papersize': 'letterpaper',
+ # 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
- #'pointsize': '10pt',
+ # 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
- #'preamble': '',
+ # 'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
@@ -218,23 +217,23 @@
# The name of an image file (relative to this directory) to place at the top of
# the title page.
-#latex_logo = None
+# latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
# If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
# If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
# Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
# If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
@@ -247,7 +246,7 @@
]
# If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
@@ -262,13 +261,13 @@
]
# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
# If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
+# texinfo_no_detailmenu = False
diff --git a/example/example/admin.py b/example/example/admin.py
index 39b4a76d36..98e0a4167a 100644
--- a/example/example/admin.py
+++ b/example/example/admin.py
@@ -1,9 +1,9 @@
-
from django.contrib import admin
-from ajax_select import make_ajax_form
-from ajax_select.admin import AjaxSelectAdmin, AjaxSelectAdminTabularInline, AjaxSelectAdminStackedInline
from example.forms import ReleaseForm
-from example.models import Person, Label, Group, Song, Release, Book, Author
+from example.models import Author, Book, Group, Label, Person, Release, Song
+
+from ajax_select import make_ajax_form
+from ajax_select.admin import AjaxSelectAdmin, AjaxSelectAdminStackedInline, AjaxSelectAdminTabularInline
@admin.register(Person)
@@ -29,7 +29,6 @@ class PersonAdmin(YourAdminSuperclass, AjaxSelectAdmin):
class ReleaseInline(AjaxSelectAdminStackedInline):
-
# Example of the stacked inline
model = Release
@@ -43,7 +42,6 @@ class ReleaseInline(AjaxSelectAdminStackedInline):
@admin.register(Group)
class GroupAdmin(AjaxSelectAdmin):
-
# this shows a ManyToMany field
form = make_ajax_form(Group, {'members': 'person'})
inlines = [
@@ -53,7 +51,6 @@ class GroupAdmin(AjaxSelectAdmin):
@admin.register(Song)
class SongAdmin(AjaxSelectAdmin):
-
form = make_ajax_form(Song, {'group': 'group', 'title': 'cliche'})
# django bug:
# readonly_fields = ('group',)
@@ -64,22 +61,20 @@ class SongAdmin(AjaxSelectAdmin):
@admin.register(Release)
class ReleaseAdmin(AjaxSelectAdmin):
-
# specify a form class manually (normal django way)
# see forms.py
form = ReleaseForm
class BookInline(AjaxSelectAdminTabularInline):
-
# AjaxSelectAdminTabularInline enables the + add option
model = Book
form = make_ajax_form(Book, {
- 'about_group': 'group',
- 'mentions_persons': 'person'
- },
- show_help_text=True)
+ 'about_group': 'group',
+ 'mentions_persons': 'person'
+ },
+ show_help_text=True)
extra = 2
# to enable the + add option
@@ -94,7 +89,6 @@ class BookInline(AjaxSelectAdminTabularInline):
@admin.register(Author)
class AuthorAdmin(AjaxSelectAdmin):
-
inlines = [
BookInline,
]
diff --git a/example/example/forms.py b/example/example/forms.py
index e641453ae1..327d0fd2ad 100644
--- a/example/example/forms.py
+++ b/example/example/forms.py
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
+
from django.forms.models import ModelForm
-from ajax_select import make_ajax_field
from example.models import Release
+from ajax_select import make_ajax_field
-class ReleaseForm(ModelForm):
+class ReleaseForm(ModelForm):
class Meta:
model = Release
exclude = []
diff --git a/example/example/lookups.py b/example/example/lookups.py
index 0be95967a9..e6e08301b8 100644
--- a/example/example/lookups.py
+++ b/example/example/lookups.py
@@ -1,14 +1,15 @@
from __future__ import unicode_literals
-from django.utils.six import text_type
+
from django.db.models import Q
from django.utils.html import escape
-from example.models import Person, Group, Song
-from ajax_select import LookupChannel
+from django.utils.six import text_type
+from example.models import Group, Person, Song
+
import ajax_select
+from ajax_select import LookupChannel
class PersonLookup(LookupChannel):
-
model = Person
def get_query(self, q, request):
@@ -29,7 +30,6 @@ def format_item_display(self, obj):
class GroupLookup(LookupChannel):
-
model = Group
def get_query(self, q, request):
@@ -53,7 +53,6 @@ def can_add(self, user, model):
class SongLookup(LookupChannel):
-
model = Song
def get_query(self, q, request):
@@ -72,7 +71,6 @@ def format_item_display(self, obj):
# Here using decorator syntax rather than settings.AJAX_LOOKUP_CHANNELS
@ajax_select.register('cliche')
class ClicheLookup(LookupChannel):
-
""" an autocomplete lookup does not need to search models
though the words here could also be stored in a model and
searched as in the lookups above
diff --git a/example/example/models.py b/example/example/models.py
index 4d02751182..bb95b218da 100644
--- a/example/example/models.py
+++ b/example/example/models.py
@@ -1,13 +1,13 @@
# -*- coding: utf8 -*-
from __future__ import unicode_literals
+
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Person(models.Model):
-
""" an actual singular human being """
name = models.CharField(blank=True, max_length=100)
email = models.EmailField()
@@ -18,13 +18,12 @@ def __str__(self):
@python_2_unicode_compatible
class Group(models.Model):
-
""" a music group """
name = models.CharField(max_length=200, unique=True, help_text="Name of the group")
members = models.ManyToManyField(Person,
- blank=True,
- help_text="Enter text to search for and add each member of the group.")
+ blank=True,
+ help_text="Enter text to search for and add each member of the group.")
url = models.URLField(blank=True)
def __str__(self):
@@ -33,7 +32,6 @@ def __str__(self):
@python_2_unicode_compatible
class Label(models.Model):
-
""" a record label """
name = models.CharField(max_length=200, unique=True)
@@ -46,7 +44,6 @@ def __str__(self):
@python_2_unicode_compatible
class Song(models.Model):
-
""" a song """
title = models.CharField(blank=False, max_length=200)
@@ -58,15 +55,14 @@ def __str__(self):
@python_2_unicode_compatible
class Release(models.Model):
-
""" a music release/product """
title = models.CharField(max_length=100)
catalog = models.CharField(blank=True, max_length=100)
group = models.ForeignKey(Group, blank=True, null=True,
- verbose_name="Русский текст (group)",
- on_delete=models.CASCADE)
+ verbose_name="Русский текст (group)",
+ on_delete=models.CASCADE)
label = models.ForeignKey(Label, blank=False, null=False, on_delete=models.CASCADE)
songs = models.ManyToManyField(Song, blank=True)
@@ -76,7 +72,6 @@ def __str__(self):
@python_2_unicode_compatible
class Author(models.Model):
-
""" Author has multiple books,
via foreign keys
"""
@@ -89,7 +84,6 @@ def __str__(self):
@python_2_unicode_compatible
class Book(models.Model):
-
""" Book has no admin, its an inline in the Author admin"""
author = models.ForeignKey(Author, on_delete=models.CASCADE)
diff --git a/example/example/settings.py b/example/example/settings.py
index 777dee1524..19322f9856 100644
--- a/example/example/settings.py
+++ b/example/example/settings.py
@@ -47,7 +47,6 @@
'song': ('example.lookups', 'SongLookup'),
}
-
# By default will use window.jQuery
# or Django Admin's jQuery
# or load one from google ajax apis
@@ -74,10 +73,10 @@
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'ajax_selects_example_db'
-DATABASE_USER = '' # Not used with sqlite3.
-DATABASE_PASSWORD = '' # Not used with sqlite3.
-DATABASE_HOST = '' # Not used with sqlite3.
-DATABASE_PORT = '' # Not used with sqlite3.
+DATABASE_USER = '' # Not used with sqlite3.
+DATABASE_PASSWORD = '' # Not used with sqlite3.
+DATABASE_HOST = '' # Not used with sqlite3.
+DATABASE_PORT = '' # Not used with sqlite3.
DATABASES = {
'default': {
@@ -104,7 +103,6 @@
# to load the internationalization machinery.
USE_I18N = True
-
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''
@@ -122,7 +120,6 @@
# Make this unique, and don't share it with nobody.
SECRET_KEY = '=9fhrrwrazha6r_m)r#+in*@n@i322ubzy4r+zz%wz$+y(=qpb'
-
ROOT_URLCONF = 'example.urls'
# Django < 1.8
diff --git a/example/example/urls.py b/example/example/urls.py
index df1b1c9ac6..8b444d7394 100644
--- a/example/example/urls.py
+++ b/example/example/urls.py
@@ -1,17 +1,17 @@
-from django.conf.urls import url, include
+from django.conf import settings
+from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
-from django.conf import settings
+
from ajax_select import urls as ajax_select_urls
from example import views
-
admin.autodiscover()
urlpatterns = [
- url(r'^search_form',
- view=views.search_form,
- name='search_form'),
- url(r'^admin/lookups/', include(ajax_select_urls)),
- url(r'^admin/', admin.site.urls),
-] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+ url(r'^search_form',
+ view=views.search_form,
+ name='search_form'),
+ url(r'^admin/lookups/', include(ajax_select_urls)),
+ url(r'^admin/', admin.site.urls),
+ ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/example/example/views.py b/example/example/views.py
index 127eb774cb..a088ae13fd 100644
--- a/example/example/views.py
+++ b/example/example/views.py
@@ -1,23 +1,22 @@
# -*- coding: utf-8 -*-
-
from __future__ import unicode_literals
+
from django import forms
from django.shortcuts import render_to_response
from django.template import RequestContext
+
from ajax_select.fields import AutoCompleteField
class SearchForm(forms.Form):
-
q = AutoCompleteField('cliche',
- required=True,
- help_text="Autocomplete will suggest clichés about cats, but you can enter anything you like.",
- label="Favorite Cliché",
- attrs={'size': 100})
+ required=True,
+ help_text="Autocomplete will suggest clichés about cats, but you can enter anything you like.",
+ label="Favorite Cliché",
+ attrs={'size': 100})
def search_form(request):
-
dd = {}
if 'q' in request.GET:
dd['entered'] = request.GET.get('q')
diff --git a/example/templates/search_form.html b/example/templates/search_form.html
index d87b80a87e..052e5542a9 100644
--- a/example/templates/search_form.html
+++ b/example/templates/search_form.html
@@ -1,19 +1,21 @@
-
- {% if entered %}
- You entered:
{{ entered }}
- {% endif %}
-
-
-
+
+{% if entered %}
+ You entered:
+
{{ entered }}
+{% endif %}
+
+
+
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 01fd0eb060..f5651852ee 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
django>=1.8, <2.2
-wheel==0.29.0
+wheel>=0.29.0
diff --git a/setup.py b/setup.py
index 59d9816829..36dbdf0da1 100644
--- a/setup.py
+++ b/setup.py
@@ -3,42 +3,42 @@
from setuptools import setup
setup(
- name='django-ajax-selects',
- version='1.7.1',
- description='Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.',
- author='Chris Sattinger',
- author_email='crucialfelix@gmail.com',
- url='https://github.com/crucialfelix/django-ajax-selects/',
- packages=['ajax_select'],
- package_data={
- 'ajax_select':
- [
- '*.py',
- '*.txt',
- '*.md',
- 'static/ajax_select/css/*',
- 'static/ajax_select/images/*',
- 'static/ajax_select/js/*',
- 'templates/ajax_select/*.html'
- ]
- },
- include_package_data=True,
- zip_safe=False,
- license="MIT",
- classifiers=[
- "Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 3",
- "Development Status :: 5 - Production/Stable",
- 'Environment :: Web Environment',
- "Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Topic :: Software Development :: Libraries :: Python Modules",
- "Topic :: Software Development :: User Interfaces",
- "Framework :: Django",
- ],
- long_description="""\
+ name='django-ajax-selects',
+ version='1.7.1',
+ description='Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.',
+ author='Chris Sattinger',
+ author_email='crucialfelix@gmail.com',
+ url='https://github.com/crucialfelix/django-ajax-selects/',
+ packages=['ajax_select'],
+ package_data={
+ 'ajax_select':
+ [
+ '*.py',
+ '*.txt',
+ '*.md',
+ 'static/ajax_select/css/*',
+ 'static/ajax_select/images/*',
+ 'static/ajax_select/js/*',
+ 'templates/ajax_select/*.html'
+ ]
+ },
+ include_package_data=True,
+ zip_safe=False,
+ license="MIT",
+ classifiers=[
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 3",
+ "Development Status :: 5 - Production/Stable",
+ 'Environment :: Web Environment',
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Software Development :: User Interfaces",
+ "Framework :: Django",
+ ],
+ long_description="""\
Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.
- Customize search query
diff --git a/tests/admin.py b/tests/admin.py
index bd22e5a63e..4196858e7c 100644
--- a/tests/admin.py
+++ b/tests/admin.py
@@ -1,5 +1,5 @@
-
from django.contrib import admin
+
from ajax_select.admin import AjaxSelectAdmin, AjaxSelectAdminTabularInline
from tests.models import Author, Book, Person
from tests.test_integration import BookForm
@@ -11,7 +11,6 @@ class BookAdmin(AjaxSelectAdmin):
class BookInline(AjaxSelectAdminTabularInline):
-
model = Book
form = BookForm
extra = 2
@@ -19,7 +18,6 @@ class BookInline(AjaxSelectAdminTabularInline):
@admin.register(Author)
class AuthorAdmin(AjaxSelectAdmin):
-
inlines = [
BookInline
]
diff --git a/tests/lookups.py b/tests/lookups.py
index 3cf2063a80..ecd8919930 100644
--- a/tests/lookups.py
+++ b/tests/lookups.py
@@ -7,13 +7,11 @@
from django.utils.html import escape
import ajax_select
-
from tests.models import Author, Person, PersonWithTitle
@ajax_select.register('person')
class PersonLookup(ajax_select.LookupChannel):
-
model = Person
def get_query(self, q, request):
@@ -31,7 +29,6 @@ def format_item_display(self, obj):
@ajax_select.register('person-with-title')
class PersonWithTitleLookup(ajax_select.LookupChannel):
-
model = PersonWithTitle
def get_query(self, q, request):
@@ -43,7 +40,6 @@ def get_result(self, obj):
@ajax_select.register('user')
class UserLookup(ajax_select.LookupChannel):
-
"""
Test if you can unset a lookup provided by a third-party application.
In this case it exposes User without any auth checking
@@ -68,5 +64,4 @@ def get_query(self, q, request):
@ajax_select.register('author')
class AuthorLookup(ajax_select.LookupChannel):
-
model = Author
diff --git a/tests/models.py b/tests/models.py
index 509d4a781f..cb64e7880a 100644
--- a/tests/models.py
+++ b/tests/models.py
@@ -1,9 +1,7 @@
-
from django.db import models
class Person(models.Model):
-
name = models.CharField(max_length=50)
email = models.EmailField(null=True, blank=True)
@@ -12,7 +10,6 @@ class Meta:
class PersonWithTitle(Person):
-
"""
Testing an inherited model (multi-table)
"""
@@ -24,7 +21,6 @@ class Meta:
class Author(models.Model):
-
name = models.CharField(max_length=50)
class Meta:
@@ -32,7 +28,6 @@ class Meta:
class Book(models.Model):
-
""" Book has no admin, its an inline in the Author admin"""
author = models.ForeignKey(Author, null=True, on_delete=models.CASCADE)
diff --git a/tests/other_lookups.py b/tests/other_lookups.py
index 5ccd740c50..3d7fb8651b 100644
--- a/tests/other_lookups.py
+++ b/tests/other_lookups.py
@@ -5,5 +5,4 @@
class BookLookup(ajax_select.LookupChannel):
-
model = Book
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 412401abb3..41821d568f 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -1,4 +1,5 @@
from django.test import TestCase
+
from ajax_select import fields
from tests.models import Book
diff --git a/tests/test_integration.py b/tests/test_integration.py
index d7bbcc9bf1..22cc0f89e1 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -6,13 +6,15 @@
should be unit tested in test_fields.py
"""
from __future__ import unicode_literals
+
import django
-from django.forms.models import ModelForm
-from django.test import TestCase, Client
from django.contrib.auth.models import User
+from django.forms.models import ModelForm
+from django.test import Client, TestCase
-from tests.models import Book, Author, Person
from ajax_select import fields
+from tests.models import Author, Book, Person
+
try:
from django.urls import reverse
except ImportError:
@@ -26,7 +28,6 @@
class BookForm(ModelForm):
-
class Meta:
model = Book
fields = ['name', 'author', 'mentions_persons']
@@ -147,7 +148,6 @@ def setUp(self):
class TestBookAdmin(TestAdmin):
-
"""
Test the admins in tests/admin.py
"""
@@ -170,7 +170,6 @@ def test_get_blank(self):
class TestAuthorAdmin(TestAdmin):
-
"""
Test an admin with inlines
"""
diff --git a/tests/test_lookups.py b/tests/test_lookups.py
index d17e89dfc8..17ca1a4a29 100644
--- a/tests/test_lookups.py
+++ b/tests/test_lookups.py
@@ -1,4 +1,3 @@
-
from django.contrib.auth.models import User
from django.test import TestCase
diff --git a/tests/test_registry.py b/tests/test_registry.py
index 86e1d5719f..186bfaee1d 100644
--- a/tests/test_registry.py
+++ b/tests/test_registry.py
@@ -1,5 +1,5 @@
-
from django.test import TestCase
+
import ajax_select
@@ -22,7 +22,7 @@ def test_unsetting_a_channel(self):
"""settings can unset a channel that was specified in a lookups.py"""
# self.assertFalse(ajax_select.registry.is_registered('user'))
self.assertFalse(
- ajax_select.registry.is_registered('was-never-a-channel'))
+ ajax_select.registry.is_registered('was-never-a-channel'))
# def test_reimporting_lookup(self):
# """
diff --git a/tests/test_views.py b/tests/test_views.py
index 44931b39bb..144ad51fe7 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -1,14 +1,13 @@
-
-from django.test import TestCase
from django.contrib.auth.models import User
from django.test import Client
+from django.test import TestCase
class TestViews(TestCase):
def setUp(self):
self.user = User.objects.create_superuser(username='admin',
- email='email@example.com',
- password='password')
+ email='email@example.com',
+ password='password')
self.client = Client()
self.client.login(username='admin', password='password')
diff --git a/tests/urls.py b/tests/urls.py
index 8627c3e6f0..bb80a61635 100644
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -1,14 +1,13 @@
-
-from django.conf.urls import url, include
+from django.conf import settings
+from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
-from django.conf import settings
-from ajax_select import urls as ajax_select_urls
+from ajax_select import urls as ajax_select_urls
admin.autodiscover()
urlpatterns = [
- url(r'^ajax_lookups/', include(ajax_select_urls)),
- url(r'^admin/', admin.site.urls),
-] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+ url(r'^ajax_lookups/', include(ajax_select_urls)),
+ url(r'^admin/', admin.site.urls),
+ ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
From 67a958f967b22ac1a8fcc6840ea195c405dd449e Mon Sep 17 00:00:00 2001
From: Ryan Jarvis
Date: Sun, 22 Dec 2019 12:58:59 -0800
Subject: [PATCH 5/6] Flake8: E501 line too long
---
example/example/views.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/example/example/views.py b/example/example/views.py
index a088ae13fd..b605e546d3 100644
--- a/example/example/views.py
+++ b/example/example/views.py
@@ -11,7 +11,8 @@
class SearchForm(forms.Form):
q = AutoCompleteField('cliche',
required=True,
- help_text="Autocomplete will suggest clichés about cats, but you can enter anything you like.",
+ help_text="Autocomplete will suggest clichés about cats, but "
+ "you can enter anything you like.",
label="Favorite Cliché",
attrs={'size': 100})
From 5bfd60aec9d5eef31ee858f48160a00cfd9ded05 Mon Sep 17 00:00:00 2001
From: Chris Sattinger
Date: Sat, 28 Dec 2019 15:51:56 +0100
Subject: [PATCH 6/6] v1.8.0
---
CHANGELOG.md | 4 +++
README.md | 4 +--
setup.py | 77 ++++++++++++++++++++++++++--------------------------
3 files changed, 44 insertions(+), 41 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1e5bcdef8..ee45cc969f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Change Log
+## [1.8.0]
+
+Added/fixed support for Django 2.2
+
## [1.6.1](https://github.com/crucialfelix/django-ajax-selects/tree/1.6.1) (2017-09-09)
[Full Changelog](https://github.com/crucialfelix/django-ajax-selects/compare/1.6.0...1.6.1)
diff --git a/README.md b/README.md
index d6279866e3..ada5a42b84 100644
--- a/README.md
+++ b/README.md
@@ -77,8 +77,8 @@ Read the full documention here: [outside of the admin](http://django-ajax-select
## Compatibility
-* Django >=1.8, <=2.1
-* Python >=2.7, 3.3+
+* Django >=1.8, <3.0
+* Python >=2.7, >=3.5
## Contributors
diff --git a/setup.py b/setup.py
index 36dbdf0da1..5d6d22262c 100644
--- a/setup.py
+++ b/setup.py
@@ -3,42 +3,41 @@
from setuptools import setup
setup(
- name='django-ajax-selects',
- version='1.7.1',
- description='Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.',
- author='Chris Sattinger',
- author_email='crucialfelix@gmail.com',
- url='https://github.com/crucialfelix/django-ajax-selects/',
- packages=['ajax_select'],
- package_data={
- 'ajax_select':
- [
- '*.py',
- '*.txt',
- '*.md',
- 'static/ajax_select/css/*',
- 'static/ajax_select/images/*',
- 'static/ajax_select/js/*',
- 'templates/ajax_select/*.html'
- ]
- },
- include_package_data=True,
- zip_safe=False,
- license="MIT",
- classifiers=[
- "Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 3",
- "Development Status :: 5 - Production/Stable",
- 'Environment :: Web Environment',
- "Intended Audience :: Developers",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- "Topic :: Software Development :: Libraries :: Python Modules",
- "Topic :: Software Development :: User Interfaces",
- "Framework :: Django",
- ],
- long_description="""\
+ name="django-ajax-selects",
+ version="1.8.0",
+ description="Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.",
+ author="Chris Sattinger",
+ author_email="crucialfelix@gmail.com",
+ url="https://github.com/crucialfelix/django-ajax-selects/",
+ packages=["ajax_select"],
+ package_data={
+ "ajax_select": [
+ "*.py",
+ "*.txt",
+ "*.md",
+ "static/ajax_select/css/*",
+ "static/ajax_select/images/*",
+ "static/ajax_select/js/*",
+ "templates/ajax_select/*.html",
+ ]
+ },
+ include_package_data=True,
+ zip_safe=False,
+ license="MIT",
+ classifiers=[
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 3",
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Web Environment",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Topic :: Software Development :: User Interfaces",
+ "Framework :: Django",
+ ],
+ long_description="""\
Edit ForeignKey, ManyToManyField and CharField in Django Admin using jQuery UI AutoComplete.
- Customize search query
@@ -50,7 +49,7 @@
- Integrate with other UI elements elsewhere on the page using the javascript API
- Works in Admin as well as in normal views
-- Django >=1.8, <=2.1
-- Python >=2.7, <=3.7
-"""
+- Django >=1.8, <3.0
+- Python >=2.7, >=3.5
+""",
)