如何在Zinnia注册templatetag以显示特定类别的最新条目?

时间:2016-06-24 11:22:17

标签: django zinnia

我正在为安装了Zinnia的django项目构建一个主页,该项目将显示每个类别的最新条目。 Here,Fantomas42建议注册一个带有get_recent_entries标记并添加了一个过滤子句的新模板标签,这是实现这一目标的最佳方式。

我试着看看其他模板标签来收集如何通过上下文线索编写这个过滤器子句,但标签被设计为动态工作,而不是抓取任何特别命名的东西,所以我无法完全解析如何编写一个子句这将过滤特定类别。

我不确定是否最好写一个子句来过滤一个slug(在这种情况下,该类别的slug是政治节拍),类别名称通过字符串(“The Political Beat”) ,或者通过类别在类别树中的位置(这将是位置1,因为它是迄今为止唯一注册的类别 - 除非它再次为0 ...我真的希望我有时间退一步并采取一些措施python教程...)。

对于上下文,以下是Zinnia注册的其他一些模板标记:

@register.inclusion_tag('zinnia/tags/dummy.html', takes_context=True)
    def get_categories(context, template='zinnia/tags/categories.html'):
    """
    Return the published categories.
    """
    return {'template': template,
            'categories': Category.published.all().annotate(
                count_entries_published=Count('entries')),
            'context_category': context.get('category')}


@register.inclusion_tag('zinnia/tags/dummy.html', takes_context=True)
def get_categories_tree(context,
template='zinnia/tags/categories_tree.html'):
    """
    Return the categories as a tree.
    """
    return {'template': template,
            'categories': Category.objects.all(),
            'context_category': context.get('category')}


@register.inclusion_tag('zinnia/tags/dummy.html', takes_context=True)
def get_authors(context, template='zinnia/tags/authors.html'):
    """
    Return the published authors.
    """
    return {'template': template,
            'authors': Author.published.all().annotate(
                count_entries_published=Count('entries')),
            'context_author': context.get('author')}


@register.inclusion_tag('zinnia/tags/dummy.html')
def get_recent_entries(number=5,
template='zinnia/tags/entries_recent.html'):
    """
    Return the most recent entries.
    """
    return {'template': template,
            'entries': Entry.published.all()[:number]}



@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_draft_entries(number=5,
                      template='zinnia/tags/entries_draft.html'):
    """
    Return the last draft entries.
    """
    return {'template': template,
            'entries': Entry.objects.filter(status=DRAFT)[:number]}

我正在盲目地尝试解决方案,但如果我偶然发现它,我会更新答案!

编辑:这是我与Zinnia整合的主页模板的照片,以防它有助于澄清创建新模板标签的目标。Photo of homepage.

1 个答案:

答案 0 :(得分:0)

这不是最漂亮的解决方案(主要是因为你必须在两个地方选择你的类别,如果你想保持你的站点地图的顺序),但它 允许你获得最近的条目基于他们各自的类别,我想分享它,以防其他缺乏python专业知识的人正在寻求实现这一功能。

而且,如果你精通python,也许这个解决方案会让你心烦意乱,发布更好的一个:)

从我可以从Zinnia的其他模板标签中收集的上下文线索中,我推断如果“Featured = True”按“精选”条目过滤,那么我可以将管理员中的条目模型扩展为包含其他类型的“精选”复选框,与发布的条目类别相对应。在这种情况下,我添加了“Featured_politics”。

然后我对以下文件进行了更改(基本上,我在整个项目中搜索“精选”,并复制/粘贴相应的代码,并将“精选”更改为“featured_politics”):

<强>百日草/管理/ 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 (不确定这是否有必要,但这是几个摘录 - 看起来完全一样 - 我在这里所做的更改)。< / p>

      "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):

<强>百日草/ templatetags / zinnia.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”框:

enter image description here

enter image description here

嘿 - 我确实说它不是最漂亮的解决方案,但是......它有效!

相关问题