简体   繁体   中英

How to filter posts by tags using django-taggit in django

Currently, I'm still learning with Django and creating my blog using Django 2.2. but somehow there's an error when I using django-taggit.

How to filter the post by tags?

I've read the documentation but there's not fully covered about how to implement this into a real project.

Here's my code:

I've tried several different ways that I'm still searching from StackOverflow but still doesn't have an answer.

The results from /blog/tag/post-tagged is the same from /blog . So how do I filter it from views.py ? or perhaps from blog.html ?.

So the result of /blog/tag/post-tagged is only from the tagged post.

here's my code:

models.py :

...

from taggit.managers import TaggableManager



"Post Model"
class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=100, null=True, blank=True, unique=True)
    title = models.CharField(max_length=200)

    tags = TaggableManager(blank=True)
...

views.py :

def blogIndex(request):
    posts = Post.objects.all().order_by("-created_date")[0:4]
    context = {"posts": posts,}
    return render(request, 'blog.html',  context)



def Tagging(request, slug):

    tags = Tag.objects.filter(slug=slug)
    posts = Post.objects.all().order_by("-tags")

    context = {
        'tags': tags,
        'posts': posts,
    }
    return render(request, 'blog.html', context)

urls.py :

path("tag/<slug:slug>/", views.Tagging, name='tagged'),

my blog.html :

<div id="tags-middle">
   <div class="tags-cloud">
      Tags :
      {% for tag in post.tags.all %}
         <a href="{% url 'tagged' tag.slug %}">{{ tag.name }}</a>
      {% endfor %}
    </div>
</div>

I've solved this issue by filtering the tags from views.py .

Since I have multiple tags in my posts. so the __in and tags must be in the list .

Here's my views.py :

tags = Tag.objects.filter(slug=slug).values_list('name', flat=True)
posts = Post.objects.filter(tags__name__in=tags)

Basically, as the documentation said that we can filter by using string just like:

posts = Post.objects.filter(tags__name__in=["Lorem"])

But it only takes one string.

if I try by using multiple strings like ["Lorem", "Ipsum"] it will show me only a blank page on /blog/tag/lorem .

In my personal blog, i'm doing the following to filter the posts by a tag:

in the urls.py :

...
path('tag/<tag>', views.tag, name='tag'),
...

the views.py :

from django.shortcuts import render    
...
def tag(request, tag):
    "This page shows all posts with the related tag"
    
     posts = Post.objects.filter(tags__name=tag)
     return render(request, 'blog/tag.html', {'tag': tag, 'posts': posts})
    

With this you can have a blog/tag.html template something like:

<h2>List of posts of the tag "{{ tag }}"</h2>

{% if posts %}

<ul>

{% for post in posts %}

// displays whatever you want about the post

{% endfor %}

</ul>

{% else %}

<p>No post related to that tag yet.</p>

{% endif%}

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