Move custom css loading to admin. Don't show author if not superuser.

Fix unique together for translated fields. Fix some manager issues.
Add default pagination to views
Simplify tag_clog() code
This commit is contained in:
Iacopo Spalletti 2014-01-10 06:37:55 +01:00
parent 3a772007f1
commit 1ac18873a0
10 changed files with 121 additions and 61 deletions

View file

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from admin_enhancer.admin import EnhancedModelAdminMixin
from cms.admin.placeholderadmin import PlaceholderAdmin, FrontendEditableAdmin
from copy import deepcopy
from django.contrib import admin
from django.conf import settings
from parler.admin import TranslatableAdmin
from .models import Post, BlogCategory
@ -11,6 +13,12 @@ class BlogCategoryAdmin(EnhancedModelAdminMixin, TranslatableAdmin):
def get_prepopulated_fields(self, request, obj=None):
return {"slug": ("name",)}
class Media:
css = {
'all': ('%sdjangocms_blog/css/%s' % (settings.STATIC_URL,
"djangocms_blog_admin.css"),)
}
class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdmin,
PlaceholderAdmin, TranslatableAdmin):
@ -19,13 +27,12 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdmin,
raw_id_fields = ['author']
frontend_editable_fields = ("title", "abstract")
enhance_exclude = ('main_image', 'tags')
change_form_template = "admin/djangocms_blog/post_change_form.html"
fieldsets = [
_fieldsets = [
(None, {
'fields': [('title', 'slug', 'publish'),
('categories', 'tags'),
('date_published', 'date_published_end'), 'author']
('date_published', 'date_published_end')]
}),
(None, {
'fields': [('main_image', 'main_image_thumbnail', 'main_image_full'),
@ -33,6 +40,14 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdmin,
}),
]
def get_fieldsets(self, request, obj=None):
if request.user.is_superuser:
fsets = deepcopy(self._fieldsets)
fsets[0][1]['fields'].append('author')
return fsets
else:
return self._fieldsets
def get_prepopulated_fields(self, request, obj=None):
return {"slug": ("title",)}
@ -41,5 +56,12 @@ class PostAdmin(EnhancedModelAdminMixin, FrontendEditableAdmin,
obj.author = request.user
super(PostAdmin, self).save_model(request, obj, form, change)
class Media:
css = {
'all': ('%sdjangocms_blog/css/%s' % (settings.STATIC_URL,
"djangocms_blog_admin.css"),)
}
admin.site.register(BlogCategory, BlogCategoryAdmin)
admin.site.register(Post, PostAdmin)

View file

@ -10,13 +10,13 @@ from .forms import LatestEntriesForm
class BlogPlugin(CMSPluginBase):
module = 'Blog'
class LatestEntriesPlugin(BlogPlugin):
render_template = 'djangocms_blog/plugins/latest_entries.html'
name = _('Latest Blog Entries')
name = _('Latest Blog Articles')
model = LatestPostsPlugin
form = LatestEntriesForm
filter_horizontal = ('categories',)
@ -25,10 +25,12 @@ class LatestEntriesPlugin(BlogPlugin):
context['instance'] = instance
return context
class AuthorPostsPlugin(BlogPlugin):
module = _('Blog')
name = _('Author Blog posts')
name = _('Author Blog Articles')
model = AuthorEntriesPlugin
form = LatestEntriesForm
render_template = 'djangocms_blog/plugins/authors.html'
filter_horizontal = ['authors']
@ -36,6 +38,7 @@ class AuthorPostsPlugin(BlogPlugin):
context['instance'] = instance
return context
class BlogTagsPlugin(BlogPlugin):
module = _('Blog')
name = _('Tags')
@ -46,6 +49,7 @@ class BlogTagsPlugin(BlogPlugin):
context['tags'] = Post.objects.tag_cloud(queryset=Post.objects.published())
return context
class BlogCategoryPlugin(BlogPlugin):
module = _('Blog')
name = _('Categories')
@ -56,6 +60,7 @@ class BlogCategoryPlugin(BlogPlugin):
context['categories'] = BlogCategory.objects.all()
return context
class BlogArchivePlugin(BlogPlugin):
module = _('Blog')
name = _('Archive')
@ -66,6 +71,7 @@ class BlogArchivePlugin(BlogPlugin):
context['dates'] = Post.objects.get_months(queryset=Post.objects.published())
return context
plugin_pool.register_plugin(LatestEntriesPlugin)
plugin_pool.register_plugin(AuthorPostsPlugin)
plugin_pool.register_plugin(BlogTagsPlugin)

View file

@ -13,16 +13,16 @@ class LatestEntriesFeed(Feed):
return reverse('djangocms_blog:latest-posts')
def title(self):
return _('Blog posts on %(site_name)s') % {'site_name': Site.objects.get_current().name}
return _('Blog articles on %(site_name)s') % {'site_name': Site.objects.get_current().name}
def items(self, obj):
return Post.objects.published().order_by('-date_published')[:10]
def item_title(self, item):
return item.lazy_translation_getter('title')
return item.safe_translation_getter('title')
def item_description(self, item):
return item.lazy_translation_getter('abstract')
return item.safe_translation_getter('abstract')
class TagFeed(LatestEntriesFeed):

View file

@ -2,8 +2,6 @@
from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.contrib.auth.models import User
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^djangocms_blog\.fields\.UsersWithPermsManyToManyField"])
class UsersWithPermsManyToManyField(models.ManyToManyField):
@ -27,4 +25,4 @@ class UsersWithPermsManyToManyField(models.ManyToManyField):
}
defaults.update(kwargs)
return super(UsersWithPermsManyToManyField, self).formfield(**defaults)
return super(UsersWithPermsManyToManyField, self).formfield(**defaults)

View file

@ -7,12 +7,12 @@ import django_select2
class LatestEntriesForm(forms.ModelForm):
class Meta:
widgets = {
'tags': django_select2.Select2MultipleWidget
}
class Media:
css = {
'all': ('%s/css/%s' % (settings.STATIC_URL, "djangocms_blog_admin.css"),)
'all': ('%sdjangocms_blog/css/%s' % (settings.STATIC_URL,
"djangocms_blog_admin.css"),)
}

View file

@ -50,23 +50,22 @@ class TaggedFilterItem(object):
qs = self.tag_list(other_model, queryset)
return qs.values("slug")
def tag_cloud(self, other_model=None, queryset=None, start=None):
from taggit_templatetags.templatetags.taggit_extras import get_weight_fun
def tag_cloud(self, other_model=None, queryset=None, published=True):
from taggit.models import TaggedItem
tag_ids = self._taglist(other_model, queryset)
tagquery = TaggedItem.tags_for(self.model).filter(id__in=tag_ids)
if start is not None:
tagquery = tagquery.filter(name__istartswith=start)
tagquery = tagquery.annotate(count=models.Count('taggit_taggeditem_items'))
count = tagquery.values_list('count', flat=True)
if len(count) > 0:
weight_fun = get_weight_fun(BLOG_TAGCLOUD_MIN,
BLOG_TAGCLOUD_MAX,
min(count), BLOG_TAGCLOUD_MAX)
tagquery = tagquery.order_by('name')
for tag in tagquery:
tag.weight = weight_fun(tag.count)
return tagquery
kwargs = {}
if published:
kwargs = TaggedItem.bulk_lookup_kwargs(self.model.objects.published())
kwargs['tag_id__in'] = tag_ids
counted_tags = dict(TaggedItem.objects
.filter(**kwargs)
.values('tag')
.annotate(count=models.Count('tag'))
.values_list('tag', 'count'))
tags = TaggedItem.tag_model().objects.filter(pk__in=counted_tags.keys())
for tag in tags:
tag.count = counted_tags[tag.pk]
return sorted(tags, key=lambda x: -x.count)
class GenericDateTaggedManager(TaggedFilterItem, TranslationManager):

View file

@ -12,12 +12,15 @@ class Migration(SchemaMigration):
db.create_table(u'djangocms_blog_blogcategory_translation', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('language_code', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, blank=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
('slug', self.gf('django.db.models.fields.SlugField')(max_length=50, blank=True, db_index=True)),
('master', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', null=True, to=orm['djangocms_blog.BlogCategory'])),
))
db.send_create_signal(u'djangocms_blog', ['BlogCategoryTranslation'])
# Adding unique constraint on 'BlogCategoryTranslation', fields ['language_code', 'slug']
db.create_unique(u'djangocms_blog_blogcategory_translation', ['language_code', 'slug'])
# Adding unique constraint on 'BlogCategoryTranslation', fields ['language_code', 'master']
db.create_unique(u'djangocms_blog_blogcategory_translation', ['language_code', 'master_id'])
@ -35,12 +38,15 @@ class Migration(SchemaMigration):
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('language_code', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)),
('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, blank=True)),
('slug', self.gf('django.db.models.fields.SlugField')(db_index=True, max_length=50, blank=True)),
('abstract', self.gf('djangocms_text_ckeditor.fields.HTMLField')()),
('master', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', null=True, to=orm['djangocms_blog.Post'])),
))
db.send_create_signal(u'djangocms_blog', ['PostTranslation'])
# Adding unique constraint on 'PostTranslation', fields ['language_code', 'slug']
db.create_unique(u'djangocms_blog_post_translation', ['language_code', 'slug'])
# Adding unique constraint on 'PostTranslation', fields ['language_code', 'master']
db.create_unique(u'djangocms_blog_post_translation', ['language_code', 'master_id'])
@ -77,7 +83,7 @@ class Migration(SchemaMigration):
db.send_create_signal(u'djangocms_blog', ['LatestPostsPlugin'])
# Adding M2M table for field tags on 'LatestPostsPlugin'
m2m_table_name = db.shorten_name(u'cmsplugin_latestpostsplugin_tags')
m2m_table_name = db.shorten_name(u'djangocms_blog_latestpostsplugin_tags')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('latestpostsplugin', models.ForeignKey(orm[u'djangocms_blog.latestpostsplugin'], null=False)),
@ -86,7 +92,7 @@ class Migration(SchemaMigration):
db.create_unique(m2m_table_name, ['latestpostsplugin_id', 'tag_id'])
# Adding M2M table for field categories on 'LatestPostsPlugin'
m2m_table_name = db.shorten_name(u'cmsplugin_latestpostsplugin_categories')
m2m_table_name = db.shorten_name(u'djangocms_blog_latestpostsplugin_categories')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('latestpostsplugin', models.ForeignKey(orm[u'djangocms_blog.latestpostsplugin'], null=False)),
@ -102,7 +108,7 @@ class Migration(SchemaMigration):
db.send_create_signal(u'djangocms_blog', ['AuthorEntriesPlugin'])
# Adding M2M table for field authors on 'AuthorEntriesPlugin'
m2m_table_name = db.shorten_name(u'cmsplugin_authorentriesplugin_authors')
m2m_table_name = db.shorten_name(u'djangocms_blog_authorentriesplugin_authors')
db.create_table(m2m_table_name, (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('authorentriesplugin', models.ForeignKey(orm[u'djangocms_blog.authorentriesplugin'], null=False)),
@ -115,9 +121,15 @@ class Migration(SchemaMigration):
# Removing unique constraint on 'PostTranslation', fields ['language_code', 'master']
db.delete_unique(u'djangocms_blog_post_translation', ['language_code', 'master_id'])
# Removing unique constraint on 'PostTranslation', fields ['language_code', 'slug']
db.delete_unique(u'djangocms_blog_post_translation', ['language_code', 'slug'])
# Removing unique constraint on 'BlogCategoryTranslation', fields ['language_code', 'master']
db.delete_unique(u'djangocms_blog_blogcategory_translation', ['language_code', 'master_id'])
# Removing unique constraint on 'BlogCategoryTranslation', fields ['language_code', 'slug']
db.delete_unique(u'djangocms_blog_blogcategory_translation', ['language_code', 'slug'])
# Deleting model 'BlogCategoryTranslation'
db.delete_table(u'djangocms_blog_blogcategory_translation')
@ -137,16 +149,16 @@ class Migration(SchemaMigration):
db.delete_table(u'cmsplugin_latestpostsplugin')
# Removing M2M table for field tags on 'LatestPostsPlugin'
db.delete_table(db.shorten_name(u'cmsplugin_latestpostsplugin_tags'))
db.delete_table(db.shorten_name(u'djangocms_blog_latestpostsplugin_tags'))
# Removing M2M table for field categories on 'LatestPostsPlugin'
db.delete_table(db.shorten_name(u'cmsplugin_latestpostsplugin_categories'))
db.delete_table(db.shorten_name(u'djangocms_blog_latestpostsplugin_categories'))
# Deleting model 'AuthorEntriesPlugin'
db.delete_table(u'cmsplugin_authorentriesplugin')
# Removing M2M table for field authors on 'AuthorEntriesPlugin'
db.delete_table(db.shorten_name(u'cmsplugin_authorentriesplugin_authors'))
db.delete_table(db.shorten_name(u'djangocms_blog_authorentriesplugin_authors'))
models = {
@ -230,12 +242,12 @@ class Migration(SchemaMigration):
'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['djangocms_blog.BlogCategory']", 'null': 'True', 'blank': 'True'})
},
u'djangocms_blog.blogcategorytranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'BlogCategoryTranslation', 'db_table': "u'djangocms_blog_blogcategory_translation'"},
'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'BlogCategoryTranslation', 'db_table': "u'djangocms_blog_blogcategory_translation'"},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
'master': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'null': 'True', 'to': u"orm['djangocms_blog.BlogCategory']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'})
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'blank': 'True'})
},
u'djangocms_blog.latestpostsplugin': {
'Meta': {'object_name': 'LatestPostsPlugin', 'db_table': "u'cmsplugin_latestpostsplugin'", '_ormbases': ['cms.CMSPlugin']},
@ -245,7 +257,7 @@ class Migration(SchemaMigration):
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['taggit.Tag']", 'symmetrical': 'False', 'blank': 'True'})
},
u'djangocms_blog.post': {
'Meta': {'object_name': 'Post'},
'Meta': {'ordering': "('-date_published', '-date_created')", 'object_name': 'Post'},
'author': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
'categories': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'blog_posts'", 'symmetrical': 'False', 'to': u"orm['djangocms_blog.BlogCategory']"}),
'content': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
@ -260,7 +272,7 @@ class Migration(SchemaMigration):
'publish': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
},
u'djangocms_blog.posttranslation': {
'Meta': {'unique_together': "[('language_code', 'master')]", 'object_name': 'PostTranslation', 'db_table': "u'djangocms_blog_post_translation'"},
'Meta': {'unique_together': "[('language_code', 'slug'), ('language_code', 'master')]", 'object_name': 'PostTranslation', 'db_table': "u'djangocms_blog_post_translation'"},
'abstract': ('djangocms_text_ckeditor.fields.HTMLField', [], {}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language_code': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
@ -321,4 +333,4 @@ class Migration(SchemaMigration):
}
}
complete_apps = ['djangocms_blog']
complete_apps = ['djangocms_blog']

