Skip to content

Commit

Permalink
Cleanup old Django references and wildly out of date backwards compat…
Browse files Browse the repository at this point in the history
…ibility
  • Loading branch information
blag committed May 20, 2024
1 parent eadd573 commit 4d290af
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 170 deletions.
116 changes: 62 additions & 54 deletions example/app/test_msf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this software. If not, see <http://www.gnu.org/licenses/>.

from django import VERSION
from django.core.exceptions import ValidationError
from django.forms.models import modelform_factory
from django.test import TestCase
Expand All @@ -23,14 +22,6 @@

from .models import Book, PROVINCES, STATES, PROVINCES_AND_STATES, ONE, TWO

if VERSION < (1, 9):
def get_field(model, name):
return model._meta.get_field_by_name(name)[0]
else:
def get_field(model, name):
return model._meta.get_field(name)


class MultiSelectTestCase(TestCase):

fixtures = ['app_data.json']
Expand All @@ -51,20 +42,10 @@ def test_values_list(self):
tag_list_list = Book.objects.all().values_list('tags', flat=True)
categories_list_list = Book.objects.all().values_list('categories', flat=True)

# Workaround for Django bug #9619
# https://code.djangoproject.com/ticket/9619
# For Django 1.6 and 1.7, calling values() or values_list() doesn't
# call Field.from_db_field, it simply returns a Python representation
# of the data in the database (which in our case is a string of
# comma-separated values). The bug was fixed in Django 1.8+.
if VERSION >= (1, 6) and VERSION < (1, 8):
self.assertStringEqual(tag_list_list, [str('sex,work,happy')])
self.assertStringEqual(categories_list_list, [str('1,3,5')])
else:
# assertCountEqual also ensures that the elements are the same (ignoring list order)
# https://docs.python.org/3.2/library/unittest.html#unittest.TestCase.assertCountEqual
self.assertCountEqual(tag_list_list, [['sex', 'work', 'happy']])
self.assertCountEqual(categories_list_list, [['1', '3', '5']])
# assertCountEqual also ensures that the elements are the same (ignoring list order)
# https://docs.python.org/3.2/library/unittest.html#unittest.TestCase.assertCountEqual
self.assertCountEqual(tag_list_list, [['sex', 'work', 'happy']])
self.assertCountEqual(categories_list_list, [['1', '3', '5']])

def test_form(self):
form_class = modelform_factory(Book, fields=('title', 'tags', 'categories'))
Expand Down Expand Up @@ -107,65 +88,92 @@ def test_object(self):

def test_validate(self):
book = Book.objects.get(id=1)
get_field(Book, 'tags').clean(['sex', 'work'], book)
Book._meta.get_field('tags').clean(['sex', 'work'], book)
try:
get_field(Book, 'tags').clean(['sex1', 'work'], book)
Book._meta.get_field('tags').clean(['sex1', 'work'], book)
raise AssertionError()
except ValidationError:
pass

get_field(Book, 'categories').clean(['1', '2', '3'], book)
Book._meta.get_field('categories').clean(['1', '2', '3'], book)
try:
get_field(Book, 'categories').clean(['1', '2', '3', '4'], book)
Book._meta.get_field('categories').clean(['1', '2', '3', '4'], book)
raise AssertionError()
except ValidationError:
pass
try:
get_field(Book, 'categories').clean(['11', '12', '13'], book)
Book._meta.get_field('categories').clean(['11', '12', '13'], book)
raise AssertionError()
except ValidationError:
pass

def test_serializer(self):
book = Book.objects.get(id=1)
self.assertEqual(get_field(Book, 'tags').value_to_string(book), 'sex,work,happy')
self.assertEqual(get_field(Book, 'categories').value_to_string(book), '1,3,5')
self.assertEqual(Book._meta.get_field('tags').value_to_string(book), 'sex,work,happy')
self.assertEqual(Book._meta.get_field('categories').value_to_string(book), '1,3,5')

def test_flatchoices(self):
self.assertEqual(get_field(Book, 'published_in').flatchoices, list(PROVINCES + STATES))
self.assertEqual(Book._meta.get_field('published_in').flatchoices, list(PROVINCES + STATES))

