Permalink
Browse files

Introduced Django 2.0 & 2.1 support (#6402)

  • Loading branch information...
toffi9 authored and czpython committed Jul 13, 2018
1 parent 8964d77 commit 50dee524a1789d2259d760ba6726072907bad36b
Showing with 489 additions and 516 deletions.
  1. +60 −61 .travis.yml
  2. +2 −0 CHANGELOG.txt
  3. +1 −1 cms/admin/forms.py
  4. +26 −9 cms/admin/pageadmin.py
  5. +13 −1 cms/admin/permissionadmin.py
  6. +25 −3 cms/admin/placeholderadmin.py
  7. +6 −0 cms/admin/useradmin.py
  8. +26 −13 cms/appresolver.py
  9. +1 −1 cms/cache/page.py
  10. +3 −3 cms/cms_menus.py
  11. +1 −1 cms/cms_toolbars.py
  12. +1 −1 cms/extensions/admin.py
  13. +1 −1 cms/extensions/toolbar.py
  14. +1 −1 cms/forms/fields.py
  15. +4 −4 cms/forms/widgets.py
  16. +12 −4 cms/management/commands/subcommands/base.py
  17. +2 −2 cms/middleware/toolbar.py
  18. +2 −7 cms/migrations/0018_create_pagenode.py
  19. +1 −1 cms/migrations/0019_set_pagenode.py
  20. +1 −1 cms/migrations/0020_old_tree_cleanup.py
  21. +27 −0 cms/migrations/0022_auto_20180620_1551.py
  22. +12 −0 cms/migrations/__init__.py
  23. +0 −12 cms/migrations/_base.py
  24. +11 −7 cms/models/pagemodel.py
  25. +2 −2 cms/models/permissionmodels.py
  26. +2 −2 cms/models/placeholdermodel.py
  27. +4 −3 cms/models/pluginmodel.py
  28. +1 −1 cms/page_rendering.py
  29. +3 −1 cms/signals/apphook.py
  30. +2 −2 cms/signals/permissions.py
  31. +7 −3 cms/templatetags/cms_tags.py
  32. +1 −1 cms/test_utils/project/extensionapp/cms_toolbars.py
  33. +1 −1 cms/test_utils/project/fakemlng/models.py
  34. +3 −3 cms/test_utils/project/fourth_urls_for_apphook_tests.py
  35. +2 −2 cms/test_utils/project/noadmin_urls.py
  36. +3 −3 cms/test_utils/project/nonroot_urls.py
  37. +2 −2 cms/test_utils/project/objectpermissionsapp/backends.py
  38. +3 −3 cms/test_utils/project/objectpermissionsapp/models.py
  39. +1 −9 cms/test_utils/project/placeholderapp/admin.py
  40. +1 −0 cms/test_utils/project/placeholderapp/cms_plugins.py
  41. +1 −18 cms/test_utils/project/placeholderapp/models.py
  42. +0 −8 cms/test_utils/project/placeholderapp/urls_multi.py
  43. +1 −25 cms/test_utils/project/placeholderapp/views.py
  44. +4 −5 cms/test_utils/project/placeholderapp_urls.py
  45. +6 −6 cms/test_utils/project/pluginapp/plugins/manytomany_rel/models.py
  46. +5 −5 cms/test_utils/project/pluginapp/plugins/revdesc/models.py
  47. +2 −2 cms/test_utils/project/sampleapp/cms_apps.py
  48. +1 −1 cms/test_utils/project/sampleapp/cms_menus.py
  49. +5 −4 cms/test_utils/project/sampleapp/models.py
  50. +2 −0 cms/test_utils/project/sampleapp/urls_example.py
  51. +2 −2 cms/test_utils/project/sampleapp/urls_excluded.py
  52. +3 −2 cms/test_utils/project/second_cms_urls_for_apphook_tests.py
  53. +3 −3 cms/test_utils/project/second_urls_for_apphook_tests.py
  54. +3 −3 cms/test_utils/project/third_urls_for_apphook_tests.py
  55. +7 −7 cms/test_utils/project/urls.py
  56. +3 −3 cms/test_utils/project/urls_2.py
  57. +3 −3 cms/test_utils/project/urls_3.py
  58. +3 −3 cms/test_utils/project/urls_for_apphook_tests.py
  59. +3 −3 cms/test_utils/project/urls_no18n.py
  60. +3 −3 cms/test_utils/testcases.py
  61. +2 −2 cms/test_utils/util/context_managers.py
  62. +5 −4 cms/tests/test_admin.py
  63. +1 −1 cms/tests/test_apphooks.py
  64. +2 −2 cms/tests/test_cache.py
  65. +2 −2 cms/tests/test_fixture_loading.py
  66. +1 −1 cms/tests/test_no_i18n.py
  67. +2 −2 cms/tests/test_page.py
  68. +5 −5 cms/tests/test_page_admin.py
  69. +17 −8 cms/tests/test_permmod.py
  70. +10 −10 cms/tests/test_plugins.py
  71. +1 −1 cms/tests/test_publisher.py
  72. +7 −133 cms/tests/test_toolbar.py
  73. +2 −2 cms/tests/test_views.py
  74. +1 −1 cms/tests/test_wizards.py
  75. +1 −1 cms/toolbar/toolbar.py
  76. +1 −1 cms/utils/apphook_reload.py
  77. +2 −0 cms/utils/compat/__init__.py
  78. +14 −0 cms/utils/compat/dj.py
  79. +1 −1 cms/utils/decorators.py
  80. +1 −1 cms/utils/helpers.py
  81. +11 −5 cms/utils/i18n.py
  82. +1 −1 cms/utils/moderator.py
  83. +1 −1 cms/utils/page.py
  84. +3 −3 cms/utils/page_permissions.py
  85. +15 −5 cms/utils/permissions.py
  86. +1 −1 cms/utils/urlutils.py
  87. +7 −7 cms/views.py
  88. +2 −2 cms/wizards/views.py
  89. +2 −6 cms/wizards/wizard_base.py
  90. +1 −1 docs/how_to/extending_page_title.rst
  91. +4 −4 docs/how_to/languages.rst
  92. +1 −1 docs/how_to/testing.rst
  93. +4 −4 docs/how_to/toolbar.rst
  94. +1 −1 docs/introduction/07-menu.rst
  95. +0 −2 manage.py
  96. +2 −2 menus/menu_pool.py
  97. +2 −2 menus/modifiers.py
  98. +1 −1 menus/templatetags/menu_tags.py
  99. +1 −1 menus/utils.py
  100. +6 −4 setup.py
  101. +0 −3 test_requirements/django-1.11.txt
  102. +2 −0 test_requirements/django-2.0.txt
  103. +2 −0 test_requirements/django-2.1.txt
  104. +4 −3 test_requirements/requirements_base.txt
@@ -29,18 +29,66 @@ env:
- secure: CbPfysSncBB2Ue+VOtLDa8xJvwKl73nJO647zt/9UvZ/3PilnZN9aZv2jHxGvCiFXcez+2AddKptMCcx/5EW5UfRkrWUDHrfLCULU2TfOjmufEGM1eOIXhiAun8WQ85LBzTAYy1r9D514cbU3Yzn3xGZwJljPE8JE4cx3MNN/qQ=
# temporary solution until https://github.com/ariya/phantomjs/issues/13953 is resolved
- PHANTOMJS_CDNURL=https://s3.amazonaws.com/aldryn-local-assets
matrix:
- FRONTEND=1 UNIT=1
- FRONTEND=1 LINT=1
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
- TEST_DOCS=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
matrix:
include:
# FRONTEND
- python: 3.6
env: FRONTEND=1 UNIT=1
- python: 3.6
env: FRONTEND=1 LINT=1
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.6
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
# DJANGO 1.11
- python: 2.7
env: DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.5
env: DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.6
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
# DJANGO 2.0
- python: 3.4
env: DJANGO=2.0 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.5
env: DJANGO=2.0 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=2.0 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=2.0 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.6
env: DJANGO=2.0 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
# DJANGO 2.1
- python: 3.5
env: DJANGO=2.1 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.5
env: DJANGO=2.1 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=2.1 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- python: 3.6
env: DJANGO=2.1 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.6
env: DJANGO=2.1 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
- python: 3.6
env: TEST_DOCS=1 DJANGO=2.1 DATABASE_URL='sqlite://localhost/:memory:'
exclude:
- python: 2.7
- python: 3.4
- python: 3.5
- python: 3.6
fast_finish: true
before_script:
- pip freeze
@@ -79,52 +127,3 @@ notifications:
- irc.freenode.org#django-cms-sprint
webhooks:
- http://addons.us-iad-rs.aldryn.io/en/travis-endpoint/
matrix:
exclude:
- python: 3.4
env: TEST_DOCS=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.4
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.4
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.4
env: FRONTEND=1 UNIT=1
- python: 3.4
env: FRONTEND=1 LINT=1
- python: 3.5
env: TEST_DOCS=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/:memory:'
- python: 3.5
env: DJANGO=1.11 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test'
- python: 3.5
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test'
- python: 3.5
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.5
env: DJANGO=1.11 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' AUTH_USER_MODEL='customuserapp.User'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=1 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=2 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.5
env: FRONTEND=1 INTEGRATION=1 INTEGRATION_TESTS_BUCKET=3 DJANGO=1.11 DATABASE_URL='sqlite://localhost/testdb.sqlite'
- python: 3.5
env: FRONTEND=1 UNIT=1
- python: 3.5
env: FRONTEND=1 LINT=1
fast_finish: true
@@ -7,6 +7,8 @@
* Moved ``Title.meta_description`` length restriction from model to form
and increased its max length to 320 characters.
* Added ``page_title`` parameter for ``cms.api.create_page()`` and ``cms.api.create_title()``.
* Introduced Django 2.0 support.
* Introduced Django 2.1 support.
=== 3.5.2 (2018-04-11) ===
@@ -506,7 +506,7 @@ class AdvancedSettingsForm(forms.ModelForm):
redirect = PageSmartLinkField(label=_('Redirect'), required=False,
help_text=_('Redirects to this URL.'),
placeholder_text=_('Start typing...'),
ajax_view='admin:cms_page_get_published_pagelist'
ajax_view='admin:cms_page_get_published_pagelist',
)
# This is really a 'fake' field which does not correspond to any Page attribute
@@ -73,6 +73,7 @@
get_site_language_from_request,
)
from cms.utils.admin import jsonify_request
from cms.utils.compat import DJANGO_2_0
from cms.utils.conf import get_cms_setting
from cms.utils.urlutils import admin_reverse
@@ -442,8 +443,19 @@ def delete_view(self, request, object_id, extra_context=None):
# Populate deleted_objects, a data structure of all related objects that
# will also be deleted.
objs = [obj] + list(obj.get_descendant_pages())
if DJANGO_2_0:
get_deleted_objects_additional_kwargs = {
'opts': opts,
'using': using,
'user': request.user,
}
else:
get_deleted_objects_additional_kwargs = {'request': request}
(deleted_objects, model_count, perms_needed, protected) = get_deleted_objects(
objs, opts, request.user, self.admin_site, using)
objs, admin_site=self.admin_site,
**get_deleted_objects_additional_kwargs
)
if request.POST and not protected: # The user has confirmed the deletion.
if perms_needed:
@@ -663,6 +675,9 @@ def has_change_permission(self, request, obj=None):
)
return can_change_page
def has_view_permission(self, request, obj=None):
return self.has_change_permission(request, obj)
def has_change_advanced_settings_permission(self, request, obj=None):
if not obj:
return False
@@ -1270,22 +1285,24 @@ def delete_translation(self, request, object_id, extra_context=None):
pluginopts = CMSPlugin._meta
saved_plugins = CMSPlugin.objects.filter(placeholder__page__id=object_id, language=language)
using = router.db_for_read(self.model)
kwargs = {
'admin_site': self.admin_site,
'user': request.user,
'using': using
}
kwargs = {'admin_site': self.admin_site}
if DJANGO_2_0:
kwargs.update({'using': using, 'opts': titleopts, 'user': request.user})
else:
kwargs.update({'request': request})
deleted_objects, __, perms_needed = get_deleted_objects(
[translation],
titleopts,
**kwargs
)[:3]
if DJANGO_2_0:
kwargs.update({'using': using, 'opts': pluginopts, 'user': request.user})
else:
kwargs.update({'request': request})
to_delete_plugins, __, perms_needed_plugins = get_deleted_objects(
saved_plugins,
pluginopts,
**kwargs
)[:3]
@@ -12,7 +12,7 @@
from cms.admin.forms import GlobalPagePermissionAdminForm, PagePermissionInlineAdminForm, ViewRestrictionInlineAdminForm
from cms.exceptions import NoPermissionsException
from cms.models import PagePermission, GlobalPagePermission
from cms.utils import permissions
from cms.utils import permissions, page_permissions
from cms.utils.conf import get_cms_setting
from cms.utils.helpers import classproperty
@@ -38,6 +38,18 @@ class PagePermissionInlineAdmin(TabularInline):
extra = 0 # edit page load time boost
show_with_view_permissions = False
def has_change_permission(self, request, obj=None):
if not obj:
return False
return page_permissions.user_can_change_page_permissions(
request.user,
page=obj,
site=obj.node.site,
)
def has_add_permission(self, request, obj=None):
return self.has_change_permission(request, obj)
@classproperty
def raw_id_fields(cls):
# Dynamically set raw_id_fields based on settings
@@ -36,8 +36,9 @@
from cms.signals import pre_placeholder_operation, post_placeholder_operation
from cms.toolbar.utils import get_plugin_tree_as_json
from cms.utils import copy_plugins, get_current_site
from cms.utils.compat import DJANGO_2_0
from cms.utils.conf import get_cms_setting
from cms.utils.i18n import get_language_list, get_language_code
from cms.utils.i18n import get_language_code, get_language_list
from cms.utils.plugins import has_reached_plugin_limit, reorder_plugins
from cms.utils.urlutils import admin_reverse
@@ -1029,8 +1030,18 @@ def delete_plugin(self, request, plugin_id):
opts = plugin._meta
using = router.db_for_write(opts.model)
if DJANGO_2_0:
get_deleted_objects_additional_kwargs = {
'opts': opts,
'using': using,
'user': request.user,
}
else:
get_deleted_objects_additional_kwargs = {'request': request}
deleted_objects, __, perms_needed, protected = get_deleted_objects(
[plugin], opts, request.user, self.admin_site, using)
[plugin], admin_site=self.admin_site,
**get_deleted_objects_additional_kwargs
)
if request.POST: # The user has already confirmed the deletion.
if perms_needed:
@@ -1117,8 +1128,19 @@ def clear_placeholder(self, request, placeholder_id):
opts = Placeholder._meta
using = router.db_for_write(Placeholder)
plugins = placeholder.get_plugins_list(language)
if DJANGO_2_0:
get_deleted_objects_additional_kwargs = {
'opts': opts,
'using': using,
'user': request.user,
}
else:
get_deleted_objects_additional_kwargs = {'request': request}
deleted_objects, __, perms_needed, protected = get_deleted_objects(
plugins, opts, request.user, self.admin_site, using)
plugins, admin_site=self.admin_site,
**get_deleted_objects_additional_kwargs
)
obj_display = force_text(placeholder)
@@ -77,6 +77,12 @@ def has_delete_permission(self, request, obj=None):
return False
return self._has_change_permissions_permission(request)
def has_view_permission(self, request, obj=None):
# For django 2.1
# Default is to return True if user got `change` perm, but we have to
# get in consideration also cms permission system
return self.has_change_permission(request, obj)
class PageUserAdmin(GenericCmsPermissionAdmin, admin_class):
form = PageUserChangeForm
Oops, something went wrong.

0 comments on commit 50dee52

Please sign in to comment.