From f6e8e27687e11c66ffaee6b965dd8d02e4111aff Mon Sep 17 00:00:00 2001 From: Iacopo Spalletti Date: Sun, 20 Sep 2015 01:11:14 +0200 Subject: [PATCH] Add support for apphook config --- cms_helper.py | 1 + djangocms_blog/admin.py | 58 +++- djangocms_blog/cms_app.py | 6 +- djangocms_blog/cms_appconfig.py | 47 +++ djangocms_blog/cms_plugins.py | 25 +- djangocms_blog/feeds.py | 9 +- djangocms_blog/forms.py | 28 ++ djangocms_blog/managers.py | 9 +- djangocms_blog/menu.py | 70 ++--- .../migrations/0010_auto_20150923_1151.py | 118 ++++++++ djangocms_blog/models.py | 69 +++-- djangocms_blog/settings.py | 1 + ...__add_unique_blogconfigtranslation_lang.py | 286 ++++++++++++++++++ .../south_migrations/0015_create_appconfig.py | 234 ++++++++++++++ .../templates/djangocms_blog/post_detail.html | 2 +- djangocms_blog/views.py | 18 +- setup.py | 1 + tests/__init__.py | 186 +++++++----- tests/test_menu.py | 83 +++-- tests/test_models.py | 164 +++++----- tests/test_plugins.py | 113 ++++--- tests/test_toolbar.py | 10 +- tests/test_views.py | 198 +++++++----- 23 files changed, 1308 insertions(+), 428 deletions(-) create mode 100644 djangocms_blog/cms_appconfig.py create mode 100644 djangocms_blog/migrations/0010_auto_20150923_1151.py create mode 100644 djangocms_blog/south_migrations/0014_auto__add_blogconfigtranslation__add_unique_blogconfigtranslation_lang.py create mode 100644 djangocms_blog/south_migrations/0015_create_appconfig.py diff --git a/cms_helper.py b/cms_helper.py index ef6b154..3b7af0d 100755 --- a/cms_helper.py +++ b/cms_helper.py @@ -18,6 +18,7 @@ HELPER_SETTINGS = dict( 'cmsplugin_filer_image', 'taggit', 'taggit_autosuggest', + 'aldryn_apphooks_config', ], LANGUAGE_CODE='en', LANGUAGES=( diff --git a/djangocms_blog/admin.py b/djangocms_blog/admin.py index 70189fe..db966e1 100755 --- a/djangocms_blog/admin.py +++ b/djangocms_blog/admin.py @@ -3,6 +3,7 @@ from __future__ import absolute_import, print_function, unicode_literals from copy import deepcopy +from aldryn_apphooks_config.admin import BaseAppHookConfig, ModelAppHookConfig from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin from django import forms from django.conf import settings @@ -10,6 +11,8 @@ from django.contrib import admin from django.contrib.auth import get_user_model from parler.admin import TranslatableAdmin +from .cms_appconfig import BlogConfig +from .forms import PostAdminForm from .models import BlogCategory, Post from .settings import get_setting @@ -20,19 +23,22 @@ except ImportError: pass -class BlogCategoryAdmin(EnhancedModelAdminMixin, TranslatableAdmin): +class BlogCategoryAdmin(EnhancedModelAdminMixin, ModelAppHookConfig, TranslatableAdmin): def get_prepopulated_fields(self, request, obj=None): + app_config_default = self._app_config_select(request, obj) + if app_config_default is None and request.method == 'GET': + return {} return {'slug': ('name',)} 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 PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, - PlaceholderAdminMixin, TranslatableAdmin): +class PostAdmin(PlaceholderAdminMixin, FrontendEditableAdminMixin, + ModelAppHookConfig, TranslatableAdmin): + form = PostAdminForm list_display = ['title', 'author', 'date_published', 'date_published_end'] date_hierarchy = 'date_published' raw_id_fields = ['author'] @@ -40,7 +46,7 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, enhance_exclude = ('main_image', 'tags') _fieldsets = [ (None, { - 'fields': [('title', 'categories', 'publish')] + 'fields': [('title', 'categories', 'publish', 'app_config')] }), ('Info', { 'fields': (['slug', 'tags'], @@ -57,6 +63,10 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, }), ] + app_config_values = { + 'default_published': 'publish' + } + def formfield_for_dbfield(self, db_field, **kwargs): field = super(PostAdmin, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name == 'meta_description': @@ -68,11 +78,25 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, return field def get_fieldsets(self, request, obj=None): + app_config_default = self._app_config_select(request, obj) + if app_config_default is None and request.method == 'GET': + return super(PostAdmin, self).get_fieldsets(request, obj) + if not obj: + config = app_config_default + else: + config = obj.app_config + fsets = deepcopy(self._fieldsets) - if get_setting('USE_ABSTRACT'): - fsets[0][1]['fields'].append('abstract') - if not get_setting('USE_PLACEHOLDER'): - fsets[0][1]['fields'].append('post_text') + if config: + if config.use_abstract: + fsets[0][1]['fields'].append('abstract') + if not config.use_placeholder: + fsets[0][1]['fields'].append('post_text') + else: + if get_setting('USE_ABSTRACT'): + fsets[0][1]['fields'].append('abstract') + if not get_setting('USE_PLACEHOLDER'): + fsets[0][1]['fields'].append('post_text') if get_setting('MULTISITE'): fsets[1][1]['fields'][0].append('sites') if request.user.is_superuser: @@ -83,7 +107,7 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, return {'slug': ('title',)} def save_model(self, request, obj, form, change): - if not obj.author_id and get_setting('AUTHOR_DEFAULT'): + if not obj.author_id and obj.app_config.set_author: if get_setting('AUTHOR_DEFAULT') is True: user = request.user else: @@ -93,10 +117,18 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdminMixin, 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 BlogConfigAdmin(BaseAppHookConfig, TranslatableAdmin): + + def get_config_fields(self): + return ( + 'app_title', 'paginate_by', 'set_author', 'config.default_published', + 'config.use_placeholder' + ) + admin.site.register(BlogCategory, BlogCategoryAdmin) admin.site.register(Post, PostAdmin) +admin.site.register(BlogConfig, BlogConfigAdmin) diff --git a/djangocms_blog/cms_app.py b/djangocms_blog/cms_app.py index 508c665..5209555 100644 --- a/djangocms_blog/cms_app.py +++ b/djangocms_blog/cms_app.py @@ -1,17 +1,19 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals -from cms.app_base import CMSApp +from aldryn_apphooks_config.app_base import CMSConfigApp from cms.apphook_pool import apphook_pool from django.utils.translation import ugettext_lazy as _ +from .cms_appconfig import BlogConfig from .menu import BlogCategoryMenu -class BlogApp(CMSApp): +class BlogApp(CMSConfigApp): name = _('Blog') urls = ['djangocms_blog.urls'] app_name = 'djangocms_blog' + app_config = BlogConfig menus = [BlogCategoryMenu] apphook_pool.register(BlogApp) diff --git a/djangocms_blog/cms_appconfig.py b/djangocms_blog/cms_appconfig.py new file mode 100644 index 0000000..34c39f4 --- /dev/null +++ b/djangocms_blog/cms_appconfig.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django import forms +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from aldryn_apphooks_config.utils import setup_config +from aldryn_apphooks_config.models import AppHookConfig +from app_data import AppDataForm +from parler.models import TranslatableModel +from parler.models import TranslatedFields + +from .settings import get_setting + + +class BlogConfig(TranslatableModel, AppHookConfig): + """ + Adds some translatable, per-app-instance fields. + """ + translations = TranslatedFields( + app_title=models.CharField(_('application title'), max_length=234), + ) + + def get_app_title(self): + return getattr(self, 'app_title', _('untitled')) + + +class BlogConfigForm(AppDataForm): + default_published = forms.BooleanField(label=_('Post published by default'), required=False, + initial=get_setting('DEFAULT_PUBLISHED')) + use_placeholder = forms.BooleanField(label=_('Use placeholder and plugins for article body'), + required=False, + initial=get_setting('USE_PLACEHOLDER')) + use_abstract = forms.BooleanField(label=_('Use abstract field'), + required=False, + initial=get_setting('USE_ABSTRACT')) + set_author = forms.BooleanField(label=_('Set author'), + required=False, + help_text=_('Set author by default'), + initial=get_setting('AUTHOR_DEFAULT')) + paginate_by = forms.IntegerField(label=_('Paginate size'), + required=False, + initial=get_setting('PAGINATION'), + help_text=_('When paginating list views, ' + 'how many articles per page?')) +setup_config(BlogConfigForm, BlogConfig) diff --git a/djangocms_blog/cms_plugins.py b/djangocms_blog/cms_plugins.py index 42ce80a..739e468 100644 --- a/djangocms_blog/cms_plugins.py +++ b/djangocms_blog/cms_plugins.py @@ -7,7 +7,7 @@ from cms.plugin_pool import plugin_pool from django.utils.translation import ugettext_lazy as _ from .forms import LatestEntriesForm -from .models import AuthorEntriesPlugin, BlogCategory, LatestPostsPlugin, Post +from .models import AuthorEntriesPlugin, BlogCategory, LatestPostsPlugin, Post, GenericBlogPlugin from .settings import get_setting @@ -70,36 +70,47 @@ class BlogAuthorPostsPlugin(BlogPlugin): class BlogTagsPlugin(BlogPlugin): module = _('Blog') name = _('Tags') - model = CMSPlugin + model = GenericBlogPlugin render_template = 'djangocms_blog/plugins/tags.html' def render(self, context, instance, placeholder): context = super(BlogTagsPlugin, self).render(context, instance, placeholder) - context['tags'] = Post.objects.tag_cloud(queryset=Post.objects.published()) + qs = Post._default_manager + qs_post = qs + if instance.app_config: + qs_post = qs_post.namespace(instance.app_config.namespace) + context['tags'] = qs.tag_cloud(queryset=qs_post.published()) return context class BlogCategoryPlugin(BlogPlugin): module = _('Blog') name = _('Categories') - model = CMSPlugin + model = GenericBlogPlugin render_template = 'djangocms_blog/plugins/categories.html' def render(self, context, instance, placeholder): context = super(BlogCategoryPlugin, self).render(context, instance, placeholder) - context['categories'] = BlogCategory.objects.all() + qs = BlogCategory._default_manager + if instance.app_config: + qs = qs.namespace(instance.app_config.namespace) + context['categories'] = qs return context class BlogArchivePlugin(BlogPlugin): module = _('Blog') name = _('Archive') - model = CMSPlugin + model = GenericBlogPlugin render_template = 'djangocms_blog/plugins/archive.html' def render(self, context, instance, placeholder): context = super(BlogArchivePlugin, self).render(context, instance, placeholder) - context['dates'] = Post.objects.get_months(queryset=Post.objects.published()) + qs = Post._default_manager + qs_post = qs + if instance.app_config: + qs_post = qs.namespace(instance.app_config.namespace) + context['dates'] = qs.get_months(queryset=qs_post.published()) return context diff --git a/djangocms_blog/feeds.py b/djangocms_blog/feeds.py index 0675c0d..481e0eb 100644 --- a/djangocms_blog/feeds.py +++ b/djangocms_blog/feeds.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals +from aldryn_apphooks_config.utils import get_app_instance from django.contrib.sites.models import Site from django.contrib.syndication.views import Feed @@ -12,14 +13,18 @@ from .settings import get_setting class LatestEntriesFeed(Feed): + def __call__(self, request, *args, **kwargs): + self.namespace, self.config = get_app_instance(request) + return super(LatestEntriesFeed, self).__call__(request, *args, **kwargs) + def link(self): - return reverse('djangocms_blog:posts-latest') + return reverse('%s:posts-latest' % self.namespace, current_app=self.namespace) def title(self): return _('Blog articles on %(site_name)s') % {'site_name': Site.objects.get_current().name} def items(self, obj=None): - return Post.objects.published().order_by('-date_published')[:10] + return Post.objects.namespace(self.namespace).published().order_by('-date_published')[:10] def item_title(self, item): return item.safe_translation_getter('title') diff --git a/djangocms_blog/forms.py b/djangocms_blog/forms.py index 9ffc323..01de6a2 100644 --- a/djangocms_blog/forms.py +++ b/djangocms_blog/forms.py @@ -3,8 +3,11 @@ from __future__ import absolute_import, print_function, unicode_literals from django import forms from django.conf import settings +from parler.forms import TranslatableModelForm from taggit_autosuggest.widgets import TagAutoSuggest +from .models import Post, BlogCategory + class LatestEntriesForm(forms.ModelForm): def __init__(self, *args, **kwargs): @@ -16,3 +19,28 @@ class LatestEntriesForm(forms.ModelForm): 'all': ('%sdjangocms_blog/css/%s' % (settings.STATIC_URL, 'djangocms_blog_admin.css'),) } + + +class PostAdminForm(TranslatableModelForm): + + class Meta: + model = Post + fields = '__all__' + + def __init__(self, *args, **kwargs): + super(PostAdminForm, self).__init__(*args, **kwargs) + + qs = BlogCategory.objects + + 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']: + qs = qs.namespace(kwargs['initial']['app_config']) + + if 'categories' in self.fields: + self.fields['categories'].queryset = qs + + 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 diff --git a/djangocms_blog/managers.py b/djangocms_blog/managers.py index 75d670a..9fce9dd 100644 --- a/djangocms_blog/managers.py +++ b/djangocms_blog/managers.py @@ -2,10 +2,13 @@ from __future__ import absolute_import, print_function, unicode_literals import django + +from aldryn_apphooks_config.managers.parler import ( + AppHookConfigTranslatableManager, AppHookConfigTranslatableQueryset +) from django.contrib.sites.models import Site from django.db import models from django.utils.timezone import now -from parler.managers import TranslatableQuerySet, TranslationManager try: from collections import Counter @@ -76,7 +79,7 @@ class TaggedFilterItem(object): return sorted(tags, key=lambda x: -x.count) -class GenericDateQuerySet(TranslatableQuerySet): +class GenericDateQuerySet(AppHookConfigTranslatableQueryset): start_date_field = 'date_published' end_date_field = 'date_published_end' publish_field = 'publish' @@ -120,7 +123,7 @@ class GenericDateQuerySet(TranslatableQuerySet): return self.active_translations(language_code=language).on_site() -class GenericDateTaggedManager(TaggedFilterItem, TranslationManager): +class GenericDateTaggedManager(TaggedFilterItem, AppHookConfigTranslatableManager): use_for_related_fields = True queryset_class = GenericDateQuerySet diff --git a/djangocms_blog/menu.py b/djangocms_blog/menu.py index d28099f..c821484 100644 --- a/djangocms_blog/menu.py +++ b/djangocms_blog/menu.py @@ -3,11 +3,11 @@ from __future__ import absolute_import, print_function, unicode_literals from cms.menu_bases import CMSAttachMenu from django.db.models.signals import post_delete, post_save -from django.utils.translation import get_language, ugettext_lazy as _ +from django.utils.translation import ugettext_lazy as _, get_language_from_request from menus.base import Modifier, NavigationNode from menus.menu_pool import menu_pool -from .models import BlogCategory +from .models import BlogCategory, Post class BlogCategoryMenu(CMSAttachMenu): @@ -15,54 +15,42 @@ class BlogCategoryMenu(CMSAttachMenu): def get_nodes(self, request): nodes = [] - qs = BlogCategory.objects.translated(get_language()) - qs = qs.order_by('parent__id', 'translations__name') - for category in qs: + + language = get_language_from_request(request, check_path=True) + + categories = BlogCategory.objects + if hasattr(self, 'instance') and self.instance: + categories = categories.namespace(self.instance.application_namespace) + categories = categories.active_translations(language).distinct() + categories = categories.order_by('parent__id', 'translations__name') + for category in categories: node = NavigationNode( category.name, category.get_absolute_url(), - category.pk, - category.parent_id + '%s-%s' % (category.__class__.__name__, category.pk), + ('%s-%s' % (category.__class__.__name__, category.parent.id) if category.parent + else None) ) nodes.append(node) + + posts = Post.objects + if hasattr(self, 'instance') and self.instance: + posts = posts.namespace(self.instance.application_namespace) + posts = posts.active_translations(language).distinct() + for post in posts: + category = post.categories.first() + node = NavigationNode( + post.get_title(), + post.get_absolute_url(language), + '%s-%s' % (post.__class__.__name__, category.pk), + '%s-%s' % (category.__class__.__name__, category.pk) + ) + nodes.append(node) + return nodes menu_pool.register_menu(BlogCategoryMenu) - -class BlogNavModifier(Modifier): - """ - This navigation modifier makes sure that when - a particular blog post is viewed, - a corresponding category is selected in menu - """ - def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): - if post_cut: - return nodes - if not hasattr(request, 'toolbar'): - return nodes - models = ('djangocms_blog.post', 'djangocms_blog.blogcategory') - model = request.toolbar.get_object_model() - if model not in models: - return nodes - if model == 'djangocms_blog.blogcategory': - cat = request.toolbar.obj - else: - cat = request.toolbar.obj.categories.first() - if not cat: - return nodes - - for node in nodes: - if (node.namespace.startswith(BlogCategoryMenu.__name__) and - cat.pk == node.id): - node.selected = True - # no break here because django-cms maintains two menu structures - # for every apphook (attached to published page and draft page) - return nodes - -menu_pool.register_modifier(BlogNavModifier) - - def clear_menu_cache(**kwargs): menu_pool.clear(all=True) diff --git a/djangocms_blog/migrations/0010_auto_20150923_1151.py b/djangocms_blog/migrations/0010_auto_20150923_1151.py new file mode 100644 index 0000000..25db956 --- /dev/null +++ b/djangocms_blog/migrations/0010_auto_20150923_1151.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import aldryn_apphooks_config.fields +import app_data.fields +import djangocms_text_ckeditor.fields + +from cms.models import Page +from cms.utils.conf import get_languages +from django.db import models, migrations + + +def forwards(apps, schema_editor): + BlogConfig = apps.get_model('djangocms_blog', 'BlogConfig') + Post = apps.get_model('djangocms_blog', 'Post') + BlogCategory = apps.get_model('djangocms_blog', 'BlogCategory') + GenericBlogPlugin = apps.get_model('djangocms_blog', 'GenericBlogPlugin') + LatestPostsPlugin = apps.get_model('djangocms_blog', 'LatestPostsPlugin') + AuthorEntriesPlugin = apps.get_model('djangocms_blog', 'AuthorEntriesPlugin') + config = None + for page in Page.objects.drafts().filter(application_urls='BlogApp'): + config = BlogConfig.objects.create(namespace=page.application_namespace) + for lang in get_languages(): + config.create_translation(lang, app_title='Blog') + if config: + for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): + for item in model.objects.all(): + item.app_config = config + item.save() + + +def backwards(apps, schema_editor): + # No need for backward data migration + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '__latest__'), + ('djangocms_blog', '0009_latestpostsplugin_tags_new'), + ] + + operations = [ + migrations.CreateModel( + name='BlogConfig', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)), + ('type', models.CharField(verbose_name='type', max_length=100)), + ('namespace', models.CharField(default=None, verbose_name='instance namespace', unique=True, max_length=100)), + ('app_data', app_data.fields.AppDataField(editable=False, default='{}')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='BlogConfigTranslation', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)), + ('language_code', models.CharField(db_index=True, verbose_name='Language', max_length=15)), + ('app_title', models.CharField(verbose_name='application title', max_length=234)), + ('master', models.ForeignKey(editable=False, to='djangocms_blog.BlogConfig', related_name='translations', null=True)), + ], + options={ + 'verbose_name': 'blog config Translation', + 'db_table': 'djangocms_blog_blogconfig_translation', + 'default_permissions': (), + 'db_tablespace': '', + 'managed': True, + }, + ), + migrations.CreateModel( + name='GenericBlogPlugin', + fields=[ + ('cmsplugin_ptr', models.OneToOneField(parent_link=True, serialize=False, primary_key=True, auto_created=True, to='cms.CMSPlugin')), + ('app_config', aldryn_apphooks_config.fields.AppHookConfigField(verbose_name='app. config', blank=True, to='djangocms_blog.BlogConfig', help_text='When selecting a value, the form is reloaded to get the updated default')), + ], + options={ + 'abstract': False, + }, + bases=('cms.cmsplugin',), + ), + migrations.AlterField( + model_name='posttranslation', + name='abstract', + field=djangocms_text_ckeditor.fields.HTMLField(default='', verbose_name='abstract', blank=True), + ), + migrations.AddField( + model_name='authorentriesplugin', + name='app_config', + field=aldryn_apphooks_config.fields.AppHookConfigField(default=None, blank=True, verbose_name='app. config', to='djangocms_blog.BlogConfig', help_text='When selecting a value, the form is reloaded to get the updated default'), + preserve_default=False, + ), + migrations.AddField( + model_name='blogcategory', + name='app_config', + field=aldryn_apphooks_config.fields.AppHookConfigField(default=None, verbose_name='app. config', to='djangocms_blog.BlogConfig', help_text='When selecting a value, the form is reloaded to get the updated default'), + preserve_default=False, + ), + migrations.AddField( + model_name='latestpostsplugin', + name='app_config', + field=aldryn_apphooks_config.fields.AppHookConfigField(default=None, blank=True, verbose_name='app. config', to='djangocms_blog.BlogConfig', help_text='When selecting a value, the form is reloaded to get the updated default'), + preserve_default=False, + ), + migrations.AddField( + model_name='post', + name='app_config', + field=aldryn_apphooks_config.fields.AppHookConfigField(default=None, verbose_name='app. config', to='djangocms_blog.BlogConfig', help_text='When selecting a value, the form is reloaded to get the updated default'), + preserve_default=False, + ), + migrations.AlterUniqueTogether( + name='blogconfigtranslation', + unique_together=set([('language_code', 'master')]), + ), + migrations.RunPython(forwards, backwards) + ] diff --git a/djangocms_blog/models.py b/djangocms_blog/models.py index f5deb6a..8a90879 100644 --- a/djangocms_blog/models.py +++ b/djangocms_blog/models.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals +from aldryn_apphooks_config.managers.parler import AppHookConfigTranslatableManager +from aldryn_apphooks_config.fields import AppHookConfigField from cms.models import CMSPlugin, PlaceholderField from django.conf import settings as dj_settings from django.core.urlresolvers import reverse @@ -13,10 +15,10 @@ from django.utils.translation import get_language, ugettext_lazy as _ from djangocms_text_ckeditor.fields import HTMLField from filer.fields.image import FilerImageField from meta_mixin.models import ModelMeta -from parler.managers import TranslationManager from parler.models import TranslatableModel, TranslatedFields from taggit_autosuggest.managers import TaggableManager +from .cms_appconfig import BlogConfig from .managers import GenericDateTaggedManager from .settings import get_setting @@ -28,10 +30,10 @@ class BlogCategory(TranslatableModel): """ Blog category """ - parent = models.ForeignKey('self', verbose_name=_('parent'), null=True, - blank=True) + parent = models.ForeignKey('self', verbose_name=_('parent'), null=True, blank=True) date_created = models.DateTimeField(_('created at'), auto_now_add=True) date_modified = models.DateTimeField(_('modified at'), auto_now=True) + app_config = AppHookConfigField(BlogConfig, verbose_name=_('app. config')) translations = TranslatedFields( name=models.CharField(_('name'), max_length=255), @@ -39,7 +41,7 @@ class BlogCategory(TranslatableModel): meta={'unique_together': (('language_code', 'slug'),)} ) - objects = TranslationManager() + objects = AppHookConfigTranslatableManager() class Meta: verbose_name = _('blog category') @@ -47,16 +49,23 @@ class BlogCategory(TranslatableModel): @property def count(self): - return self.blog_posts.published().count() + return self.blog_posts.namespace(self.app_config.namespace).published().count() - def get_absolute_url(self): - lang = get_language() - if self.has_translation(lang): + def get_absolute_url(self, lang=None): + if not lang: + lang = get_language() + if self.has_translation(lang, ): slug = self.safe_translation_getter('slug', language_code=lang) - return reverse('djangocms_blog:posts-category', kwargs={'category': slug}) + return reverse( + '%s:posts-category' % self.app_config.namespace, + kwargs={'category': slug}, + current_app=self.app_config.namespace + ) # in case category doesn't exist in this language, gracefully fallback # to posts-latest - return reverse('djangocms_blog:posts-latest') + return reverse( + '%s:posts-latest' % self.app_config.namespace, current_app=self.app_config.namespace + ) def __str__(self): return self.safe_translation_getter('name') @@ -108,6 +117,7 @@ class Post(ModelMeta, TranslatableModel): help_text=_('Select sites in which to show the post. ' u'If none is set it will be ' u'visible in all the configured sites.')) + app_config = AppHookConfigField(BlogConfig, verbose_name=_('app. config')) translations = TranslatedFields( title=models.CharField(_('title'), max_length=255), @@ -165,19 +175,21 @@ class Post(ModelMeta, TranslatableModel): def __str__(self): return self.safe_translation_getter('title') - def get_absolute_url(self): + def get_absolute_url(self, lang=None): + if not lang: + lang = get_language() kwargs = {'year': self.date_published.year, 'month': '%02d' % self.date_published.month, 'day': '%02d' % self.date_published.day, 'slug': self.safe_translation_getter('slug', - language_code=get_language(), + language_code=lang, any_language=True)} - return reverse('djangocms_blog:post-detail', kwargs=kwargs) + return reverse('%s:post-detail' % self.app_config.namespace, kwargs=kwargs) - def save(self, *args, **kwargs): - if not self.slug and self.title: - self.slug = slugify(self.title) - super(Post, self).save(*args, **kwargs) + def save_translation(self, translation, *args, **kwargs): + if not translation.slug and translation.title: + translation.slug = slugify(translation.title) + super(Post, self).save_translation(translation, *args, **kwargs) def get_title(self): title = self.safe_translation_getter('meta_title', any_language=True) @@ -230,7 +242,10 @@ class BasePostPlugin(CMSPlugin): def post_queryset(self, request=None): language = get_language() - posts = Post._default_manager.active_translations(language_code=language) + posts = Post._default_manager + if self.app_config: + posts = posts.namespace(self.app_config.namespace) + posts = posts.active_translations(language_code=language) if not request or not getattr(request, 'toolbar', False) or not request.toolbar.edit_mode: posts = posts.published() return posts @@ -240,7 +255,7 @@ class BasePostPlugin(CMSPlugin): class LatestPostsPlugin(BasePostPlugin): - + app_config = AppHookConfigField(BlogConfig, verbose_name=_('app. config'), blank=True) latest_posts = models.IntegerField(_('articles'), default=get_setting('LATEST_POSTS'), help_text=_('The number of latests ' u'articles to be displayed.')) @@ -269,6 +284,7 @@ class LatestPostsPlugin(BasePostPlugin): class AuthorEntriesPlugin(BasePostPlugin): + app_config = AppHookConfigField(BlogConfig, verbose_name=_('app. config'), blank=True) authors = models.ManyToManyField( dj_settings.AUTH_USER_MODEL, verbose_name=_('authors'), limit_choices_to={'djangocms_blog_post_author__publish': True} @@ -292,6 +308,17 @@ class AuthorEntriesPlugin(BasePostPlugin): authors = self.authors.all() for author in authors: author.count = 0 - if author.djangocms_blog_post_author.filter(publish=True).exists(): - author.count = author.djangocms_blog_post_author.filter(publish=True).count() + qs = author.djangocms_blog_post_author + if self.app_config: + qs = qs.namespace(self.app_config.namespace) + count = qs.filter(publish=True).count() + if count: + author.count = count return authors + + +class GenericBlogPlugin(BasePostPlugin): + app_config = AppHookConfigField(BlogConfig, verbose_name=_('app. config'), blank=True) + + def __str__(self): + return _('generic blog plugin') diff --git a/djangocms_blog/settings.py b/djangocms_blog/settings.py index 6676154..40b9dbe 100644 --- a/djangocms_blog/settings.py +++ b/djangocms_blog/settings.py @@ -52,5 +52,6 @@ def get_setting(name): 'BLOG_USE_PLACEHOLDER': getattr(settings, 'BLOG_USE_PLACEHOLDER', True), 'BLOG_MULTISITE': getattr(settings, 'BLOG_MULTISITE', True), 'BLOG_AUTHOR_DEFAULT': getattr(settings, 'BLOG_AUTHOR_DEFAULT', True), + 'BLOG_DEFAULT_PUBLISHED': getattr(settings, 'BLOG_DEFAULT_PUBLISHED', False), } return default['BLOG_%s' % name] diff --git a/djangocms_blog/south_migrations/0014_auto__add_blogconfigtranslation__add_unique_blogconfigtranslation_lang.py b/djangocms_blog/south_migrations/0014_auto__add_blogconfigtranslation__add_unique_blogconfigtranslation_lang.py new file mode 100644 index 0000000..9cd1487 --- /dev/null +++ b/djangocms_blog/south_migrations/0014_auto__add_blogconfigtranslation__add_unique_blogconfigtranslation_lang.py @@ -0,0 +1,286 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'BlogConfigTranslation' + db.create_table('djangocms_blog_blogconfig_translation', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('language_code', self.gf('django.db.models.fields.CharField')(db_index=True, max_length=15)), + ('app_title', self.gf('django.db.models.fields.CharField')(max_length=234)), + ('master', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['djangocms_blog.BlogConfig'], related_name='translations', null=True)), + )) + db.send_create_signal('djangocms_blog', ['BlogConfigTranslation']) + + # Adding unique constraint on 'BlogConfigTranslation', fields ['language_code', 'master'] + db.create_unique('djangocms_blog_blogconfig_translation', ['language_code', 'master_id']) + + # Adding model 'BlogConfig' + db.create_table('djangocms_blog_blogconfig', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('type', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('namespace', self.gf('django.db.models.fields.CharField')(default=None, max_length=100, unique=True)), + ('app_data', self.gf('app_data.fields.AppDataField')(default='{}')), + )) + db.send_create_signal('djangocms_blog', ['BlogConfig']) + + # Adding model 'GenericBlogPlugin' + db.create_table('djangocms_blog_genericblogplugin', ( + ('cmsplugin_ptr', self.gf('django.db.models.fields.related.OneToOneField')(primary_key=True, to=orm['cms.CMSPlugin'], unique=True)), + ('app_config', self.gf('aldryn_apphooks_config.fields.AppHookConfigField')(blank=True, null=True, to=orm['djangocms_blog.BlogConfig'])), + )) + db.send_create_signal('djangocms_blog', ['GenericBlogPlugin']) + + # Adding field 'AuthorEntriesPlugin.app_config' + db.add_column('djangocms_blog_authorentriesplugin', 'app_config', + self.gf('aldryn_apphooks_config.fields.AppHookConfigField')(default=None, blank=True, null=True, to=orm['djangocms_blog.BlogConfig']), + keep_default=False) + + # Adding field 'Post.app_config' + db.add_column('djangocms_blog_post', 'app_config', + self.gf('aldryn_apphooks_config.fields.AppHookConfigField')(to=orm['djangocms_blog.BlogConfig'], null=True, default=None), + keep_default=False) + + # Adding field 'BlogCategory.app_config' + db.add_column('djangocms_blog_blogcategory', 'app_config', + self.gf('aldryn_apphooks_config.fields.AppHookConfigField')(to=orm['djangocms_blog.BlogConfig'], null=True, default=None), + keep_default=False) + + # Adding field 'LatestPostsPlugin.app_config' + db.add_column('djangocms_blog_latestpostsplugin', 'app_config', + self.gf('aldryn_apphooks_config.fields.AppHookConfigField')(default=None, null=True, blank=True, to=orm['djangocms_blog.BlogConfig']), + keep_default=False) + + + def backwards(self, orm): + # Removing unique constraint on 'BlogConfigTranslation', fields ['language_code', 'master'] + db.delete_unique('djangocms_blog_blogconfig_translation', ['language_code', 'master_id']) + + # Deleting model 'BlogConfigTranslation' + db.delete_table('djangocms_blog_blogconfig_translation') + + # Deleting model 'BlogConfig' + db.delete_table('djangocms_blog_blogconfig') + + # Deleting model 'GenericBlogPlugin' + db.delete_table('djangocms_blog_genericblogplugin') + + # Deleting field 'AuthorEntriesPlugin.app_config' + db.delete_column('djangocms_blog_authorentriesplugin', 'app_config_id') + + # Deleting field 'Post.app_config' + db.delete_column('djangocms_blog_post', 'app_config_id') + + # Deleting field 'BlogCategory.app_config' + db.delete_column('djangocms_blog_blogcategory', 'app_config_id') + + # Deleting field 'LatestPostsPlugin.app_config' + db.delete_column('djangocms_blog_latestpostsplugin', 'app_config_id') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'unique': 'True'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['auth.Permission']"}) + }, + 'auth.permission': { + 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission', 'ordering': "('content_type__app_label', 'content_type__model', 'codename')"}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}), + 'first_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'related_name': "'user_set'", 'to': "orm['auth.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'related_name': "'user_set'", 'to': "orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'}) + }, + 'cms.cmsplugin': { + 'Meta': {'object_name': 'CMSPlugin'}, + 'changed_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['cms.CMSPlugin']", 'null': 'True'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'unique': 'True'}), + 'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}), + 'plugin_type': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50'}), + 'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'blank': 'True', 'null': 'True'}) + }, + 'cms.placeholder': { + 'Meta': {'object_name': 'Placeholder'}, + 'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255'}) + }, + 'cmsplugin_filer_image.thumbnailoption': { + 'Meta': {'object_name': 'ThumbnailOption', 'ordering': "('width', 'height')"}, + 'crop': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'upscale': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'db_table': "'django_content_type'", 'object_name': 'ContentType'}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'djangocms_blog.authorentriesplugin': { + 'Meta': {'object_name': 'AuthorEntriesPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}), + 'latest_posts': ('django.db.models.fields.IntegerField', [], {'default': '5'}) + }, + 'djangocms_blog.blogcategory': { + 'Meta': {'object_name': 'BlogCategory'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'to': "orm['djangocms_blog.BlogConfig']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'date_modified': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogCategory']", 'null': 'True'}) + }, + 'djangocms_blog.blogcategorytranslation': { + 'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'BlogCategoryTranslation', 'db_table': "'djangocms_blog_blogcategory_translation'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.BlogCategory']", 'related_name': "'translations'", 'null': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '50'}) + }, + 'djangocms_blog.blogconfig': { + 'Meta': {'object_name': 'BlogConfig'}, + 'app_data': ('app_data.fields.AppDataField', [], {'default': "'{}'"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '100', 'unique': 'True'}), + 'paginate_by': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}), + 'set_author': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'djangocms_blog.blogconfigtranslation': { + 'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'BlogConfigTranslation', 'db_table': "'djangocms_blog_blogconfig_translation'"}, + 'app_title': ('django.db.models.fields.CharField', [], {'max_length': '234'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.BlogConfig']", 'related_name': "'translations'", 'null': 'True'}) + }, + 'djangocms_blog.genericblogplugin': { + 'Meta': {'object_name': 'GenericBlogPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}) + }, + 'djangocms_blog.latestpostsplugin': { + 'Meta': {'object_name': 'LatestPostsPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['djangocms_blog.BlogCategory']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}), + 'latest_posts': ('django.db.models.fields.IntegerField', [], {'default': '5'}) + }, + 'djangocms_blog.post': { + 'Meta': {'object_name': 'Post', 'ordering': "('-date_published', '-date_created')"}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'to': "orm['djangocms_blog.BlogConfig']"}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'djangocms_blog_post_author'", 'to': "orm['auth.User']", 'null': 'True'}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['djangocms_blog.BlogCategory']", 'related_name': "'blog_posts'"}), + 'content': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'related_name': "'post_content'", 'null': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'date_modified': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'date_published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'date_published_end': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}), + 'enable_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'main_image': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_image'", 'to': "orm['filer.Image']", 'null': 'True'}), + 'main_image_full': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_full'", 'to': "orm['cmsplugin_filer_image.ThumbnailOption']", 'null': 'True'}), + 'main_image_thumbnail': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_thumbnail'", 'to': "orm['cmsplugin_filer_image.ThumbnailOption']", 'null': 'True'}), + 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'sites': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['sites.Site']", 'null': 'True'}) + }, + 'djangocms_blog.posttranslation': { + 'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'PostTranslation', 'db_table': "'djangocms_blog_post_translation'"}, + 'abstract': ('djangocms_text_ckeditor.fields.HTMLField', [], {'blank': 'True', 'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.Post']", 'related_name': "'translations'", 'null': 'True'}), + 'meta_description': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}), + 'meta_keywords': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}), + 'meta_title': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'default': "''"}), + 'post_text': ('djangocms_text_ckeditor.fields.HTMLField', [], {'blank': 'True', 'default': "''"}), + 'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '50'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'filer.file': { + 'Meta': {'object_name': 'File'}, + '_file_size': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), + 'file': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'folder': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'all_files'", 'to': "orm['filer.Folder']", 'null': 'True'}), + 'has_all_mandatory_data': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'default': "''"}), + 'original_filename': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_files'", 'to': "orm['auth.User']", 'null': 'True'}), + 'polymorphic_ctype': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'related_name': "'polymorphic_filer.file_set+'", 'null': 'True'}), + 'sha1': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '40', 'default': "''"}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}) + }, + 'filer.folder': { + 'Meta': {'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder', 'ordering': "('name',)"}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'to': "orm['auth.User']", 'null': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'to': "orm['filer.Folder']", 'null': 'True'}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}) + }, + 'filer.image': { + 'Meta': {'object_name': 'Image'}, + '_height': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + '_width': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + 'author': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'date_taken': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}), + 'default_alt_text': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'default_caption': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'file_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['filer.File']", 'unique': 'True'}), + 'must_always_publish_author_credit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'must_always_publish_copyright': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subject_location': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '64', 'default': 'None', 'null': 'True'}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", 'db_table': "'django_site'", 'object_name': 'Site'}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + } + } + + complete_apps = ['djangocms_blog'] diff --git a/djangocms_blog/south_migrations/0015_create_appconfig.py b/djangocms_blog/south_migrations/0015_create_appconfig.py new file mode 100644 index 0000000..90c6d73 --- /dev/null +++ b/djangocms_blog/south_migrations/0015_create_appconfig.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models +from cms.models import Page +from cms.utils.conf import get_languages + + +class Migration(DataMigration): + + def forwards(self, orm): + BlogConfig = orm['djangocms_blog.BlogConfig'] + Post = orm['djangocms_blog.Post'] + BlogCategory = orm['djangocms_blog.BlogCategory'] + GenericBlogPlugin = orm['djangocms_blog.GenericBlogPlugin'] + LatestPostsPlugin = orm['djangocms_blog.LatestPostsPlugin'] + AuthorEntriesPlugin = orm['djangocms_blog.AuthorEntriesPlugin'] + config = None + for page in Page.objects.drafts().filter(application_urls='BlogApp'): + config = BlogConfig.objects.create(namespace=page.application_namespace) + for lang in get_languages(): + config.create_translation(lang, app_title='Blog') + if config: + for model in (Post, BlogCategory, GenericBlogPlugin, LatestPostsPlugin, AuthorEntriesPlugin): + for item in model.objects.all(): + item.app_config = config + item.save() + + def backwards(self, orm): + # No need for backward data migration + pass + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '80', 'unique': 'True'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['auth.Permission']"}) + }, + 'auth.permission': { + 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission', 'ordering': "('content_type__app_label', 'content_type__model', 'codename')"}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}), + 'first_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'related_name': "'user_set'", 'to': "orm['auth.Group']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '30'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'related_name': "'user_set'", 'to': "orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'}) + }, + 'cms.cmsplugin': { + 'Meta': {'object_name': 'CMSPlugin'}, + 'changed_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'depth': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['cms.CMSPlugin']", 'null': 'True'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'unique': 'True'}), + 'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}), + 'plugin_type': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50'}), + 'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'blank': 'True', 'null': 'True'}) + }, + 'cms.placeholder': { + 'Meta': {'object_name': 'Placeholder'}, + 'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slot': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '255'}) + }, + 'cmsplugin_filer_image.thumbnailoption': { + 'Meta': {'object_name': 'ThumbnailOption', 'ordering': "('width', 'height')"}, + 'crop': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'upscale': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'db_table': "'django_content_type'", 'object_name': 'ContentType'}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'djangocms_blog.authorentriesplugin': { + 'Meta': {'object_name': 'AuthorEntriesPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'authors': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}), + 'latest_posts': ('django.db.models.fields.IntegerField', [], {'default': '5'}) + }, + 'djangocms_blog.blogcategory': { + 'Meta': {'object_name': 'BlogCategory'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'to': "orm['djangocms_blog.BlogConfig']"}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'date_modified': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogCategory']", 'null': 'True'}) + }, + 'djangocms_blog.blogcategorytranslation': { + 'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'BlogCategoryTranslation', 'db_table': "'djangocms_blog_blogcategory_translation'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.BlogCategory']", 'related_name': "'translations'", 'null': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '50'}) + }, + 'djangocms_blog.blogconfig': { + 'Meta': {'object_name': 'BlogConfig'}, + 'app_data': ('app_data.fields.AppDataField', [], {'default': "'{}'"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'namespace': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '100', 'unique': 'True'}), + 'paginate_by': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}), + 'set_author': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'djangocms_blog.blogconfigtranslation': { + 'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'BlogConfigTranslation', 'db_table': "'djangocms_blog_blogconfig_translation'"}, + 'app_title': ('django.db.models.fields.CharField', [], {'max_length': '234'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.BlogConfig']", 'related_name': "'translations'", 'null': 'True'}) + }, + 'djangocms_blog.genericblogplugin': { + 'Meta': {'object_name': 'GenericBlogPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}) + }, + 'djangocms_blog.latestpostsplugin': { + 'Meta': {'object_name': 'LatestPostsPlugin'}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'blank': 'True', 'to': "orm['djangocms_blog.BlogConfig']"}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['djangocms_blog.BlogCategory']"}), + 'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['cms.CMSPlugin']", 'unique': 'True'}), + 'latest_posts': ('django.db.models.fields.IntegerField', [], {'default': '5'}) + }, + 'djangocms_blog.post': { + 'Meta': {'object_name': 'Post', 'ordering': "('-date_published', '-date_created')"}, + 'app_config': ('aldryn_apphooks_config.fields.AppHookConfigField', [], {'to': "orm['djangocms_blog.BlogConfig']"}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'djangocms_blog_post_author'", 'to': "orm['auth.User']", 'null': 'True'}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['djangocms_blog.BlogCategory']", 'related_name': "'blog_posts'"}), + 'content': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'related_name': "'post_content'", 'null': 'True'}), + 'date_created': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'date_modified': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'date_published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'date_published_end': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}), + 'enable_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'main_image': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_image'", 'to': "orm['filer.Image']", 'null': 'True'}), + 'main_image_full': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_full'", 'to': "orm['cmsplugin_filer_image.ThumbnailOption']", 'null': 'True'}), + 'main_image_thumbnail': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'related_name': "'djangocms_blog_post_thumbnail'", 'to': "orm['cmsplugin_filer_image.ThumbnailOption']", 'null': 'True'}), + 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'sites': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'to': "orm['sites.Site']", 'null': 'True'}) + }, + 'djangocms_blog.posttranslation': { + 'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'PostTranslation', 'db_table': "'djangocms_blog_post_translation'"}, + 'abstract': ('djangocms_text_ckeditor.fields.HTMLField', [], {'blank': 'True', 'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '15'}), + 'master': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangocms_blog.Post']", 'related_name': "'translations'", 'null': 'True'}), + 'meta_description': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}), + 'meta_keywords': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}), + 'meta_title': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'default': "''"}), + 'post_text': ('djangocms_text_ckeditor.fields.HTMLField', [], {'blank': 'True', 'default': "''"}), + 'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '50'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'filer.file': { + 'Meta': {'object_name': 'File'}, + '_file_size': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True', 'null': 'True'}), + 'file': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'folder': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'all_files'", 'to': "orm['filer.Folder']", 'null': 'True'}), + 'has_all_mandatory_data': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'default': "''"}), + 'original_filename': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_files'", 'to': "orm['auth.User']", 'null': 'True'}), + 'polymorphic_ctype': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'related_name': "'polymorphic_filer.file_set+'", 'null': 'True'}), + 'sha1': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '40', 'default': "''"}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}) + }, + 'filer.folder': { + 'Meta': {'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder', 'ordering': "('name',)"}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'modified_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'to': "orm['auth.User']", 'null': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'to': "orm['filer.Folder']", 'null': 'True'}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'auto_now_add': 'True'}) + }, + 'filer.image': { + 'Meta': {'object_name': 'Image'}, + '_height': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + '_width': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}), + 'author': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'date_taken': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}), + 'default_alt_text': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'default_caption': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '255', 'null': 'True'}), + 'file_ptr': ('django.db.models.fields.related.OneToOneField', [], {'primary_key': 'True', 'to': "orm['filer.File']", 'unique': 'True'}), + 'must_always_publish_author_credit': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'must_always_publish_copyright': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subject_location': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '64', 'default': 'None', 'null': 'True'}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", 'db_table': "'django_site'", 'object_name': 'Site'}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + } + } + + complete_apps = ['djangocms_blog'] diff --git a/djangocms_blog/templates/djangocms_blog/post_detail.html b/djangocms_blog/templates/djangocms_blog/post_detail.html index 9313f11..1ca1fe3 100644 --- a/djangocms_blog/templates/djangocms_blog/post_detail.html +++ b/djangocms_blog/templates/djangocms_blog/post_detail.html @@ -21,7 +21,7 @@ {% endif %} {% endspaceless %} - {% if use_placeholder %} + {% if post.app_config.use_placeholder %}
{% render_placeholder post.content %}
{% else %}
{% render_model post "post_text" "post_text" %}
diff --git a/djangocms_blog/views.py b/djangocms_blog/views.py index 31c64f5..87268d4 100644 --- a/djangocms_blog/views.py +++ b/djangocms_blog/views.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals +from aldryn_apphooks_config.mixins import AppConfigMixin from django.contrib.auth import get_user_model -from django.core.urlresolvers import resolve from django.utils.timezone import now from django.utils.translation import get_language from django.views.generic import DetailView, ListView @@ -14,25 +14,24 @@ from .settings import get_setting User = get_user_model() -class BaseBlogView(ViewUrlMixin): +class BaseBlogView(AppConfigMixin, ViewUrlMixin): def get_queryset(self): language = get_language() - queryset = self.model._default_manager.all().active_translations(language_code=language) + queryset = self.model._default_manager.namespace( + self.namespace + ).active_translations( + language_code=language + ) if not getattr(self.request, 'toolbar', False) or not self.request.toolbar.edit_mode: queryset = queryset.published() return queryset - def render_to_response(self, context, **response_kwargs): - response_kwargs['current_app'] = resolve(self.request.path).namespace - return super(BaseBlogView, self).render_to_response(context, **response_kwargs) - class PostListView(BaseBlogView, ListView): model = Post context_object_name = 'post_list' template_name = 'djangocms_blog/post_list.html' - paginate_by = get_setting('PAGINATION') view_url_name = 'djangocms_blog:posts-latest' def get_context_data(self, **kwargs): @@ -40,6 +39,9 @@ class PostListView(BaseBlogView, ListView): context['TRUNCWORDS_COUNT'] = get_setting('POSTS_LIST_TRUNCWORDS_COUNT') return context + def get_paginate_by(self, queryset): + return self.config.paginate_by + class PostDetailView(TranslatableSlugMixin, BaseBlogView, DetailView): model = Post diff --git a/setup.py b/setup.py index da66159..0623fcb 100755 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ setup( 'cmsplugin-filer', 'django-meta>=0.2', 'django-meta-mixin>=0.1.1', + 'aldryn-apphooks-config', ], license='BSD', zip_safe=False, diff --git a/tests/__init__.py b/tests/__init__.py index 9cf872c..73624fa 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -3,11 +3,13 @@ Tests for `djangocms_blog` module. """ from __future__ import absolute_import, print_function, unicode_literals +from copy import deepcopy from cmsplugin_filer_image.models import ThumbnailOption from django.contrib.auth import get_user_model from django.contrib.sites.models import Site -from django.utils.translation import activate +from parler.utils.context import smart_override +from djangocms_blog.cms_appconfig import BlogConfig from djangocms_helper.base_test import BaseTestCase from djangocms_blog.models import BlogCategory, Post @@ -31,85 +33,123 @@ class BaseTest(BaseTestCase): {'en': {'title': 'page one', 'template': 'page.html', 'publish': True}, 'fr': {'title': 'page un', 'publish': True}, 'it': {'title': 'pagina uno', 'publish': True}}, - {'en': {'title': 'page two', 'template': 'page.html', 'publish': True}, + {'en': {'title': 'page two', 'template': 'page.html', 'publish': True, + 'apphook': 'BlogApp', 'apphook_namespace': 'sample_app'}, 'fr': {'title': 'page deux', 'publish': True}, 'it': {'title': 'pagina due', 'publish': True}}, + {'en': {'title': 'page three', 'template': 'page.html', 'publish': True, + 'apphook': 'BlogApp', 'apphook_namespace': 'sample_app2'}, + 'fr': {'title': 'page trois', 'publish': True}, + 'it': {'title': 'pagina tre', 'publish': True}}, ) - data = { - 'it': [ - {'title': u'Primo post', 'abstract': u'

prima riga

', - 'description': u'Questa è la descrizione', 'keywords': u'keyword1, keyword2', - 'text': u'Testo del post'}, - {'title': u'Secondo post', 'abstract': u'

prima riga del secondo post

', - 'description': u'Descrizione del secondo post', 'keywords': u'keyword3, keyword4', - 'text': u'Testo del secondo post'}, - {'title': u'Terzo post', 'abstract': u'

prima riga del terzo post

', - 'description': u'Descrizione del terzo post', 'keywords': u'keyword5, keyword6', - 'text': u'Testo del terzo post'}, - ], - 'en': [ - {'title': u'First post', 'abstract': u'

first line

', - 'description': u'This is the description', 'keywords': u'keyword1, keyword2', - 'text': u'Post text'}, - {'title': u'Second post', 'abstract': u'

second post first line

', - 'description': u'Second post description', 'keywords': u'keyword3, keyword4', - 'text': u'Second post text'}, - {'title': u'Third post', 'abstract': u'

third post first line

', - 'description': u'third post description', 'keywords': u'keyword5, keyword6', - 'text': u'Third post text'} - ] - } + _post_data = ( + {'en': {'title': 'First post', 'abstract': '

first line

', + 'description': 'This is the description', 'keywords': 'keyword1, keyword2', + 'text': 'Post text', 'app_config': 'sample_app', 'publish': True}, + 'it': {'title': 'Primo post', 'abstract': '

prima riga

', + 'description': 'Questa è la descrizione', 'keywords': 'keyword1, keyword2', + 'text': 'Testo del post'}, + }, + {'en': {'title': 'Second post', 'abstract': '

second post first line

', + 'description': 'Second post description', 'keywords': 'keyword3, keyword4', + 'text': 'Second post text', 'app_config': 'sample_app', 'publish': False}, + 'it': {'title': 'Secondo post', 'abstract': '

prima riga del secondo post

', + 'description': 'Descrizione del secondo post', 'keywords': 'keyword3, keyword4', + 'text': 'Testo del secondo post', 'app_config': 'sample_app'}, + }, + {'en': {'title': 'Third post', 'abstract': '

third post first line

', + 'description': 'third post description', 'keywords': 'keyword5, keyword6', + 'text': 'Third post text', 'app_config': 'sample_app', 'publish': False}, + 'it': {'title': 'Terzo post', 'abstract': '

prima riga del terzo post

', + 'description': 'Descrizione del terzo post', 'keywords': 'keyword5, keyword6', + 'text': 'Testo del terzo post'}, + }, + {'en': {'title': 'Different appconfig', 'abstract': '

Different appconfig first line

', + 'description': 'Different appconfig description', 'keywords': 'keyword5, keyword6', + 'text': 'Different appconfig text', 'app_config': 'sample_app2', 'publish': True}, + 'it': {'title': 'Altro appconfig', 'abstract': '

prima riga del Altro appconfig

', + 'description': 'Descrizione Altro appconfig', 'keywords': 'keyword5, keyword6', + 'text': 'Testo del Altro appconfig'}, + }, + ) - cat_data = { - 'it': [ - {'name': u'Fortissimo'}, - {'name': u'Pianississimo'}, - {'name': u'Mezzo'}, - {'name': u'Forte', 'parent_id': _get_cat_pk('it', 'Mezzo')}, - ], - 'en': [ - {'name': u'Very loud'}, - {'name': u'Very very silent'}, - {'name': u'Almost'}, - {'name': u'Loud', 'parent_id': _get_cat_pk('en', 'Almost')}, - {'name': u'Silent', 'parent_id': _get_cat_pk('en', 'Almost')}, - ] - } + _categories_data = ( + {'en': {'name': 'Very loud', 'app_config': 'sample_app'}, + 'it': {'name': 'Fortissimo'}, + }, + {'en': {'name': 'Very very silent', 'app_config': 'sample_app'}, + 'it': {'name': 'Pianississimo'}, + }, + {'en': {'name': 'Almost', 'app_config': 'sample_app'}, + 'it': {'name': 'Mezzo'}, + }, + {'en': {'name': 'Loud', 'parent_id': _get_cat_pk('en', 'Almost'), 'app_config': 'sample_app'}, + 'it': {'name': 'Forte', 'parent_id': _get_cat_pk('it', 'Mezzo')}, + }, + {'en': {'name': 'Silent', 'parent_id': _get_cat_pk('en', 'Almost'), 'app_config': 'sample_app'}, + }, + {'en': {'name': 'Drums', 'app_config': 'sample_app2'}, + 'it': {'name': 'Tamburi'}, + }, + {'en': {'name': 'Guitars', 'app_config': 'sample_app2'}, + 'it': {'name': 'Chitarre'}, + }, + ) @classmethod def setUpClass(cls): super(BaseTest, cls).setUpClass() + cls.thumb_1 = ThumbnailOption.objects.create( + name='base', width=100, height=100, crop=True, upscale=False + ) + cls.thumb_2 = ThumbnailOption.objects.create( + name='main', width=200, height=200, crop=False, upscale=False + ) + cls.app_config_1 = BlogConfig.objects.create( + namespace='sample_app', app_title='app1' + ) + cls.app_config_2 = BlogConfig.objects.create( + namespace='sample_app2', app_title='app2' + ) + cls.app_config_1.app_data.config.paginate_by = 1 + cls.app_config_1.save() + cls.app_config_2.app_data.config.paginate_by = 2 + cls.app_config_2.save() + cls.app_configs = { + 'sample_app': cls.app_config_1, + 'sample_app2': cls.app_config_2, + } + cls.category_1 = BlogCategory.objects.create(name='category 1', app_config=cls.app_config_1) + cls.category_1.set_current_language('it', initialize=True) + cls.category_1.name = 'categoria 1' + cls.category_1.save() cls.site_2 = Site.objects.create(domain='http://example2.com', name='example 2') def setUp(self): - activate('en') super(BaseTest, self).setUp() - self.category_1 = BlogCategory.objects.create(name=u'category 1') - self.category_1.set_current_language('it', initialize=True) - self.category_1.name = u'categoria 1' - self.category_1.save() - self.thumb_1 = ThumbnailOption.objects.create( - name='base', width=100, height=100, crop=True, upscale=False - ) - self.thumb_2 = ThumbnailOption.objects.create( - name='main', width=200, height=200, crop=False, upscale=False - ) self.img = self.create_filer_image_object() def tearDown(self): - for post in Post.objects.all(): - post.delete() + Post.objects.all().delete() super(BaseTest, self).tearDown() + @classmethod + def tearDownClass(cls): + BlogConfig.objects.all().delete() + super(BaseTest, cls).tearDownClass() + def _get_category(self, data, category=None, lang='en'): + data = deepcopy(data) for k, v in data.items(): if hasattr(v, '__call__'): data[k] = v() if not category: - category = BlogCategory.objects.create(**data) + with smart_override(lang): + data['app_config'] = self.app_configs[data['app_config']] + category = BlogCategory.objects.create(**data) else: - category.set_current_language(lang) + category.set_current_language(lang, initialize=True) for attr, val in data.items(): setattr(category, attr, val) category.save() @@ -123,15 +163,18 @@ class BaseTest(BaseTestCase): 'abstract': data['abstract'], 'meta_description': data['description'], 'meta_keywords': data['keywords'], + 'app_config': self.app_configs[data['app_config']] } post = Post.objects.create(**post_data) else: - post.set_current_language(lang) - post.title = data['title'] - post.abstract = data['abstract'] - post.meta_description = data['description'] - post.meta_keywords = data['keywords'] - post.save() + post.create_translation( + lang, + title=data['title'], + abstract=data['abstract'], + meta_description=data['description'], + meta_keywords=data['keywords'] + ) + post = self.reload_model(post) post.categories.add(self.category_1) if sites: for site in sites: @@ -139,13 +182,12 @@ class BaseTest(BaseTestCase): return post def get_posts(self, sites=None): - post1 = self._get_post(self.data['en'][0], sites=sites) - post1 = self._get_post(self.data['it'][0], post1, 'it') - post1.publish = True - post1.main_image = self.img - post1.save() - post2 = self._get_post(self.data['en'][1], sites=sites) - post2 = self._get_post(self.data['it'][1], post2, 'it') - post2.main_image = self.img - post2.save() - return post1, post2 + posts = [] + for post in self._post_data: + post1 = self._get_post(post['en'], sites=sites) + post1 = self._get_post(post['it'], post=post1, lang='it') + post1.publish = post['en']['publish'] + post1.main_image = self.img + post1.save() + posts.append(post1) + return posts diff --git a/tests/test_menu.py b/tests/test_menu.py index 84d334c..56673d6 100644 --- a/tests/test_menu.py +++ b/tests/test_menu.py @@ -2,10 +2,11 @@ from __future__ import absolute_import, print_function, unicode_literals import copy +from aldryn_apphooks_config.utils import get_app_instance from django.utils.translation import activate from menus.menu_pool import menu_pool -from parler.utils.context import switch_language +from parler.utils.context import switch_language, smart_override from djangocms_blog.views import CategoryEntriesView, PostDetailView @@ -13,13 +14,15 @@ from . import BaseTest class MenuTest(BaseTest): + cats = [] + def setUp(self): super(MenuTest, self).setUp() self.cats = [self.category_1] - for i, cat_data in enumerate(self.cat_data['en']): - cat = self._get_category(cat_data) - if i < len(self.cat_data['it']): - cat = self._get_category(self.cat_data['it'][i], cat, 'it') + for i, lang_data in enumerate(self._categories_data): + cat = self._get_category(lang_data['en']) + if 'it' in lang_data: + cat = self._get_category(lang_data['it'], cat, 'it') self.cats.append(cat) activate('en') @@ -32,54 +35,46 @@ class MenuTest(BaseTest): """ Tests if all categories are present in the menu """ + self.get_posts() + self.get_pages() + for lang in ('en', 'it'): - request = self.get_page_request(None, self.user, - r'/%s/blog/' % lang, edit=False) - activate(lang) - nodes = menu_pool.get_nodes(request, namespace='BlogCategoryMenu') - nodes_copy = copy.deepcopy(nodes) - for cat in self.cats: - if not cat.has_translation(lang): - continue - with switch_language(cat, lang): - # find in node list - found = None - for node in nodes_copy: - if node.url == cat.get_absolute_url(): - found = node - break - self.assertIsNotNone(found) - nodes_copy.remove(found) - self.assertEqual(node.id, cat.id) - self.assertEqual(node.title, cat.name) - # check that all categories were found in menu - self.assertEqual(len(nodes_copy), 0) + request = self.get_page_request(None, self.user, r'/%s/page-two/' % lang) + with smart_override(lang): + nodes = menu_pool.get_nodes(request, namespace='BlogCategoryMenu') + nodes_url = set([node.url for node in nodes]) + cats_url = set([cat.get_absolute_url() for cat in self.cats if cat.has_translation(lang)]) + self.assertTrue(cats_url.issubset(nodes_url)) def test_modifier(self): """ Tests if correct category is selected in the menu according to context (view object) """ - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() + tests = ( # view class, view kwarg, view object, category - (PostDetailView, 'slug', post1, post1.categories.first()), + (PostDetailView, 'slug', posts[0], posts[0].categories.first()), (CategoryEntriesView, 'category', self.cats[2], self.cats[2]) ) for view_cls, kwarg, obj, cat in tests: - request = self.get_page_request(None, self.user, r'/en/blog/', edit=False) - activate('en') - with switch_language(obj, 'en'): - view_obj = view_cls() - view_obj.request = request - view_obj.kwargs = {kwarg: obj.slug} - view_obj.get(request) - # check if selected menu node points to cat - nodes = menu_pool.get_nodes(request, namespace='BlogCategoryMenu') - found = False - for node in nodes: - if node.selected: - self.assertEqual(node.url, cat.get_absolute_url()) - found = True - break - self.assertTrue(found) + request = self.get_page_request(pages[1], self.user, path=obj.get_absolute_url()) + with smart_override('en'): + with switch_language(obj, 'en'): + view_obj = view_cls() + view_obj.request = request + view_obj.namespace, view_obj.config = get_app_instance(request) + view_obj.app_config = self.app_config_1 + view_obj.kwargs = {kwarg: obj.slug} + view_obj.get(request) + # check if selected menu node points to cat + nodes = menu_pool.get_nodes(request, namespace='BlogCategoryMenu') + found = False + for node in nodes: + if node.selected: + self.assertEqual(node.url, obj.get_absolute_url()) + found = True + break + self.assertTrue(found) diff --git a/tests/test_models.py b/tests/test_models.py index 771ac94..9d40595 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -25,24 +25,41 @@ from . import BaseTest class AdminTest(BaseTest): + def setUp(self): + super(AdminTest, self).setUp() + admin.autodiscover() + def test_admin_fieldsets(self): - request = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=False) post_admin = admin.site._registry[Post] + request = self.get_page_request('/', self.user_staff, r'/en/blog/?app_config=%s' % self.app_config_1.pk, edit=False) - with self.settings(BLOG_USE_PLACEHOLDER=True): - fsets = post_admin.get_fieldsets(request) - self.assertFalse('post_text' in fsets[0][1]['fields']) + # Use placeholder + self.app_config_1.app_data.config.use_placeholder = True + self.app_config_1.save() + fsets = post_admin.get_fieldsets(request) + self.assertFalse('post_text' in fsets[0][1]['fields']) - with self.settings(BLOG_USE_PLACEHOLDER=False): - fsets = post_admin.get_fieldsets(request) - self.assertTrue('post_text' in fsets[0][1]['fields']) + self.app_config_1.app_data.config.use_placeholder = False + self.app_config_1.save() + fsets = post_admin.get_fieldsets(request) + self.assertTrue('post_text' in fsets[0][1]['fields']) - with self.settings(BLOG_USE_ABSTRACT=True): - fsets = post_admin.get_fieldsets(request) - self.assertTrue('abstract' in fsets[0][1]['fields']) - with self.settings(BLOG_USE_ABSTRACT=False): - fsets = post_admin.get_fieldsets(request) - self.assertFalse('abstract' in fsets[0][1]['fields']) + self.app_config_1.app_data.config.use_placeholder = True + self.app_config_1.save() + + # Use abstract + self.app_config_1.app_data.config.use_abstract = True + self.app_config_1.save() + fsets = post_admin.get_fieldsets(request) + self.assertTrue('abstract' in fsets[0][1]['fields']) + + self.app_config_1.app_data.config.use_abstract = False + self.app_config_1.save() + fsets = post_admin.get_fieldsets(request) + self.assertFalse('abstract' in fsets[0][1]['fields']) + + self.app_config_1.app_data.config.use_abstract = True + self.app_config_1.save() with self.settings(BLOG_MULTISITE=True): fsets = post_admin.get_fieldsets(request) @@ -51,49 +68,55 @@ class AdminTest(BaseTest): fsets = post_admin.get_fieldsets(request) self.assertFalse('sites' in fsets[1][1]['fields'][0]) - request = self.get_page_request('/', self.user, r'/en/blog/', edit=False) + request = self.get_page_request('/', self.user, r'/en/blog/?app_config=%s' % self.app_config_1.pk, edit=False) fsets = post_admin.get_fieldsets(request) self.assertTrue('author' in fsets[1][1]['fields'][0]) def test_admin_auto_author(self): - page1, page2 = self.get_pages() - data = deepcopy(self.data['en'][0]) + pages = self.get_pages() + data = deepcopy(self._post_data[0]['en']) with self.login_user_context(self.user): - with self.settings(BLOG_AUTHOR_DEFAULT=True): - data['date_published_0'] = now().strftime('%Y-%m-%d') - data['date_published_1'] = now().strftime('%H:%M:%S') - data['categories'] = self.category_1.pk - request = self.post_request(page1, 'en', user=self.user, data=data, path='/en/?edit_fields=post_text') - msg_mid = MessageMiddleware() - msg_mid.process_request(request) - post_admin = admin.site._registry[Post] - response = post_admin.add_view(request) - self.assertEqual(response.status_code, 302) - self.assertEqual(Post.objects.count(), 1) - self.assertEqual(Post.objects.get(translations__slug='first-post').author_id, - request.user.pk) + self.app_config_1.app_data.config.set_author = True + self.app_config_1.save() + data['date_published_0'] = now().strftime('%Y-%m-%d') + data['date_published_1'] = now().strftime('%H:%M:%S') + data['categories'] = self.category_1.pk + data['app_config'] = self.app_config_1.pk + request = self.post_request(pages[0], 'en', user=self.user, data=data, path=r'/en/blog/?app_config=%s' % self.app_config_1.pk) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + response = post_admin.add_view(request) + self.assertEqual(response.status_code, 302) + self.assertEqual(Post.objects.count(), 1) + self.assertEqual(Post.objects.get(translations__slug='first-post').author_id, request.user.pk) - with self.settings(BLOG_AUTHOR_DEFAULT=False): - data = deepcopy(self.data['en'][1]) - data['date_published_0'] = now().strftime('%Y-%m-%d') - data['date_published_1'] = now().strftime('%H:%M:%S') - data['categories'] = self.category_1.pk - request = self.post_request(page1, 'en', user=self.user, data=data, path='/en/?edit_fields=post_text') - msg_mid = MessageMiddleware() - msg_mid.process_request(request) - post_admin = admin.site._registry[Post] - response = post_admin.add_view(request) - self.assertEqual(response.status_code, 302) - self.assertEqual(Post.objects.count(), 2) - self.assertEqual(Post.objects.get(translations__slug='second-post').author_id, None) + self.app_config_1.app_data.config.set_author = False + self.app_config_1.save() + data = deepcopy(self._post_data[1]['en']) + data['date_published_0'] = now().strftime('%Y-%m-%d') + data['date_published_1'] = now().strftime('%H:%M:%S') + data['categories'] = self.category_1.pk + data['app_config'] = self.app_config_1.pk + request = self.post_request(pages[0], 'en', user=self.user, data=data, path=r'/en/blog/?app_config=%s' % self.app_config_1.pk) + msg_mid = MessageMiddleware() + msg_mid.process_request(request) + post_admin = admin.site._registry[Post] + response = post_admin.add_view(request) + self.assertEqual(response.status_code, 302) + self.assertEqual(Post.objects.count(), 2) + self.assertEqual(Post.objects.get(translations__slug='second-post').author_id, None) with self.settings(BLOG_AUTHOR_DEFAULT='staff'): - data = deepcopy(self.data['en'][2]) + self.app_config_1.app_data.config.set_author = True + self.app_config_1.save() + data = deepcopy(self._post_data[2]['en']) data['date_published_0'] = now().strftime('%Y-%m-%d') data['date_published_1'] = now().strftime('%H:%M:%S') data['categories'] = self.category_1.pk - request = self.post_request(page1, 'en', user=self.user, data=data, path='/en/?edit_fields=post_text') + data['app_config'] = self.app_config_1.pk + request = self.post_request(pages[0], 'en', user=self.user, data=data, path=r'/en/blog/?app_config=%s' % self.app_config_1.pk) msg_mid = MessageMiddleware() msg_mid.process_request(request) post_admin = admin.site._registry[Post] @@ -103,17 +126,18 @@ class AdminTest(BaseTest): self.assertEqual(Post.objects.get(translations__slug='third-post').author.username, 'staff') def test_admin_post_text(self): - page1, page2 = self.get_pages() - post = self._get_post(self.data['en'][0]) + pages = self.get_pages() + post = self._get_post(self._post_data[0]['en']) with self.login_user_context(self.user): with self.settings(BLOG_USE_PLACEHOLDER=False): - data = {'post_text': 'ehi text'} - request = self.post_request(page1, 'en', user=self.user, data=data, path='/en/?edit_fields=post_text') + data = {'post_text': 'ehi text', 'title': 'some title'} + request = self.post_request(pages[0], 'en', user=self.user, data=data, path='/en/?edit_fields=post_text') msg_mid = MessageMiddleware() msg_mid.process_request(request) post_admin = admin.site._registry[Post] response = post_admin.edit_field(request, post.pk, 'en') + #print(response.content.decode('utf-8')) self.assertEqual(response.status_code, 200) modified_post = Post.objects.language('en').get(pk=post.pk) self.assertEqual(modified_post.safe_translation_getter('post_text'), data['post_text']) @@ -122,8 +146,8 @@ class AdminTest(BaseTest): class ModelsTest(BaseTest): def test_model_attributes(self): - post = self._get_post(self.data['en'][0]) - post = self._get_post(self.data['it'][0], post, 'it') + post = self._get_post(self._post_data[0]['en']) + post = self._get_post(self._post_data[0]['it'], post, 'it') post.main_image = self.img post.save() post.set_current_language('en') @@ -186,8 +210,8 @@ class ModelsTest(BaseTest): self.assertEqual(post.get_title(), 'meta title') def test_manager(self): - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) + post1 = self._get_post(self._post_data[0]['en']) + post2 = self._get_post(self._post_data[1]['en']) # default queryset, published and unpublished posts months = Post.objects.get_months() @@ -222,7 +246,7 @@ class ModelsTest(BaseTest): self.assertEqual(len(Post.objects.archived()), 1) # counting with language fallback enabled - self._get_post(self.data['it'][0], post1, 'it') + self._get_post(self._post_data[0]['it'], post1, 'it') self.assertEqual(len(Post.objects.filter_by_language('it')), 2) # No fallback @@ -235,8 +259,8 @@ class ModelsTest(BaseTest): parler.appsettings.PARLER_LANGUAGES[Site.objects.get_current().pk][index]['hide_untranslated'] = False def test_tag_cloud(self): - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) + post1 = self._get_post(self._post_data[0]['en']) + post2 = self._get_post(self._post_data[1]['en']) post1.tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') post1.save() post2.tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') @@ -270,14 +294,14 @@ class ModelsTest(BaseTest): self.assertEqual(set(Post.objects.tag_cloud(published=False)), set(tags)) def test_plugin_latest(self): - post1 = self._get_post(self.data['en'][0]) - self._get_post(self.data['en'][1]) + post1 = self._get_post(self._post_data[0]['en']) + self._get_post(self._post_data[1]['en']) post1.tags.add('tag 1') post1.save() request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False) request_auth = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=False) request_edit = self.get_page_request('/', self.user_staff, r'/en/blog/', edit=True) - plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en') + plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) tag = Tag.objects.get(slug='tag-1') plugin.tags.add(tag) # unauthenticated users get no post @@ -292,11 +316,11 @@ class ModelsTest(BaseTest): self.assertEqual(len(plugin.get_posts(request)), 1) def test_copy_plugin_latest(self): - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) + post1 = self._get_post(self._post_data[0]['en']) + post2 = self._get_post(self._post_data[1]['en']) tag1 = Tag.objects.create(name='tag 1') tag2 = Tag.objects.create(name='tag 2') - plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en') + plugin = add_plugin(post1.content, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin.tags.add(tag1) plugin.tags.add(tag2) if CMS_30: @@ -309,10 +333,10 @@ class ModelsTest(BaseTest): self.assertEqual(set(new[0].tags.all()), set(plugin.tags.all())) def test_plugin_author(self): - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) + post1 = self._get_post(self._post_data[0]['en']) + post2 = self._get_post(self._post_data[1]['en']) request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False) - plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en') + plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin.authors.add(self.user) self.assertEqual(len(plugin.get_posts(request)), 0) self.assertEqual(plugin.get_authors()[0].count, 0) @@ -328,9 +352,9 @@ class ModelsTest(BaseTest): self.assertEqual(plugin.get_authors()[0].count, 2) def test_copy_plugin_author(self): - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) - plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en') + post1 = self._get_post(self._post_data[0]['en']) + post2 = self._get_post(self._post_data[1]['en']) + plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin.authors.add(self.user) if CMS_30: plugins = list(post1.content.cmsplugin_set.filter(language='en').order_by('tree_id', 'level', 'position')) @@ -342,9 +366,9 @@ class ModelsTest(BaseTest): def test_multisite(self): with override('en'): - post1 = self._get_post(self.data['en'][0], sites=(self.site_1,)) - post2 = self._get_post(self.data['en'][1], sites=(self.site_2,)) - post3 = self._get_post(self.data['en'][2], sites=(self.site_2, self.site_1)) + post1 = self._get_post(self._post_data[0]['en'], sites=(self.site_1,)) + post2 = self._get_post(self._post_data[1]['en'], sites=(self.site_2,)) + post3 = self._get_post(self._post_data[2]['en'], sites=(self.site_2, self.site_1)) self.assertEqual(len(Post.objects.all()), 3) with self.settings(**{'SITE_ID': self.site_1.pk}): diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 348a6ca..9981d81 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -16,73 +16,70 @@ from . import BaseTest class PluginTest(BaseTest): def test_plugin_latest(self): - page1, page2 = self.get_pages() - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) - post1.tags.add('tag 1') - post1.publish = True - post1.save() - ph = page1.placeholders.get(slot='content') + pages = self.get_pages() + posts = self.get_posts() + posts[0].tags.add('tag 1') + posts[0].publish = True + posts[0].save() + ph = pages[0].placeholders.get(slot='content') - plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en') + plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) tag = Tag.objects.get(slug='tag-1') plugin.tags.add(tag) - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1) self.assertTrue(rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1) self.assertTrue(rendered.find('

first line

') > -1) self.assertTrue(rendered.find('
-1) - self.assertTrue(rendered.find(post1.get_absolute_url()) > -1) + self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1) - category_2 = BlogCategory.objects.create(name=u'category 2') + category_2 = BlogCategory.objects.create(name='category 2', app_config=self.app_config_1) category_2.set_current_language('it', initialize=True) - category_2.name = u'categoria 2' + category_2.name = 'categoria 2' category_2.save() category_2.set_current_language('en') - post2.categories.add(category_2) - plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en') + posts[1].categories.add(category_2) + plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin.categories.add(category_2) - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-2') > -1) self.assertTrue(rendered.find(reverse('djangocms_blog:posts-category', kwargs={'category': category_2.slug})) > -1) self.assertTrue(rendered.find('

second post first line

') > -1) self.assertTrue(rendered.find('
-1) - self.assertTrue(rendered.find(post2.get_absolute_url()) > -1) + self.assertTrue(rendered.find(posts[1].get_absolute_url()) > -1) def test_plugin_authors(self): - page1, page2 = self.get_pages() - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) - post1.publish = True - post1.save() - post2.publish = True - post2.save() - ph = page1.placeholders.get(slot='content') - plugin = add_plugin(ph, 'BlogAuthorPostsPlugin', language='en') + pages = self.get_pages() + posts = self.get_posts() + posts[0].publish = True + posts[0].save() + posts[1].publish = True + posts[1].save() + ph = pages[0].placeholders.get(slot='content') + plugin = add_plugin(ph, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin.authors.add(self.user) - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) self.assertTrue(rendered.find(reverse('djangocms_blog:posts-author', kwargs={'username': self.user.get_username()})) > -1) self.assertTrue(rendered.find('2 articles') > -1) def test_plugin_tags(self): - page1, page2 = self.get_pages() - post1 = self._get_post(self.data['en'][0]) - post2 = self._get_post(self.data['en'][1]) - post1.tags.add('tag 1', 'tag 2', 'test tag') - post1.publish = True - post1.save() - post2.tags.add('test tag', 'another tag') - post2.publish = True - post2.save() - ph = page1.placeholders.get(slot='content') - plugin = add_plugin(ph, 'BlogTagsPlugin', language='en') - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + pages = self.get_pages() + posts = self.get_posts() + posts[0].tags.add('tag 1', 'tag 2', 'test tag') + posts[0].publish = True + posts[0].save() + posts[1].tags.add('test tag', 'another tag') + posts[1].publish = True + posts[1].save() + ph = pages[0].placeholders.get(slot='content') + plugin = add_plugin(ph, 'BlogTagsPlugin', language='en', app_config=self.app_config_1) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) for tag in Tag.objects.all(): self.assertTrue(rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1) @@ -94,38 +91,38 @@ class PluginTest(BaseTest): self.assertEqual(len(rx.findall(rendered)), 1) def test_blog_category_plugin(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() - post1.publish = True - post1.save() - post2.publish = True - post2.save() - ph = page1.placeholders.get(slot='content') - plugin = add_plugin(ph, 'BlogCategoryPlugin', language='en') + pages = self.get_pages() + posts = self.get_posts() + posts[0].publish = True + posts[0].save() + posts[1].publish = True + posts[1].save() + ph = pages[0].placeholders.get(slot='content') + plugin = add_plugin(ph, 'BlogCategoryPlugin', language='en', app_config=self.app_config_1) plugin_class = plugin.get_plugin_class_instance() - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) context = plugin_class.render(context, plugin, ph) self.assertTrue(context['categories']) self.assertEqual(list(context['categories']), [self.category_1]) def test_blog_archive_plugin(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() - post1.publish = True - post1.save() - post2.publish = True - post2.save() - ph = page1.placeholders.get(slot='content') - plugin = add_plugin(ph, 'BlogArchivePlugin', language='en') + pages = self.get_pages() + posts = self.get_posts() + posts[0].publish = True + posts[0].save() + posts[1].publish = True + posts[1].save() + ph = pages[0].placeholders.get(slot='content') + plugin = add_plugin(ph, 'BlogArchivePlugin', language='en', app_config=self.app_config_1) plugin_class = plugin.get_plugin_class_instance() - context = self.get_plugin_context(page1, 'en', plugin, edit=True) + context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) context = plugin_class.render(context, plugin, ph) self.assertEqual(context['dates'][0]['date'].date(), now().replace(year=now().year, month=now().month, day=1).date()) self.assertEqual(context['dates'][0]['count'], 2) - post2.publish = False - post2.save() + posts[1].publish = False + posts[1].save() context = plugin_class.render(context, plugin, ph) self.assertEqual(context['dates'][0]['date'].date(), now().replace(year=now().year, month=now().month, day=1).date()) self.assertEqual(context['dates'][0]['count'], 1) diff --git a/tests/test_toolbar.py b/tests/test_toolbar.py index be0ffb9..180191d 100644 --- a/tests/test_toolbar.py +++ b/tests/test_toolbar.py @@ -16,13 +16,13 @@ class ToolbarTest(BaseTest): Test that Blog toolbar is present and contains all items """ from cms.toolbar.toolbar import CMSToolbar - post = self._get_post(self.data['en'][0]) - page1, page2 = self.get_pages() - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=True) - setattr(request, BLOG_CURRENT_POST_IDENTIFIER, post) + posts = self.get_posts() + pages = self.get_pages() + request = self.get_page_request(pages[0], self.user, r'/en/blog/', edit=True) + setattr(request, BLOG_CURRENT_POST_IDENTIFIER, posts[0]) toolbar = CMSToolbar(request) toolbar.get_left_items() blog_menu = toolbar.menus['djangocms_blog'] self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_changelist'))), 1) self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_add'))), 1) - self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_change', args=(post.pk,)))), 1) + self.assertEqual(len(blog_menu.find_items(ModalItem, url=reverse('admin:djangocms_blog_post_change', args=(posts[0].pk,)))), 1) diff --git a/tests/test_views.py b/tests/test_views.py index 27c35e8..ebaf6dd 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -21,51 +21,53 @@ from . import BaseTest class ViewTest(BaseTest): def test_post_list_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() - request = self.get_page_request(page1, AnonymousUser(), r'/en/blog/', edit=False) + request = self.get_page_request(pages[0], AnonymousUser(), r'/en/blog/', edit=False) with smart_override('en'): view_obj = PostListView() view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 - self.assertEqual(list(view_obj.get_queryset()), [post1]) + self.assertEqual(list(view_obj.get_queryset()), [posts[0]]) - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=False) + request = self.get_page_request(pages[1], self.user, edit=False) view_obj.request = request view_obj.kwargs = {} qs = view_obj.get_queryset() self.assertEqual(qs.count(), 1) - self.assertEqual(set(qs), set([post1])) + self.assertEqual(set(qs), set([posts[0]])) - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=True) + request = self.get_page_request(pages[1], self.user, edit=True) view_obj.request = request - self.assertEqual(set(view_obj.get_queryset()), set([post1, post2])) + self.assertEqual(set(view_obj.get_queryset()), set([posts[0], posts[1], posts[2]])) view_obj.kwargs = {} view_obj.object_list = view_obj.get_queryset() view_obj.paginate_by = 1 context = view_obj.get_context_data(object_list=view_obj.object_list) self.assertTrue(context['is_paginated']) - self.assertEqual(list(context['post_list']), [post2]) - self.assertEqual(context['paginator'].count, 2) - self.assertEqual(context['post_list'][0].title, 'Second post') + self.assertEqual(list(context['post_list']), [posts[2]]) + self.assertEqual(context['paginator'].count, 3) + self.assertEqual(context['post_list'][0].title, 'Third post') response = view_obj.render_to_response(context) self.assertContains(response, context['post_list'][0].get_absolute_url()) with smart_override('it'): - request = self.get_page_request(page1, self.user, r'/it/blog/', lang='it', edit=True) + request = self.get_page_request(pages[1], self.user, lang='it', edit=True) view_obj.request = request view_obj.object_list = view_obj.get_queryset() context = view_obj.get_context_data(object_list=view_obj.object_list) - self.assertEqual(context['post_list'][0].title, 'Secondo post') + self.assertEqual(context['post_list'][0].title, 'Terzo post') response = view_obj.render_to_response(context) self.assertContains(response, context['post_list'][0].get_absolute_url()) def test_post_list_view_fallback(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() PARLER_FALLBACK = { 1: ( @@ -81,89 +83,103 @@ class ViewTest(BaseTest): with smart_override('fr'): view_obj = PostListView() - request = self.get_page_request(page1, self.user, r'/fr/blog/', lang='fr', edit=True) + request = self.get_page_request(pages[0], self.user, r'/fr/blog/', lang='fr', edit=True) view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.kwargs = {} view_obj.object_list = view_obj.get_queryset() view_obj.get_context_data(object_list=view_obj.object_list) - self.assertEqual(view_obj.get_queryset().count(), 2) + self.assertEqual(view_obj.get_queryset().count(), 3) PARLER_FALLBACK = add_default_language_settings(PARLER_FALLBACK) with override_parler_settings(PARLER_LANGUAGES=PARLER_FALLBACK): view_obj = PostListView() - request = self.get_page_request(page1, self.user, r'/fr/blog/', lang='fr', edit=True) + request = self.get_page_request(pages[0], self.user, r'/fr/blog/', lang='fr', edit=True) view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.kwargs = {} view_obj.object_list = view_obj.get_queryset() view_obj.get_context_data(object_list=view_obj.object_list) self.assertEqual(view_obj.get_queryset().count(), 0) def test_post_detail_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() with smart_override('en'): - with switch_language(post1, 'en'): - request = self.get_page_request(page1, AnonymousUser(), r'/en/blog/', edit=False) + with switch_language(posts[0], 'en'): + request = self.get_page_request(pages[0], AnonymousUser(), r'/en/blog/', edit=False) view_obj = PostDetailView() view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 with self.assertRaises(Http404): view_obj.kwargs = {'slug': 'not-existing'} post_obj = view_obj.get_object() - view_obj.kwargs = {'slug': post1.slug} + view_obj.kwargs = {'slug': posts[0].slug} post_obj = view_obj.get_object() - self.assertEqual(post_obj, post1) + self.assertEqual(post_obj, posts[0]) self.assertEqual(post_obj.language_code, 'en') with smart_override('it'): - with switch_language(post1, 'it'): - request = self.get_page_request(page1, AnonymousUser(), r'/it/blog/', lang='it', edit=False) + with switch_language(posts[0], 'it'): + request = self.get_page_request(pages[0], AnonymousUser(), r'/it/blog/', lang='it', edit=False) + view_obj = PostDetailView() view_obj.request = request - view_obj.kwargs = {'slug': post1.slug} + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 + + view_obj.kwargs = {'slug': posts[0].slug} post_obj = view_obj.get_object() - self.assertEqual(post_obj, post1) + self.assertEqual(post_obj, posts[0]) self.assertEqual(post_obj.language_code, 'it') view_obj.object = post_obj context = view_obj.get_context_data() - self.assertEqual(context['post'], post1) + self.assertEqual(context['post'], posts[0]) self.assertEqual(context['post'].language_code, 'it') self.assertTrue(context['meta']) def test_post_archive_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() with smart_override('en'): - request = self.get_page_request(page1, AnonymousUser(), r'/en/blog/', edit=False) + request = self.get_page_request(pages[0], AnonymousUser(), r'/en/blog/', edit=False) view_obj = PostArchiveView() view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.kwargs = {'year': now().year, 'month': now().month} # One post only, anonymous request qs = view_obj.get_queryset() self.assertEqual(qs.count(), 1) - self.assertEqual(list(qs), [post1]) + self.assertEqual(list(qs), [posts[0]]) view_obj.object_list = qs context = view_obj.get_context_data(object_list=view_obj.object_list) self.assertEqual(context['archive_date'].date(), now().replace(year=now().year, month=now().month, day=1).date()) def test_category_entries_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() with smart_override('en'): - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=True) + request = self.get_page_request(pages[0], self.user, r'/en/blog/', edit=True) view_obj = CategoryEntriesView() view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.kwargs = {'category': 'category-1'} qs = view_obj.get_queryset() - self.assertEqual(qs.count(), 2) - self.assertEqual(set(qs), set([post1, post2])) + self.assertEqual(qs.count(), 3) + self.assertEqual(set(qs), set([posts[0], posts[1], posts[2]])) view_obj.paginate_by = 1 view_obj.object_list = qs @@ -171,22 +187,29 @@ class ViewTest(BaseTest): self.assertTrue(context['category']) self.assertEqual(context['category'], self.category_1) self.assertTrue(context['is_paginated']) - self.assertEqual(list(context['post_list']), [post2]) - self.assertEqual(context['paginator'].count, 2) - self.assertEqual(context['post_list'][0].title, 'Second post') + self.assertEqual(list(context['post_list']), [posts[2]]) + self.assertEqual(context['paginator'].count, 3) + self.assertEqual(context['post_list'][0].title, 'Third post') + + request = self.get_page_request(pages[1], self.user, edit=False) + view_obj.request = request + qs = view_obj.get_queryset() + self.assertEqual(qs.count(), 1) def test_author_entries_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() + posts = self.get_posts() + pages = self.get_pages() with smart_override('en'): - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=True) + request = self.get_page_request(pages[1], self.user, edit=True) view_obj = AuthorEntriesView() + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.request = request view_obj.kwargs = {'username': self.user.get_username()} qs = view_obj.get_queryset() - self.assertEqual(qs.count(), 2) - self.assertEqual(set(qs), set([post1, post2])) + self.assertEqual(qs.count(), 3) + self.assertEqual(set(qs), set([posts[0], posts[1], posts[2]])) view_obj.paginate_by = 1 view_obj.object_list = qs @@ -194,74 +217,87 @@ class ViewTest(BaseTest): self.assertTrue(context['author']) self.assertEqual(context['author'], self.user) self.assertTrue(context['is_paginated']) - self.assertEqual(list(context['post_list']), [post2]) - self.assertEqual(context['paginator'].count, 2) - self.assertEqual(context['post_list'][0].title, 'Second post') + self.assertEqual(list(context['post_list']), [posts[2]]) + self.assertEqual(context['paginator'].count, 3) + self.assertEqual(context['post_list'][0].title, 'Third post') + + request = self.get_page_request(pages[1], self.user, edit=False) + view_obj.request = request + qs = view_obj.get_queryset() + self.assertEqual(qs.count(), 1) def test_taggedlist_view(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() - post1.tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') - post1.save() - post2.tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') - post2.save() + pages = self.get_pages() + posts = self.get_posts() + posts[0].tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') + posts[0].save() + posts[1].tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') + posts[1].save() with smart_override('en'): - request = self.get_page_request(page1, self.user, r'/en/blog/', edit=True) + request = self.get_page_request(pages[1], self.user, edit=True) view_obj = TaggedListView() view_obj.request = request + view_obj.namespace = self.app_config_1.namespace + view_obj.config = self.app_config_1 view_obj.kwargs = {'tag': 'tag-2'} qs = view_obj.get_queryset() self.assertEqual(qs.count(), 2) - self.assertEqual(set(qs), set([post1, post2])) + self.assertEqual(set(qs), set([posts[0], posts[1]])) view_obj.paginate_by = 1 view_obj.object_list = qs context = view_obj.get_context_data(object_list=view_obj.object_list) self.assertTrue(context['tagged_entries'], 'tag-2') self.assertTrue(context['is_paginated']) - self.assertEqual(list(context['post_list']), [post2]) + self.assertEqual(list(context['post_list']), [posts[1]]) self.assertEqual(context['paginator'].count, 2) self.assertEqual(context['post_list'][0].title, 'Second post') def test_feed(self): - page1, page2 = self.get_pages() - post1, post2 = self.get_posts() - post1.tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') - post1.save() - post2.tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') - post2.save() - post1.set_current_language('en') + pages = self.get_pages() + posts = self.get_posts() + posts[0].tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') + posts[0].save() + posts[1].tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') + posts[1].save() + posts[0].set_current_language('en') feed = LatestEntriesFeed() - self.assertEqual(list(feed.items()), [post1]) - request = self.get_page_request(page1, self.user, r'/en/blog/', lang='en', edit=False) + feed.namespace = self.app_config_1.namespace + feed.config = self.app_config_1 + self.assertEqual(list(feed.items()), [posts[0]]) + request = self.get_page_request(pages[1], self.user, lang='en', edit=False) xml = feed(request) - self.assertContains(xml, post1.get_absolute_url()) + self.assertContains(xml, posts[0].get_absolute_url()) self.assertContains(xml, 'Blog articles on example.com') with smart_override('it'): - with switch_language(post1, 'it'): + with switch_language(posts[0], 'it'): feed = LatestEntriesFeed() - self.assertEqual(list(feed.items()), [post1]) - request = self.get_page_request(page1, self.user, r'/it/blog/', lang='it', edit=False) + feed.namespace = self.app_config_1.namespace + feed.config = self.app_config_1 + self.assertEqual(list(feed.items()), [posts[0]]) + request = self.get_page_request(pages[1], self.user, lang='en', edit=False) xml = feed(request) - self.assertContains(xml, post1.get_absolute_url()) + self.assertContains(xml, posts[0].get_absolute_url()) self.assertContains(xml, 'Articoli del blog su example.com') feed = TagFeed() - self.assertEqual(list(feed.items('tag-2')), [post1]) + feed.namespace = self.app_config_1.namespace + feed.config = self.app_config_1 + self.assertEqual(list(feed.items('tag-2')), [posts[0]]) def test_sitemap(self): - post1, post2 = self.get_posts() - post1.tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') - post1.save() - post2.tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') - post2.publish = True - post2.save() - post1.set_current_language('en') + posts = self.get_posts() + posts[0].tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') + posts[0].save() + posts[1].tags.add('tag 6', 'tag 2', 'tag 5', 'tag 8') + posts[1].publish = True + posts[1].save() + posts[0].set_current_language('en') sitemap = BlogSitemap() - self.assertEqual(sitemap.items().count(), 2) + self.assertEqual(sitemap.items().count(), 3) for item in sitemap.items(): self.assertTrue(sitemap.lastmod(item).date(), now().today())