View file

@ -11,10 +11,12 @@ from django.utils.translation import ugettext_lazy as _
from djangocms_text_ckeditor.fields import HTMLField
from filer.fields.image import FilerImageField
from parler.models import TranslatableModel, TranslatedFields
from parler.managers import TranslationManager
from taggit_autosuggest.managers import TaggableManager
from .managers import GenericDateTaggedManager
from . import settings
from .managers import GenericDateTaggedManager
from .fields import UsersWithPermsManyToManyField
class BlogCategory(TranslatableModel):
@ -28,16 +30,19 @@ class BlogCategory(TranslatableModel):
translations = TranslatedFields(
name=models.CharField(_('name'), max_length=255),
slug=models.SlugField(_('slug'), blank=True, unique=True),
slug=models.SlugField(_('slug'), blank=True, db_index=True),
meta={'unique_together': (('language_code', 'slug'),)}
)
objects = TranslationManager()
class Meta:
verbose_name = _('blog category')
verbose_name_plural = _('blog categories')
@property
def count(self):
return self.blog_posts.count()
return self.blog_posts.filter(publish=True).count()
def __unicode__(self):
return self.safe_translation_getter('name')
@ -55,7 +60,7 @@ class Post(TranslatableModel):
"""
Blog post
"""
author = models.ForeignKey(User)
author = models.ForeignKey(User, blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
@ -76,9 +81,9 @@ class Post(TranslatableModel):
translations = TranslatedFields(
title=models.CharField(max_length=255),
slug=models.SlugField(_('slug'), blank=True, unique=True),
slug=models.SlugField(_('slug'), blank=True, db_index=True),
abstract=HTMLField(),
meta={'unique_together': (('language_code', 'slug'),)}
)
content = PlaceholderField("post_content")
@ -86,8 +91,9 @@ class Post(TranslatableModel):
tags = TaggableManager(blank=True)
class Meta:
verbose_name = _('blog post')
verbose_name_plural = _('blog post')
verbose_name = _('blog article')
verbose_name_plural = _('blog articles')
ordering = ("-date_published", "-date_created")
def __unicode__(self):
return self.safe_translation_getter('title')
@ -129,12 +135,15 @@ class Post(TranslatableModel):
class LatestPostsPlugin(CMSPlugin):
latest_posts = models.IntegerField(default=5, help_text=_('The number of latests posts to be displayed.'))
tags = models.ManyToManyField('taggit.Tag', blank=True, help_text=_('Show only the blog posts tagged with chosen tags.'))
categories = models.ManyToManyField('BlogCategory', blank=True, help_text=_('Show only the blog posts tagged with chosen tags.'))
latest_posts = models.IntegerField(_(u'Articles'), default=settings.BLOG_LATEST_POSTS,
help_text=_('The number of latests articles to be displayed.'))
tags = models.ManyToManyField('taggit.Tag', blank=True,
help_text=_('Show only the blog articles tagged with chosen tags.'))
categories = models.ManyToManyField('BlogCategory', blank=True,
help_text=_('Show only the blog articles tagged with chosen tags.'))
def __unicode__(self):
return u"%s latest post by tag" % self.latest_posts
return u"%s latest articles by tag" % self.latest_posts
def copy_relations(self, oldinstance):
self.tags = oldinstance.tags.all()
@ -148,11 +157,14 @@ class LatestPostsPlugin(CMSPlugin):
class AuthorEntriesPlugin(CMSPlugin):
authors = models.ManyToManyField(User, verbose_name=_('Authors'))
latest_posts = models.IntegerField(default=5, help_text=_('The number of author entries to be displayed.'))
#authors = models.ManyToManyField(User, verbose_name=_('Authors'))
authors = UsersWithPermsManyToManyField(perms=['add_post'],
verbose_name=_('Authors'))
latest_posts = models.IntegerField(_(u'Articles'), default=settings.BLOG_LATEST_POSTS,
help_text=_('The number of author articles to be displayed.'))
def __unicode__(self):
return u"%s latest post by author" % self.latest_posts
return u"%s latest articles by author" % self.latest_posts
def copy_relations(self, oldinstance):
self.authors = oldinstance.authors.all()
@ -163,4 +175,7 @@ class AuthorEntriesPlugin(CMSPlugin):
def get_authors(self):
authors = self.authors.all()
for author in authors:
if author.post_set.filter(publish=True).exists:
author.count = author.post_set.filter(publish=True).count()
return authors

View file

@ -13,4 +13,6 @@ BLOG_IMAGE_FULL_SIZE = {
}
BLOG_TAGCLOUD_MIN = 1
BLOG_TAGCLOUD_MAX = 10
BLOG_TAGCLOUD_MAX = 10
BLOG_PAGINATION = 10
BLOG_LATEST_POSTS = 5

View file

@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from django.views.generic import ListView, DetailView
from .models import Post, BlogCategory
from .settings import BLOG_PAGINATION
class BaseBlogView(object):
@ -28,6 +29,7 @@ class PostListView(BaseBlogView, ListView):
model = Post
context_object_name = 'post_list'
template_name = "djangocms_blog/post_list.html"
paginate_by = BLOG_PAGINATION
class PostDetailView(BaseBlogView, DetailView):
@ -44,6 +46,7 @@ class PostArchiveView(BaseBlogView, ListView):
date_field = 'date_published'
allow_empty = True
allow_future = True
paginate_by = BLOG_PAGINATION
def get_queryset(self):
qs = super(PostArchiveView, self).get_queryset()
@ -65,6 +68,7 @@ class TaggedListView(BaseBlogView, ListView):
model = Post
context_object_name = 'post_list'
template_name = "djangocms_blog/post_list.html"
paginate_by = BLOG_PAGINATION
def get_queryset(self):
qs = super(TaggedListView, self).get_queryset()
@ -80,6 +84,7 @@ class AuthorEntriesView(BaseBlogView, ListView):
model = Post
context_object_name = 'post_list'
template_name = "djangocms_blog/post_list.html"
paginate_by = BLOG_PAGINATION
def get_queryset(self):
qs = super(AuthorEntriesView, self).get_queryset()
@ -97,6 +102,7 @@ class CategoryEntriesView(BaseBlogView, ListView):
context_object_name = 'post_list'
template_name = "djangocms_blog/post_list.html"
_category = None
paginate_by = BLOG_PAGINATION
@property
def category(self):