diff --git a/djangocms_blog/cms_wizards.py b/djangocms_blog/cms_wizards.py
index 2f797e4..ae89870 100644
--- a/djangocms_blog/cms_wizards.py
+++ b/djangocms_blog/cms_wizards.py
@@ -10,13 +10,13 @@ from django import forms
from django.conf import settings
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
-from parler.forms import TranslatableModelForm
from .cms_appconfig import BlogConfig
+from .forms import PostAdminFormBase
from .models import Post
-class PostWizardForm(TranslatableModelForm):
+class PostWizardForm(PostAdminFormBase):
default_appconfig = None
def __init__(self, *args, **kwargs):
@@ -31,6 +31,8 @@ class PostWizardForm(TranslatableModelForm):
choices=self.fields['app_config'].widget.choices,
)
self.fields['app_config'].widget.attrs['disabled'] = True
+ if 'categories' in self.fields:
+ self.fields['categories'].queryset = self.available_categories
class Meta:
model = Post
diff --git a/djangocms_blog/forms.py b/djangocms_blog/forms.py
index 936a507..1ba16fd 100644
--- a/djangocms_blog/forms.py
+++ b/djangocms_blog/forms.py
@@ -4,6 +4,7 @@ from __future__ import absolute_import, print_function, unicode_literals
from django import forms
from django.conf import settings
from django.core.validators import MaxLengthValidator
+from django.utils.functional import cached_property
from parler.forms import TranslatableModelForm
from taggit_autosuggest.widgets import TagAutoSuggest
@@ -12,7 +13,25 @@ from djangocms_blog.settings import get_setting
from .models import BlogCategory, BlogConfig, Post
-class CategoryAdminForm(TranslatableModelForm):
+class ConfigFormBase(object):
+ """
+ This provide the app_config property which returns the currently
+ selected app_config, whether it's an instance attribute or
+ passed in the request
+ """
+
+ @cached_property
+ def app_config(self):
+ if getattr(self.instance, 'app_config_id', None):
+ return self.instance.app_config
+ elif 'app_config' in self.initial:
+ return BlogConfig.objects.get(pk=self.initial['app_config'])
+ elif self.data.get('app_config', None):
+ return BlogConfig.objects.get(pk=self.data['app_config'])
+ return None
+
+
+class CategoryAdminForm(ConfigFormBase, TranslatableModelForm):
def __init__(self, *args, **kwargs):
self.base_fields['meta_description'].validators = [
@@ -33,11 +52,14 @@ class CategoryAdminForm(TranslatableModelForm):
qs = qs.exclude(
pk__in=[self.instance.pk] + [child.pk for child in self.instance.descendants()]
)
-
+ config = None
if getattr(self.instance, 'app_config_id', None):
qs = qs.namespace(self.instance.app_config.namespace)
- elif 'initial' in kwargs and 'app_config' in kwargs['initial']:
- config = BlogConfig.objects.get(pk=kwargs['initial']['app_config'])
+ elif 'app_config' in self.initial:
+ config = BlogConfig.objects.get(pk=self.initial['app_config'])
+ elif self.data.get('app_config', None):
+ config = BlogConfig.objects.get(pk=self.data['app_config'])
+ if config:
qs = qs.namespace(config.namespace)
self.fields['parent'].queryset = qs
@@ -53,17 +75,31 @@ class LatestEntriesForm(forms.ModelForm):
class Media:
css = {
- 'all': ('%sdjangocms_blog/css/%s' % (settings.STATIC_URL,
- 'djangocms_blog_admin.css'),)
+ 'all': ('%sdjangocms_blog/css/%s' % (
+ settings.STATIC_URL, 'djangocms_blog_admin.css'
+ ),)
}
-class PostAdminForm(TranslatableModelForm):
+class PostAdminFormBase(ConfigFormBase, TranslatableModelForm):
+ """
+ This provide common methods between the admin and wizard form
+ """
class Meta:
model = Post
fields = '__all__'
+ @cached_property
+ def available_categories(self):
+ qs = BlogCategory.objects
+ if self.app_config:
+ return qs.namespace(self.app_config.namespace)
+ return qs
+
+
+class PostAdminForm(PostAdminFormBase):
+
def __init__(self, *args, **kwargs):
self.base_fields['meta_description'].validators = [
MaxLengthValidator(get_setting('META_DESCRIPTION_LENGTH'))
@@ -79,26 +115,16 @@ class PostAdminForm(TranslatableModelForm):
MaxLengthValidator(get_setting('META_TITLE_LENGTH'))
]
super(PostAdminForm, self).__init__(*args, **kwargs)
-
- qs = BlogCategory.objects
-
- config = None
- if getattr(self.instance, 'app_config_id', None):
- qs = qs.namespace(self.instance.app_config.namespace)
- elif 'initial' in kwargs and 'app_config' in kwargs['initial']:
- config = BlogConfig.objects.get(pk=kwargs['initial']['app_config'])
- qs = qs.namespace(config.namespace)
-
if 'categories' in self.fields:
- self.fields['categories'].queryset = qs
+ self.fields['categories'].queryset = self.available_categories
if 'app_config' in self.fields:
# Don't allow app_configs to be added here. The correct way to add an
# apphook-config is to create an apphook on a cms Page.
self.fields['app_config'].widget.can_add_related = False
- if config:
+ if self.app_config:
self.initial['main_image_full'] = \
- config.app_data['config'].get('default_image_full')
+ self.app_config.app_data['config'].get('default_image_full')
self.initial['main_image_thumbnail'] = \
- config.app_data['config'].get('default_image_thumbnail')
+ self.app_config.app_data['config'].get('default_image_thumbnail')
diff --git a/tests/test_models.py b/tests/test_models.py
index bc62016..dbf90da 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -15,6 +15,7 @@ from django.contrib.auth.models import AnonymousUser
from django.contrib.messages.middleware import MessageMiddleware
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
+from django.http import QueryDict
from django.test import override_settings
from django.utils.encoding import force_text
from django.utils.html import strip_tags
@@ -181,13 +182,32 @@ class AdminTest(BaseTest):
def test_admin_category_views(self):
category_admin = admin.site._registry[BlogCategory]
request = self.get_page_request('/', self.user, r'/en/blog/', edit=False)
+ BlogCategory.objects.create(name='category 1 - blog 2', app_config=self.app_config_2)
# Add view only has an empty form - no type
response = category_admin.add_view(request)
self.assertNotContains(response, 'id="id_name" maxlength="767" name="name" type="text" value="category 1"')
self.assertContains(response, '' % self.app_config_1.pk)
+ # Add view select categories on the given appconfig, even when reloading the form
+ request.POST = QueryDict('app_config=1')
+ request.method = 'POST'
+ response = category_admin.add_view(request)
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['parent'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
+
+ request.GET = QueryDict('app_config=1')
+ request.method = 'GET'
+ response = category_admin.add_view(request)
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['parent'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
+
# Changeview is 'normal', with a few preselected items
+ request.GET = QueryDict()
response = category_admin.change_view(request, str(self.category_1.pk))
self.assertContains(response, 'id="id_name" maxlength="767" name="name" type="text" value="category 1"')
self.assertContains(response, 'id="id_meta_description" maxlength="320"')
@@ -240,31 +260,25 @@ class AdminTest(BaseTest):
# Add view shows all the exising categories
response = post_admin.add_view(request)
- self.assertContains(response, '')
- self.assertContains(response, '')
- self.assertContains(response, '')
- self.assertContains(response, '')
- self.assertContains(response, '')
- self.assertNotContains(response, 'category different branch')
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['parent'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
# Changeview hides the children of the current category
response = post_admin.change_view(request, str(category2.pk))
- self.assertContains(response, '')
- self.assertContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, 'category different branch')
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['parent'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1, parent__isnull=True)
+ )
# Test second apphook categories
request = self.get_page_request('/', self.user, r'/en/blog/?app_config=%s' % self.app_config_2.pk, edit=False)
response = post_admin.add_view(request)
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertNotContains(response, '')
- self.assertContains(response, 'category different branch')
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['parent'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_2)
+ )
def test_admin_fieldsets(self):
post_admin = admin.site._registry[Post]
@@ -339,13 +353,31 @@ class AdminTest(BaseTest):
msg_mid.process_request(request)
post_admin = admin.site._registry[Post]
response = post_admin.add_view(request)
- self.assertContains(response, '' % (
- self.category_1.pk, self.category_1.safe_translation_getter('name', language_code='en')
- ))
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['categories'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
self.assertContains(response, 'id="id_sites" name="sites"')
self.assertContains(response, 'selected="selected">Blog image')
self.assertContains(response, 'selected="selected">Blog thumbnail')
+ # Add view select categories on the given appconfig, even when reloading the form
+ request.POST = QueryDict('app_config=1')
+ request.method = 'POST'
+ response = post_admin.add_view(request)
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['categories'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
+
+ request.GET = QueryDict('app_config=1')
+ request.method = 'GET'
+ response = post_admin.add_view(request)
+ self.assertTrue(
+ response.context_data['adminform'].form.fields['categories'].queryset,
+ BlogCategory.objects.filter(app_config=self.app_config_1)
+ )
+
self.user.sites.add(self.site_1)
with self.login_user_context(self.user):
request = self.get_request('/', 'en', user=self.user,
diff --git a/tests/test_wizards.py b/tests/test_wizards.py
index 692c1a8..fda2011 100644
--- a/tests/test_wizards.py
+++ b/tests/test_wizards.py
@@ -3,6 +3,8 @@ from __future__ import absolute_import, print_function, unicode_literals
import sys
+from djangocms_blog.models import BlogCategory
+
from .base import BaseTest
@@ -41,6 +43,12 @@ class WizardTest(BaseTest):
from djangocms_blog.models import Post
self.get_pages()
+ cat_1 = BlogCategory.objects.create(name='category 1 - blog 1', app_config=self.app_config_1)
+ cat_2 = BlogCategory.objects.create(name='category 1 - blog 2', app_config=self.app_config_2)
+ cats = {
+ self.app_config_1.pk: cat_1,
+ self.app_config_2.pk: cat_2,
+ }
with current_user(self.user_staff):
wizs = [entry for entry in wizard_pool.get_entries() if entry.model == Post]
for index, wiz in enumerate(wizs):
@@ -52,7 +60,7 @@ class WizardTest(BaseTest):
form = wiz.form(data={
'1-title': 'title{0}'.format(index),
'1-abstract': 'abstract{0}'.format(index),
- '1-categories': [self.category_1.pk],
+ '1-categories': [cats[app_config].pk],
}, prefix=1)
self.assertEqual(form.default_appconfig, app_config)
self.assertTrue(form.is_valid())
@@ -66,7 +74,7 @@ class WizardTest(BaseTest):
form = wiz.form(data={
'1-title': 'title-2{0}'.format(index),
'1-abstract': 'abstract-2{0}'.format(index),
- '1-categories': [self.category_1.pk],
+ '1-categories': [cats[app_config].pk],
}, prefix=1)
self.assertEqual(form.default_appconfig, app_config)
self.assertTrue(form.is_valid())
@@ -74,6 +82,26 @@ class WizardTest(BaseTest):
instance = form.save()
self.assertEqual(instance.author, self.user_normal)
+ def test_wizard_init_categories_check(self):
+ from cms.utils.permissions import current_user
+ from cms.wizards.wizard_pool import wizard_pool
+ from djangocms_blog.models import Post
+ self.get_pages()
+
+ with current_user(self.user_staff):
+ wiz = None
+ for wiz in wizard_pool.get_entries():
+ if wiz.model == Post and wiz.title == 'New Article':
+ break
+ form = wiz.form(data={
+ '1-title': 'title article',
+ '1-abstract': 'abstract article',
+ '1-categories': [self.category_1.pk],
+ }, prefix=1)
+ self.assertEqual(form.default_appconfig, self.app_config_2.pk)
+ self.assertFalse(form.is_valid())
+ self.assertTrue('categories' in form.errors.keys())
+
def test_wizard_import(self):
# The following import should not fail in any django CMS version
pass