def test_named_groups(self):
self.assertEqual(get_field(Book, 'published_in').choices, PROVINCES_AND_STATES)
self.assertEqual(Book._meta.published_in.choices, PROVINCES_AND_STATES)

def test_named_groups_form(self):
form_class = modelform_factory(Book, fields=('published_in',))
self.assertEqual(len(form_class.base_fields), 1)
form = form_class(initial={'published_in': ['BC', 'AK']})

expected_html = str(
"""<p><label for="id_published_in_0">Province or State:</label> <ul id="id_published_in"><li>Canada - Provinces<ul id="id_published_in_0"><li><label for="id_published_in_0_0"><input id="id_published_in_0_0" name="published_in" type="checkbox" value="AB" /> Alberta</label></li>\n"""
"""<li><label for="id_published_in_0_1"><input checked="checked" id="id_published_in_0_1" name="published_in" type="checkbox" value="BC" /> British Columbia</label></li></ul></li>\n"""
"""<li>USA - States<ul id="id_published_in_1"><li><label for="id_published_in_1_0"><input checked="checked" id="id_published_in_1_0" name="published_in" type="checkbox" value="AK" /> Alaska</label></li>\n"""
"""<li><label for="id_published_in_1_1"><input id="id_published_in_1_1" name="published_in" type="checkbox" value="AL" /> Alabama</label></li>\n"""
"""<li><label for="id_published_in_1_2"><input id="id_published_in_1_2" name="published_in" type="checkbox" value="AZ" /> Arizona</label></li></ul></li></ul></p>"""
)
expected_html = """
<p>
<label>
Province or State:
</label>
<div id="id_published_in">
<div>
<label>
Canada - Provinces
</label>
<div>
<label for="id_published_in_0_0">
<input id="id_published_in_0_0" name="published_in" type="checkbox" value="AB" />
Alberta
</label>
</div>
<div>
<label for="id_published_in_0_1">
<input checked id="id_published_in_0_1" name="published_in" type="checkbox" value="BC" />
British Columbia
</label>
</div>
</div>
<div>
<label>
USA - States
</label>
<div>
<label for="id_published_in_1_0">
<input checked id="id_published_in_1_0" name="published_in" type="checkbox" value="AK" />
Alaska
</label>
</div>
<div>
<label for="id_published_in_1_1">
<input id="id_published_in_1_1" name="published_in" type="checkbox" value="AL" />
Alabama
</label>
</div>
<div>
<label for="id_published_in_1_2">
<input id="id_published_in_1_2" name="published_in" type="checkbox" value="AZ" />
Arizona
</label>
</div>
</div>
</div>
</p>
"""

actual_html = form.as_p()
if (1, 11) <= VERSION:
# Django 1.11+ does not assign 'for' attributes on labels if they
# are group labels
expected_html = expected_html.replace('label for="id_published_in_0"', 'label')

if VERSION < (1, 6):
# Django 1.6 renders the Python repr() for each group (eg: tuples
# with HTML entities), so we skip the test for that version
self.assertEqual(expected_html.replace('\n', ''), actual_html.replace('\n', ''))

if VERSION >= (2, 0):
expected_html = expected_html.replace('input checked="checked"', 'input checked')

if VERSION >= (1, 7):
self.assertHTMLEqual(expected_html, actual_html)
self.assertHTMLEqual(expected_html, actual_html)


Expand Down
34 changes: 5 additions & 29 deletions example/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,11 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this software. If not, see <http://www.gnu.org/licenses/>.

from django import VERSION
try:
from django.conf.urls import url

# Compatibility for Django > 1.8
def patterns(prefix, *args):
if VERSION < (1, 9):
from django.conf.urls import patterns as django_patterns
return django_patterns(prefix, *args)
elif prefix != '':
raise NotImplementedError("You need to update your URLConf for "
"Django 1.10, or tweak it to remove the "
"prefix parameter")
else:
return list(args)
except ImportError: # Django < 1.4
if VERSION < (4, 0):
from django.conf.urls.defaults import patterns, url
else:
from django.urls import re_path as url
from django.urls import path

from .views import app_index

if VERSION < (1, 11):
urlpatterns = patterns(
'',
url(r'^$', app_index, name='app_index'),
)
else:
urlpatterns = [
url(r'^$', app_index, name='app_index'),
]

urlpatterns = [
path('', app_index, name='app_index'),
]
93 changes: 31 additions & 62 deletions example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import os
from os import path

from django import VERSION

DEBUG = True

BASE_DIR = path.dirname(path.abspath(__file__))
Expand Down Expand Up @@ -121,57 +119,30 @@
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'example.wsgi.application'

if VERSION < (1, 8):
TEMPLATE_DEBUG = DEBUG

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)

TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.request',
'django.core.context_processors.tz',
'django.core.context_processors.static',
'django.contrib.messages.context_processors.messages',
)
else:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
'debug': DEBUG,
'loaders': [
# List of callables that know how to import templates from
# various sources.
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]
},
}
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
'debug': DEBUG,
'loaders': [
# List of callables that know how to import templates from
# various sources.
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]
},
}
]

INSTALLED_APPS = (
'django.contrib.auth',
Expand Down Expand Up @@ -227,13 +198,11 @@
}
}

if VERSION >= (1, 4):
LOGGING['filters'] = {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
}
LOGGING['handlers']['mail_admins']['filters'] = ['require_debug_false']
LOGGING['filters'] = {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse',
},
}
LOGGING['handlers']['mail_admins']['filters'] = ['require_debug_false']

if VERSION >= (1, 6):
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
7 changes: 1 addition & 6 deletions example/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import os
import sys

import django
from django.conf import ENVIRONMENT_VARIABLE
from django.core import management
from django.core.wsgi import get_wsgi_application
Expand All @@ -30,10 +29,6 @@
else:
os.environ[ENVIRONMENT_VARIABLE] = sys.argv[1]

if django.VERSION[0] == 1 and django.VERSION[1] >= 7:
from django.core.wsgi import get_wsgi_application as get_wsgi_application_v1
application = get_wsgi_application_v1()
else:
application = get_wsgi_application()
application = get_wsgi_application()

management.call_command('test', 'app')
24 changes: 5 additions & 19 deletions multiselectfield/db/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this programe. If not, see <http://www.gnu.org/licenses/>.

from django import VERSION

from django.db import models
from django.utils.text import capfirst
from django.core import exceptions
Expand Down Expand Up @@ -101,10 +99,7 @@ def validate(self, value, model_instance):
arr_choices = self.get_choices_selected(self.get_choices_default())
for opt_select in value:
if (opt_select not in arr_choices):
if VERSION >= (1, 6):
raise exceptions.ValidationError(self.error_messages['invalid_choice'] % {"value": value})
else:
raise exceptions.ValidationError(self.error_messages['invalid_choice'] % value)
raise exceptions.ValidationError(self.error_messages['invalid_choice'] % {"value": value})

def get_default(self):
default = super(MultiSelectField, self).get_default()
Expand Down Expand Up @@ -146,16 +141,10 @@ def to_python(self, value):
return MSFList(choices, list(value))
return MSFList(choices, [])

if VERSION < (2, ):
def from_db_value(self, value, expression, connection, context):
if value is None:
return value
return self.to_python(value)
else:
def from_db_value(self, value, expression, connection):
if value is None:
return value
return self.to_python(value)
def from_db_value(self, value, expression, connection):
if value is None:
return value
return self.to_python(value)

def contribute_to_class(self, cls, name):
super(MultiSelectField, self).contribute_to_class(cls, name)
Expand Down Expand Up @@ -183,9 +172,6 @@ def get_display(obj):
setattr(cls, 'get_%s_display' % self.name, get_display)


if VERSION < (1, 8):
MultiSelectField = add_metaclass(models.SubfieldBase)(MultiSelectField)

try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ['^multiselectfield\.db.fields\.MultiSelectField'])
Expand Down

0 comments on commit 4d290af

Please sign in to comment.