这不是最漂亮的解决方案(主要是因为你必须在两个地方选择你的类别,如果你想保持你的站点地图井井有条),但它确实允许你根据各自的类别获取最近的条目,我想分享它,以防其他缺乏 Python 全面专业知识的人正在寻求实现此功能。
而且,如果您精通python,也许这个解决方案会让您感到不安,以至于发布一个更好的解决方案:)
从我可以从 Zinnia 的其他模板标签中收集到的上下文线索中,我推断如果“Featured=True”被“Featured”条目过滤,那么也许我可以扩展管理员中的条目模型以包含其他类型的“Featured”复选框,其中将与发布的条目的类别相对应。在这种情况下,我添加了“Featured_politics”。
然后我对以下文件进行了更改(本质上,我在整个项目中搜索了“featured”,并复制/粘贴了相应的代码,并将“featured”更改为“featured_politics”):
百日草/admin/entry.py
class EntryAdmin(admin.ModelAdmin):
"""
Admin for Entry model.
"""
form = EntryAdminForm
date_hierarchy = 'publication_date'
fieldsets = (
(_('Content'), {
'fields': (('title', 'status'), 'lead', 'content',)}),
(_('Illustration'), {
'fields': ('image', 'image_caption'),
'classes': ('collapse', 'collapse-closed')}),
(_('Publication'), {
'fields': ('publication_date', 'sites',
('start_publication', 'end_publication')),
'classes': ('collapse', 'collapse-closed')}),
(_('Discussions'), {
'fields': ('comment_enabled', 'pingback_enabled',
'trackback_enabled'),
'classes': ('collapse', 'collapse-closed')}),
(_('Privacy'), {
'fields': ('login_required', 'password'),
'classes': ('collapse', 'collapse-closed')}),
(_('Templates'), {
'fields': ('content_template', 'detail_template'),
'classes': ('collapse', 'collapse-closed')}),
(_('Metadatas'), {
'fields': ('featured', 'featured_politics', 'excerpt', 'authors', 'related'),
'classes': ('collapse', 'collapse-closed')}),
(None, {'fields': ('categories', 'tags', 'slug')}))
list_filter = (CategoryListFilter, AuthorListFilter,
'publication_date', 'sites', 'status')
list_display = ('get_title', 'get_authors', 'get_categories',
'get_tags', 'get_sites', 'get_is_visible', 'featured',
'get_short_url', 'publication_date')
radio_fields = {'content_template': admin.VERTICAL,
'detail_template': admin.VERTICAL}
filter_horizontal = ('categories', 'authors', 'related')
prepopulated_fields = {'slug': ('title', )}
search_fields = ('title', 'excerpt', 'content', 'tags')
actions = ['make_mine', 'make_published', 'make_hidden',
'close_comments', 'close_pingbacks', 'close_trackbacks',
'ping_directories', 'put_on_top',
'mark_featured', 'mark_featured_poltics', 'unmark_featured_poltics', 'unmark_featured']
def mark_featured_politics(self, request, queryset):
"""
Mark selected as featured post.
"""
queryset.update(featured_politics=True)
self.message_user(
request, _('Selected entries are now marked as featured in politics.'))
mark_featured_politics.short_description = _('Mark selected entries as featured in politics.')
def unmark_featured(self, request, queryset):
"""
Un-Mark selected featured posts.
"""
queryset.update(featured=False)
self.message_user(
request, _('Selected entries are no longer marked as featured.'))
unmark_featured.short_description = _(
'Unmark selected entries as featured')
def unmark_featured_politics(self, request, queryset):
"""
Un-Mark selected featured posts.
"""
queryset.update(featured_politics=False)
self.message_user(
request, _('Selected entries are no longer marked as featured in politics.'))
unmark_featured_politics.short_description = _(
'Unmark selected entries as featured in politics.')
zinnia/fixtures/helloworld.json(不确定这是否有必要,但这是我在此处所做的几个更改的摘录——看起来完全相同——更改)。
"featured": false,
"featured_politics": false,
"start_publication": null,
"pingback_enabled": true,
"trackback_enabled": true,
"authors": [
百日草/models_bases/entry.py
class FeaturedEntry(models.Model):
"""
Abstract model class to mark entries as featured.
"""
featured = models.BooleanField(
_('featured'), default=False)
class Meta:
abstract = True
class FeaturedEntryPolitics(models.Model):
"""
Abstract model class to mark entries as featured.
"""
featured_politics = models.BooleanField(
_('featured_politics'), default=False)
class Meta:
abstract = True
并且,在 models_bases/entry.py 的底部,更新此列表以包含您的新类:
class AbstractEntry(
CoreEntry,
ContentEntry,
DiscussionsEntry,
RelatedEntry,
LeadEntry,
ExcerptEntry,
ImageEntry,
FeaturedEntry,
FeaturedEntryPolitics,
AuthorsEntry,
CategoriesEntry,
TagsEntry,
LoginRequiredEntry,
PasswordRequiredEntry,
ContentTemplateEntry,
DetailTemplateEntry):
百日草/模板标签/百日草.py
@register.inclusion_tag('zinnia/tags/dummy.html')
def get_featured_entries(number=5,
template='zinnia/tags/entries_featured.html'):
"""
Return the featured entries.
"""
return {'template': template,
'entries': Entry.published.filter(featured=True)[:number]}
@register.inclusion_tag('zinnia/tags/dummy.html')
def get_politics_entries(number=5,
template='recent_politics.html'):
"""
Return the featured entries.
"""
return {'template': template,
'entries': Entry.published.filter(featured_politics=True)[:number]}
百日草/xmlrpc/metaweblog.py
# Useful Wordpress Extensions
'wp_author': author.get_username(),
'wp_author_id': author.pk,
'wp_author_display_name': author.__str__(),
'wp_password': entry.password,
'wp_slug': entry.slug,
'sticky': entry.featured,
'sticky': entry.featured_politics}
@xmlrpc_func(returns='struct[]', args=['string', 'string', 'string'])
def get_users_blogs(apikey, username, password):
"""
blogger.getUsersBlogs(api_key, username, password)
=> blog structure[]
"""
authenticate(username, password)
site = Site.objects.get_current()
return [blog_structure(site)]
@xmlrpc_func(returns='struct', args=['string', 'string', 'string'])
def get_user_info(apikey, username, password):
"""
blogger.getUserInfo(api_key, username, password)
=> user structure
"""
user = authenticate(username, password)
site = Site.objects.get_current()
return user_structure(user, site)
@xmlrpc_func(returns='struct[]', args=['string', 'string', 'string'])
def get_authors(apikey, username, password):
"""
wp.getAuthors(api_key, username, password)
=> author structure[]
"""
authenticate(username, password)
return [author_structure(author)
for author in Author.objects.filter(is_staff=True)]
@xmlrpc_func(returns='boolean', args=['string', 'string',
'string', 'string', 'string'])
def delete_post(apikey, post_id, username, password, publish):
"""
blogger.deletePost(api_key, post_id, username, password, 'publish')
=> boolean
"""
user = authenticate(username, password, 'zinnia.delete_entry')
entry = Entry.objects.get(id=post_id, authors=user)
entry.delete()
return True
@xmlrpc_func(returns='struct', args=['string', 'string', 'string'])
def get_post(post_id, username, password):
"""
metaWeblog.getPost(post_id, username, password)
=> post structure
"""
user = authenticate(username, password)
site = Site.objects.get_current()
return post_structure(Entry.objects.get(id=post_id, authors=user), site)
@xmlrpc_func(returns='struct[]',
args=['string', 'string', 'string', 'integer'])
def get_recent_posts(blog_id, username, password, number):
"""
metaWeblog.getRecentPosts(blog_id, username, password, number)
=> post structure[]
"""
user = authenticate(username, password)
site = Site.objects.get_current()
return [post_structure(entry, site)
for entry in Entry.objects.filter(authors=user)[:number]]
@xmlrpc_func(returns='struct[]', args=['string', 'string', 'string'])
def get_tags(blog_id, username, password):
"""
wp.getTags(blog_id, username, password)
=> tag structure[]
"""
authenticate(username, password)
site = Site.objects.get_current()
return [tag_structure(tag, site)
for tag in Tag.objects.usage_for_queryset(
Entry.published.all(), counts=True)]
@xmlrpc_func(returns='struct[]', args=['string', 'string', 'string'])
def get_categories(blog_id, username, password):
"""
metaWeblog.getCategories(blog_id, username, password)
=> category structure[]
"""
authenticate(username, password)
site = Site.objects.get_current()
return [category_structure(category, site)
for category in Category.objects.all()]
@xmlrpc_func(returns='string', args=['string', 'string', 'string', 'struct'])
def new_category(blog_id, username, password, category_struct):
"""
wp.newCategory(blog_id, username, password, category)
=> category_id
"""
authenticate(username, password, 'zinnia.add_category')
category_dict = {'title': category_struct['name'],
'description': category_struct['description'],
'slug': category_struct['slug']}
if int(category_struct['parent_id']):
category_dict['parent'] = Category.objects.get(
pk=category_struct['parent_id'])
category = Category.objects.create(**category_dict)
return category.pk
@xmlrpc_func(returns='string', args=['string', 'string', 'string',
'struct', 'boolean'])
def new_post(blog_id, username, password, post, publish):
"""
metaWeblog.newPost(blog_id, username, password, post, publish)
=> post_id
"""
user = authenticate(username, password, 'zinnia.add_entry')
if post.get('dateCreated'):
creation_date = datetime.strptime(
post['dateCreated'].value[:18], '%Y-%m-%dT%H:%M:%S')
if settings.USE_TZ:
creation_date = timezone.make_aware(
creation_date, timezone.utc)
else:
creation_date = timezone.now()
entry_dict = {'title': post['title'],
'content': post['description'],
'excerpt': post.get('mt_excerpt', ''),
'publication_date': creation_date,
'creation_date': creation_date,
'last_update': creation_date,
'comment_enabled': post.get('mt_allow_comments', 1) == 1,
'pingback_enabled': post.get('mt_allow_pings', 1) == 1,
'trackback_enabled': post.get('mt_allow_pings', 1) == 1,
'featured': post.get('sticky', 0) == 1,
'featured_politics': post.get('sticky', 0) == 1,
'tags': 'mt_keywords' in post and post['mt_keywords'] or '',
'slug': 'wp_slug' in post and post['wp_slug'] or slugify(
post['title']),
'password': post.get('wp_password', '')}
if user.has_perm('zinnia.can_change_status'):
entry_dict['status'] = publish and PUBLISHED or DRAFT
entry = Entry.objects.create(**entry_dict)
author = user
if 'wp_author_id' in post and user.has_perm('zinnia.can_change_author'):
if int(post['wp_author_id']) != user.pk:
author = Author.objects.get(pk=post['wp_author_id'])
entry.authors.add(author)
entry.sites.add(Site.objects.get_current())
if 'categories' in post:
entry.categories.add(*[
Category.objects.get_or_create(
title=cat, slug=slugify(cat))[0]
for cat in post['categories']])
return entry.pk
@xmlrpc_func(returns='boolean', args=['string', 'string', 'string',
'struct', 'boolean'])
def edit_post(post_id, username, password, post, publish):
"""
metaWeblog.editPost(post_id, username, password, post, publish)
=> boolean
"""
user = authenticate(username, password, 'zinnia.change_entry')
entry = Entry.objects.get(id=post_id, authors=user)
if post.get('dateCreated'):
creation_date = datetime.strptime(
post['dateCreated'].value[:18], '%Y-%m-%dT%H:%M:%S')
if settings.USE_TZ:
creation_date = timezone.make_aware(
creation_date, timezone.utc)
else:
creation_date = entry.creation_date
entry.title = post['title']
entry.content = post['description']
entry.excerpt = post.get('mt_excerpt', '')
entry.publication_date = creation_date
entry.creation_date = creation_date
entry.last_update = timezone.now()
entry.comment_enabled = post.get('mt_allow_comments', 1) == 1
entry.pingback_enabled = post.get('mt_allow_pings', 1) == 1
entry.trackback_enabled = post.get('mt_allow_pings', 1) == 1
entry.featured = post.get('sticky', 0) == 1
entry.featured_politics = post.get('sticky', 0) == 1
不要忘记您已经对模型进行了更改,因此您需要运行迁移!
现在,我可以使用{% get_politics_entries 3 template="homepage_latest_politics.html" %}
.
不完全相关,但以防万一它对任何人都有帮助,我的 homepage_latest_politics.html 模板是:
{% load i18n %}
<div class="row {% if not entries %}no-{% endif %}entries-featured_poltics">
{% for entry in entries %}
<div class="col s4">
<div class="card large">
<div class="card-image">
<img src="{% if entry.image %}{{ entry.image.url }}{% endif %}" alt="{{ entry.title }}">
<span class="card-title">{{ entry.title }}</span>
</div>
<div class="card-content">
<p>{{ entry.excerpt|safe|linebreaks|truncatewords_html:30 }}</p>
</div>
<div class="card-action">
<a href="#">Click to read more.</a>
</div>
</div>
</div>
{% endfor %}
</div>
这是 zinnia 的标签与 Materialise 的“Card”组件的集成,并产生了这个——条目是最新的选中“Featured_politics”框的条目:
嘿——我确实说过这不是最漂亮的解决方案,但是......它有效!