简体   繁体   中英

django-taggit - display all tags based on date vlog published

Using django-taggit-templatetags2 , I can display all the tags associated for a test vlog in a template page.

I have vlogs stored in the db that are not yet released to the public (only displayed after a certain date), so that I can store numerous vlog details in the db and then automatically release each individual vlog on a certain day (say Tuesday of each week).

This means that the django-taggit-templatetags2 display all code of {% for tag in vlog_tags %} will include tags for vlog entries that are not yet displayed to the user in the vlog but are stored in the db.

How can I only display the tags and the count for vlog entries where the vlog_date_published is not greater than now ? There may be the same tags that are used for published and not-yet published vlog entries. So this should be factored in to the display of the tag.

Here is my models code:

from taggit.managers import TaggableManager

class VlogDetails(models.Model):
    ....
    vlog_date_published = models.DateField(null=False, blank=False, default=datetime.now, help_text='The date the vlog video will be made public.')
    vlog_tags = TaggableManager(blank=True, help_text='To make a new tag, add a comma after the new tag name.')
    ....

Here is the display all tags template code:

    {% load taggit_templatetags2_tags %}

    {% get_taglist as vlog_tags %}

    {% for tag in vlog_tags %}
        {% if tag.num_times > 0 %}
            <a class='u-tags-v1 g-color-grey g-bg-grey-opacity-0_1 g-bg-grey--hover g-color-white--hover g-rounded-50 g-py-4 g-px-15' href="{% url 'vlog_tag' tag %}" hreflang="en" rel="tooltip" title="{% blocktrans %}Display all vlog entries containing this tag.{% endblocktrans %}"><i class="fa fa-tag icon_padding"></i> {{tag}} x {{tag.num_times}}</a>
        {% endif %}
    {% endfor %}

EDIT

Here are the screen shots from the database referring to the tag that is displayed to the user even though the vlog is not yet displayed to the user, but is stored in the db waiting to be automatically published based on the vlog_date_published > now .

In this scenario, the tag of Employment NDA should not be displayed to the user because the vlog entry that is using that tag is not yet displayed to the user as the vlog_date_published is greater than today (at the time of this post).

vlogdetails table (id = 24): 在此输入图像描述

taggit_taggeditem table (id=191 - FK's 24 & 123): 在此输入图像描述

taggit_tag table (id=123): 在此输入图像描述

ANOTHER EDIT

So in this scenario, the following tag of Employment NDA should not be displayed as it belongs to the vlog details that has not yet been published / displayed to the public, while all the other tags should be displayed (as the vlog details that all the other tags belong to have been published):

在此输入图像描述

This can be achieved by creating two custom template tags to replace the {{tag}} and the {{tag.num_times}} values from django-taggit-templatetags2 .

The conditional custom tag of {% if tag.id|vlog_tag_display %} will only display the tag if the related vlog published date is GT now and {{tag.num_times}} will be replaced by the custom tag of {{tag|vlog_tag_count}} as shown below.

First add the following code to your template page. This will loop through all the tags, but only display the tag if the vlog has been published:

{% load customised_template_tags i18n taggit_templatetags2_tags %}
{% get_taglist as tags %}

{% for tag in tags %}
    {% if tag.num_times > 0 %}
        {# only display the tag if the vlog is published #}
        {% if tag.id|vlog_tag_display %}
                <a class='u-tags-v1 g-color-grey g-bg-grey-opacity-0_1 g-bg-grey--hover g-color-white--hover g-rounded-50 g-py-4 g-px-15' href="{% url 'vlog_tag' tag %}" hreflang="en" rel="tooltip" title="{% blocktrans %}Display all vlog entries containing this tag.{% endblocktrans %}"><i class="fa fa-tag icon_padding"></i> {{tag}} x {{tag|vlog_tag_count}}</a>
        {% endif %}
    {% endif %}
{% empty %}
    {# No Tags recorded. #}
    <br /><b>{% trans "No Tags Recorded." %}</b><br />
{% endfor %}

Next add the following code to your custom template tags page. Here is a link to set up the custom template tags page if this is a new experience for you:

from zoodal.core.models import VlogDetails

@register.filter(name='vlog_tag_count')
def vlog_tag_count(value):
    date_now = timezone.now()
    count_vlog_tag = VlogDetails.objects.filter(vlog_date_published__lte=date_now, tags__name=value).count()
    """ Only count the tag if the vlog entry is published. """
    return count_vlog_tag


@register.filter(name='vlog_tag_display')
def vlog_tag_display(value):
    date_now = timezone.now()
    display_vlog_tag = VlogDetails.objects.filter(vlog_date_published__lte=date_now, tags__id=value)
    """ Only display the tag if the vlog entry is published. """
    if display_vlog_tag:
        return True
    else:
        return False

There are different ways you could do it.

Change default filter on the main model

class VlogDetailsManager(models.Manager):
    def get_queryset(self):
        return super(VlogDetailsManager, self).get_queryset().filter(vlog_date_published__lte=datetime.now())

class VlogDetails(models.Model):
    ....
    vlog_date_published = models.DateField(null=False, blank=False, default=datetime.now, help_text='The date the vlog video will be made public.')
    vlog_tags = TaggableManager(blank=True, help_text='To make a new tag, add a comma after the new tag name.')
    objects = VlogDetailsManager()
    ....

But not sure if this creates issues for you when you are editing.

Create a proxy model with a default filter

class VlogDetailsManager(models.Manager):
    def get_queryset(self):
        return super(VlogDetailsManager, self).get_queryset().filter(vlog_date_published__lte=datetime.now())

class VlogDetails(models.Model):
    ....
    vlog_date_published = models.DateField(null=False, blank=False, default=datetime.now, help_text='The date the vlog video will be made public.')
    vlog_tags = TaggableManager(blank=True, help_text='To make a new tag, add a comma after the new tag name.')
    ....

class VlogDetails2(VlogDetails):
      objects = VlogDetailsManager()
      class Meta:
            proxy = True

In this case you will set the VlogDetails2 as the model in the settings

Change source code of tag manager

Next option is to change the source code of the django-taggit-templatetags2 . The code for filtering happens here

https://github.com/fizista/django-taggit-templatetags2/blob/6c456bc0071dcd9e4bc4402a15be2a8bc031da81/taggit_templatetags2/templatetags/taggit_templatetags2_tags.py#L28

https://github.com/fizista/django-taggit-templatetags2/blob/6c456bc0071dcd9e4bc4402a15be2a8bc031da81/taggit_templatetags2/templatetags/taggit_templatetags2_tags.py#L44

You can add your filter there if you want. Not a recommended way of doing though

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM