Skip to content

Commit

Permalink
Drop Django 1.5/1.6 compatibility and Python 2.6 support
Browse files Browse the repository at this point in the history
There isn't much point in maintaining this,
and it adds a burden to new contributors.
  • Loading branch information
vdboor committed May 1, 2017
1 parent 7055613 commit 1bbe987
Show file tree
Hide file tree
Showing 23 changed files with 37 additions and 254 deletions.
13 changes: 0 additions & 13 deletions .travis.yml
Expand Up @@ -5,27 +5,14 @@ python:
- '3.4'
- '3.3'
- '2.7'
- '2.6'
env:
- DJANGO="django>=1.5.0,<1.6.0"
- DJANGO="django>=1.6.0,<1.7.0"
- DJANGO="django>=1.7.0,<1.8.0"
- DJANGO="django>=1.8.0,<1.9.0"
- DJANGO="django>=1.9.0,<1.10.0"
- DJANGO="django>=1.10.0,<1.11.0"
- DJANGO="django>=1.11.0,<1.12.0"
matrix:
exclude:
- python: '2.6'
env: DJANGO="django>=1.7.0,<1.8.0"
- python: '2.6'
env: DJANGO="django>=1.8.0,<1.9.0"
- python: '2.6'
env: DJANGO="django>=1.9.0,<1.10.0"
- python: '2.6'
env: DJANGO="django>=1.10.0,<1.11.0"
- python: '2.6'
env: DJANGO="django>=1.11.0,<1.12.0"
- python: '3.3'
env: DJANGO="django>=1.4.0,<1.5.0"
- python: '3.3'
Expand Down
6 changes: 2 additions & 4 deletions fluent_contents/admin/contentitems.py
@@ -1,12 +1,10 @@
import django
from django.contrib.contenttypes.admin import BaseGenericInlineFormSet, GenericInlineModelAdmin

from fluent_contents import extensions, appsettings
from fluent_contents.forms import ContentItemForm
from fluent_contents.models import Placeholder, get_parent_language_code

try:
from django.contrib.contenttypes.admin import BaseGenericInlineFormSet, GenericInlineModelAdmin # Django 1.7
except ImportError:
from django.contrib.contenttypes.generic import BaseGenericInlineFormSet, GenericInlineModelAdmin


class BaseContentItemFormSet(BaseGenericInlineFormSet):
Expand Down
6 changes: 1 addition & 5 deletions fluent_contents/admin/genericextensions.py
@@ -1,12 +1,8 @@
from django.contrib.contenttypes.forms import BaseGenericInlineFormSet
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.forms.formsets import ManagementForm

try:
from django.contrib.contenttypes.forms import BaseGenericInlineFormSet # Django 1.7
except ImportError:
from django.contrib.contenttypes.generic import BaseGenericInlineFormSet



class BaseInitialGenericInlineFormSet(BaseGenericInlineFormSet):
Expand Down
32 changes: 5 additions & 27 deletions fluent_contents/admin/placeholdereditor.py
Expand Up @@ -4,6 +4,7 @@
from django.conf.urls import url
from django.contrib.admin import ModelAdmin
from django.contrib.admin.helpers import InlineAdminFormSet
from django.contrib.contenttypes.admin import GenericInlineModelAdmin
from django.core.exceptions import ImproperlyConfigured
from django.db.models import signals
from django.dispatch import receiver
Expand All @@ -18,11 +19,6 @@
from fluent_contents.models.managers import get_parent_active_language_choices
from fluent_utils.ajax import JsonResponse

try:
from django.contrib.contenttypes.admin import GenericInlineModelAdmin # Django 1.7
except ImportError:
from django.contrib.contenttypes.generic import GenericInlineModelAdmin


class PlaceholderInlineFormSet(BaseInitialGenericInlineFormSet):
# Most logic happens in the generic base class
Expand Down Expand Up @@ -192,9 +188,6 @@ def get_inline_instances(self, request, *args, **kwargs):
"""
Create the inlines for the admin, including the placeholder and contentitem inlines.
"""
# Django 1.3: inlines were created once in self.inline_instances (not supported anymore)
# Django 1.4: inlines are created per request
# Django 1.5: 'obj' parameter was added so it can be passed to 'has_change_permission' and friends.
inlines = super(PlaceholderEditorAdmin, self).get_inline_instances(request, *args, **kwargs)

