Search code examples
pythondjangodjango-taggit

Better way to delete unused tag. / django taggit python


Hi i'm python django beginner.

I'm creating a simple blog

and i want to delete tags that are not used while deleting a post

class Post(models.Model):
    title = models.CharField(max_length=50)
    content = models.TextField(max_length=500)
    create_date = models.DateTimeField(auto_now_add=True)
    modify_date = models.DateTimeField(auto_now=True)
    tags = TaggableManager(blank=True)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='owner', blank=True, null=True)
class PostDelete(WriterCheckMixin, DeleteView):
    model = Post
    success_url = reverse_lazy('blog:list')

    def delete(self, request, *args, **kwargs):    
        temp = Post.objects.get(pk=kwargs['pk'])
        for tag in temp.tags.all():
            if tag.taggit_taggeditem_items.count() <= 1:
                tag.delete()
        return super().delete(request, *args, **kwargs)

I just follow tutorial so don't know what happens behind DeleteView.

It worked as intended but seems inefficient.

Do i need "temp = Post.objects.get(pk=kwargs['pk'])"?

Please give me advices.


Solution

  • You can delete unused tags with:

    from django.db.models import Count
    from taggit.models import Tag
    
    class PostDelete(WriterCheckMixin, DeleteView):
        model = Post
        success_url = reverse_lazy('blog:list')
    
        def delete(self, request, *args, **kwargs):
            try:
                return super().delete(request, *args, **kwargs)
            finally:
                Tag.objects.annotate(
                    ntag=Count('taggit_taggeditem_items')
                ).filter(ntag=0).delete()

    This will thus annotate the queryset, and remove the tags with no related items.

    That being said, I am not sure why you per se need to remove unused tags. You can decide to only render tags that have one item. But storing tags in the database, will normally not result in large amounts of disk usage anyway.