extra_inline_instances = []
Expand All @@ -214,7 +207,8 @@ def get_extra_inlines(self):

def get_urls(self):
urls = super(PlaceholderEditorAdmin, self).get_urls()
info = _get_url_format(self.model._meta)
opts = self.model._meta
info = opts.app_label, opts.model_name
return [
url(
r'^(?P<object_id>\d+)/api/get_placeholder_data/',
Expand Down Expand Up @@ -256,12 +250,7 @@ def _get_object_formset_data(self, request, obj):
placeholder_slots = dict(Placeholder.objects.parent(obj).values_list('id', 'slot'))
all_forms = []

if django.VERSION >= (1,7):
formsets_with_inlines = self.get_formsets_with_inlines(request, obj=obj)
else:
# Removed in Django 1.9:
formsets_with_inlines = zip(self.get_formsets(request, obj), inline_instances)

formsets_with_inlines = self.get_formsets_with_inlines(request, obj=obj)
for FormSet, inline in formsets_with_inlines:
# Only ContentItem inlines
if isinstance(inline, PlaceholderEditorInline) \
Expand All @@ -281,11 +270,7 @@ def _get_contentitem_formset_html(self, request, obj, FormSet, inline, placehold
# as some form fields (e.g. picture field or MultiValueField) have a different representation.
# The only way to pass a form copy to the client is by actually rendering it.
# Hence, emulating change_view code here:
if django.VERSION >= (1, 6):
queryset = inline.get_queryset(request)
else:
queryset = inline.queryset(request)

queryset = inline.get_queryset(request)
formset = FormSet(instance=obj, prefix='', queryset=queryset)
fieldsets = list(inline.get_fieldsets(request, obj))
readonly = list(inline.get_readonly_fields(request, obj))
Expand Down Expand Up @@ -349,10 +334,3 @@ def save_formset(self, request, form, formset, change):
def _get_pk_on_placeholder_delete(instance, **kwargs):
# Make sure the old PK can still be tracked
instance._old_pk = instance.pk


def _get_url_format(opts):
try:
return opts.app_label, opts.model_name # Django 1.7 format
except AttributeError:
return opts.app_label, opts.module_name
8 changes: 0 additions & 8 deletions fluent_contents/extensions/model_fields.py
Expand Up @@ -34,14 +34,6 @@ def _get_path(cls):

class MigrationMixin(object):

def south_field_triple(self):
# Undo the softdep feature
# Show as Plugin..Field in the migrations.
from south.modelsinspector import introspector
path = _get_path(self.__class__)
args, kwargs = introspector(self)
return (path, args, kwargs)

def deconstruct(self):
# Don't masquerade as optional field like fluent-utils does,
# Show as Plugin..Field in the migrations.
Expand Down
6 changes: 1 addition & 5 deletions fluent_contents/forms/widgets.py
@@ -1,4 +1,5 @@
from django.contrib.admin.widgets import AdminTextareaWidget
from django.forms.utils import flatatt
from django.forms.widgets import Widget
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
Expand All @@ -7,11 +8,6 @@
from fluent_contents.models.managers import get_parent_active_language_choices
from fluent_utils.django_compat import smart_text

try:
from django.forms.utils import flatatt # Django 1.7+
except ImportError:
from django.forms.util import flatatt # Django 1.6-


class PlaceholderFieldWidget(Widget):
"""
Expand Down
9 changes: 1 addition & 8 deletions fluent_contents/models/__init__.py
Expand Up @@ -15,6 +15,7 @@
"""
from future.builtins import str
from future.utils import python_2_unicode_compatible
from django.core.cache.backends.base import DEFAULT_TIMEOUT
from django.forms import Media
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe, SafeData
Expand All @@ -31,14 +32,6 @@

_ALLOWED_ROLES = list(dict(Placeholder.ROLES).keys())

try:
# Django 1.6 started using a sentinel value to indicate the default.
# The values 0 and None became allowed values which mean set+forget and indefinitely.
from django.core.cache.backends.base import DEFAULT_TIMEOUT
except ImportError:
# Provide the value for older Django versions in a compatible way.
DEFAULT_TIMEOUT = object()


class PlaceholderData(object):
"""
Expand Down
6 changes: 3 additions & 3 deletions fluent_contents/models/db.py
Expand Up @@ -151,8 +151,8 @@ def get_absolute_url(self):
return None

def delete(self, using=None):
# Workaround for the fact that South 0.7.4 does not support on_delete=SET_NULL yet
# It doesn't add that attribute to the foreign key, causing a DatabaseError instead.
# Some databases may not have a proper ON DELETE rule set, causing a DatabaseError on delete.
# This happened because South 0.7.4 didn't support on_delete=SET_NULL.
ContentItem.objects.filter(placeholder=self).update(placeholder=None)
super(Placeholder, self).delete(using)

Expand All @@ -177,7 +177,7 @@ def __new__(mcs, name, bases, attrs):
model_name = db_table[len(app_label) + 1:]
new_class._meta.db_table = truncate_name("contentitem_%s_%s" % (app_label, model_name), connection.ops.max_name_length())
if hasattr(new_class._meta, 'original_attrs'):
# Make sure that the Django 1.7 migrations also pick up this change!
# Make sure that the Django migrations also pick up this change!
# Changing the db_table beforehand might be cleaner,
# but also requires duplicating the whole algorithm that Django uses.
new_class._meta.original_attrs['db_table'] = new_class._meta.db_table
Expand Down
35 changes: 6 additions & 29 deletions fluent_contents/models/fields.py
Expand Up @@ -83,19 +83,12 @@ def __init__(self, field, to, related_name=None, related_query_name=None, limit_
)

# TODO: make sure reverse queries work properly
if django.VERSION >= (1, 6, 0):
super(PlaceholderRel, self).__init__(
field=field,
to=Placeholder,
related_name=None, # NOTE: must be unique for app/model/slot.
limit_choices_to=limit_choices_to
)
else:
super(PlaceholderRel, self).__init__(
to=Placeholder,
related_name=None, # NOTE: must be unique for app/model/slot.
limit_choices_to=limit_choices_to
)
super(PlaceholderRel, self).__init__(
field=field,
to=Placeholder,
related_name=None, # NOTE: must be unique for app/model/slot.
limit_choices_to=limit_choices_to
)


class PlaceholderFieldDescriptor(object):
Expand Down Expand Up @@ -250,19 +243,3 @@ def value_from_object(self, obj):
return None # Still allow ModelForm / admin to open and create a new Placeholder if the table was truncated.

return placeholder.id if placeholder else None # Be consistent with other fields, like ForeignKey


if django.VERSION < (1, 7):
try:
from south.modelsinspector import add_ignored_fields
except ImportError:
pass
else:
# South 0.7.x ignores GenericRelation fields but doesn't ignore subclasses.
# Taking the same fix as applied in http://south.aeracode.org/ticket/414
_name_re = "^" + __name__.replace(".", "\.")
add_ignored_fields((
_name_re + "\.PlaceholderField",
_name_re + "\.PlaceholderRelation",
_name_re + "\.ContentItemRelation",
))
8 changes: 1 addition & 7 deletions fluent_contents/models/managers.py
Expand Up @@ -21,11 +21,8 @@ def parent(self, parent_object):
"""
Return all placeholders which are associated with a given parent object.
"""
# NOTE: by using .all(), the correct get_queryset() or get_query_set() method is called.
# Just calling self.get_queryset() will break the RelatedManager.get_query_set() override in Django 1.5
# This avoids all issues with Django 1.5/1.6/1.7 compatibility.
lookup = get_parent_lookup_kwargs(parent_object)
return self.all().filter(**lookup)
return self.filter(**lookup)

def get_by_slot(self, parent_object, slot):
"""
Expand Down Expand Up @@ -155,9 +152,6 @@ def translated(self, *language_codes):
When no language codes are given, only the currently active language is returned.
"""
# NOTE: by using .all(), the correct get_queryset() or get_query_set() method is called.
# Just calling self.get_queryset() will break the RelatedManager.get_query_set() override in Django 1.5
# This avoids all issues with Django 1.5/1.6/1.7 compatibility.
return self.all().translated(language_codes)

def parent(self, parent_object, limit_parent_language=True):
Expand Down
23 changes: 0 additions & 23 deletions fluent_contents/plugins/disquswidgets/__init__.py
@@ -1,24 +1 @@
import django
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

VERSION = (0, 1)

if django.VERSION < (1, 7):
# TODO: this needs to be ported to system checks
# providing these checks at import time breaks Django 1.7

backendapp = 'disqus'

# Do some settings checks.
if backendapp not in settings.INSTALLED_APPS:
raise ImproperlyConfigured("The '{0}' application is required to use the '{1}' plugin.".format(backendapp, 'disqusarea'))

try:
import disqus
except ImportError:
raise ImproperlyConfigured("The 'django-disqus' package is required to use the 'disqusarea' plugin.")

for varname in ('DISQUS_API_KEY', 'DISQUS_WEBSITE_SHORTNAME'):
if not getattr(settings, varname, None):
raise ImproperlyConfigured("The '{0}' setting is required to use the '{1}' plugin.".format(varname, 'disqusarea'))
19 changes: 0 additions & 19 deletions fluent_contents/plugins/formdesignerlink/__init__.py
@@ -1,20 +1 @@
import django
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

VERSION = (0, 1)

if django.VERSION < (1, 7):
# TODO: this needs to be ported to system checks
# providing these checks at import time breaks Django 1.7

backendapp = 'form_designer'

# Do some settings checks.
if backendapp not in settings.INSTALLED_APPS:
raise ImproperlyConfigured("The '{0}' application is required to use the '{1}' plugin.".format(backendapp, 'formdesignerlink'))

try:
import form_designer
except ImportError as e:
raise ImproperlyConfigured("The 'django-form-designer' package is required to use the 'formdesignerlink' plugin.")
5 changes: 0 additions & 5 deletions fluent_contents/plugins/markup/models.py
@@ -1,4 +1,3 @@
import django
from future.utils import python_2_unicode_compatible
from django.core.exceptions import ValidationError
from django.db import models
Expand Down Expand Up @@ -65,10 +64,6 @@ def __init__(self, fixed_language):
def get_queryset(self):
return super(MarkupLanguageManager, self).get_queryset().filter(language=self.fixed_language)

if django.VERSION < (1, 6):
def get_query_set(self):
return super(MarkupLanguageManager, self).get_query_set().filter(language=self.fixed_language)


def _create_markup_model(fixed_language):
"""
Expand Down
10 changes: 0 additions & 10 deletions fluent_contents/plugins/oembeditem/fields.py
@@ -1,4 +1,3 @@
import django
from django.core.exceptions import ValidationError
from django.db.models import URLField
from django.utils.translation import ugettext_lazy as _
Expand All @@ -23,12 +22,3 @@ def clean(self, *args, **kwargs):
raise ValidationError(_("The URL is not valid for embedding content")) # or is not configured as provider.

return url


if django.VERSION < (1, 7):
try:
from south.modelsinspector import add_introspection_rules
except ImportError:
pass
else:
add_introspection_rules([], ["^" + __name__.replace(".", "\.") + "\.OEmbedUrlField"])
5 changes: 2 additions & 3 deletions fluent_contents/plugins/sharedcontent/admin.py
Expand Up @@ -26,8 +26,7 @@ def get_prepopulated_fields(self, request, obj=None):
'slug': ('title',)
}

# Using declared_fieldsets for Django 1.4, otherwise fieldsets= would work too.
declared_fieldsets = (
fieldsets = (
(None, {
'fields': ('title', 'contents')
}),
Expand All @@ -38,7 +37,7 @@ def get_prepopulated_fields(self, request, obj=None):
)

if sharedcontent_appsettings.FLUENT_SHARED_CONTENT_ENABLE_CROSS_SITE:
declared_fieldsets[1][1]['fields'] += ('is_cross_site',)
fieldsets[1][1]['fields'] += ('is_cross_site',)


admin.site.register(SharedContent, SharedContentAdmin)

0 comments on commit 1bbe987

Please sign in to comment.