Last modified: Oct 14, 2026

How to Install django-taggit

Tags make content easier to organize and discover. django-taggit is the most popular tagging library for Django, and it takes just three steps to set up.

Install the package, add it to your settings, and run migrations. Then you can attach tags to any model with a single line of code.

This guide covers the full installation process. You will also learn how to add tags in forms, display them in the admin, and use them with Django REST Framework.

What Is django-taggit?

django-taggit is a reusable Django application for simple, powerful tagging. It provides a TaggableManager that you can add to any model.

Unlike custom solutions that require join tables and manual queries, django-taggit handles everything behind the scenes. You get a clean API for adding, removing, and filtering tags.

The package works with Django 4.1 and above, and Python 3.8 or newer. It is a Jazzband project, which means it follows community governance and consistent maintenance standards.

Tags created through django-taggit work in forms and the Django admin automatically. You can also integrate them with Django REST Framework for API-based tagging.

Prerequisites

Before installing django-taggit, check that your environment meets these requirements.

  • Python 3.8 or higher installed
  • Django 4.1 or higher in your project
  • pip available for package installation
  • An active virtual environment is recommended

Activate your virtual environment before installing. This keeps django-taggit isolated from other projects on your system.

You should also have a Django project with at least one app and a configured database. If you are still setting up Django itself, get that working first.

Installing django-taggit with pip

The installation is a single command. Run this inside your activated virtual environment.

 pip install django-taggit 

This downloads the latest stable release from PyPI. The package has minimal dependencies, so installation is fast.

The current stable version is 6.1.0, released in September 2024. It supports Django 5.2 and 6.0, plus Python 3.13 and 3.14.

If you use a requirements file, pin the version for reproducible builds.

 pip install django-taggit==6.1.0 

Pinning prevents surprise upgrades during deployment. You can check the latest version on the PyPI page at any time.

Verifying the Installation

After installation, confirm the package is importable. Run this command in your terminal.

 python -c "import taggit; print(taggit.__version__)" 

You should see a version number printed.

 6.1.0 

The exact number may differ. What matters is that the import succeeds without errors.

If you see a "ModuleNotFoundError", pip installed the package for a different interpreter. Use python -m pip install django-taggit to ensure the correct target.

Adding taggit to INSTALLED_APPS

Open your project's settings.py file and add "taggit" to the INSTALLED_APPS list.

 # settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Third-party apps 'taggit', # Your apps 'myapp', ] 

The app label is taggit with no underscore or hyphen. The pip package is django-taggit, but the Django app name is just taggit.

Without this step, Django will not recognize the tagging models and migrations will fail.

Running Migrations

django-taggit includes database models for tags and the relationships between tags and your objects. Run migrations to create the required tables.

 python manage.py migrate 

You should see migration output for the taggit app.

 Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions, taggit Running migrations: Applying taggit.0001_initial... OK Applying taggit.0002_auto_20150616_2121... OK Applying taggit.0003_taggeditem_add_unique_index... OK ... 

Once migrations complete, the database has the tables needed for tagging. You are ready to add tags to your models.

Adding Tags to a Model

Adding tagging to a model takes one import and one line. Open your model file and add a TaggableManager field.

 # models.py from django.db import models from taggit.managers import TaggableManager class Food(models.Model): name = models.CharField(max_length=100) # Add the tags field tags = TaggableManager() def __str__(self): return self.name 

The TaggableManager() class creates a relationship between your model and the tag model. It works like a many-to-many field but with a much simpler API.

After adding the field, run migrations again to update your model's database schema.

 python manage.py makemigrations python manage.py migrate 

Now you can create objects and add tags to them through the Django shell or your application code.

Using Tags in Python

The django-taggit API is clean and intuitive. Open the Django shell to try it out.

 python manage.py shell 

Create an object and attach tags to it.

 >>> from myapp.models import Food >>> apple = Food.objects.create(name="apple") >>> apple.tags.add("red", "green", "delicious") >>> apple.tags.all() [, , ] 

The .add() method accepts one or more tag names. It creates the tags if they do not exist and links them to the object.

You can remove tags with the .remove() method.

 >>> apple.tags.remove("green") >>> apple.tags.all() [, ] 

Filtering objects by tag is equally simple. Use the tags__name__in lookup.

 >>> Food.objects.filter(tags__name__in=["red"]) [, ] 

The filter() method works like any standard Django queryset filter. You can combine tag filters with other conditions.

Case-Insensitive Tag Lookups

By default, django-taggit treats tags as case-sensitive. "Red" and "red" are different tags.

If you want case-insensitive lookups, add this setting to your settings.py file.

 # settings.py TAGGIT_CASE_INSENSITIVE = True 

With this enabled, looking up "red" will also match "Red" and "RED". The tag display name still preserves the original casing.

This setting defaults to False. Enable it if your users are likely to enter tags with inconsistent casing.

Tags in Forms

The TaggableManager appears automatically in any ModelForm. You do not need to add a separate field.

 # forms.py from django import forms from .models import Food class FoodForm(forms.ModelForm): class Meta: model = Food fields = ["name", "tags"] 

When the form renders, tags appear as a text input. Users enter tags as a space-delimited or comma-separated list.

The parser handles several input formats automatically. Quotes group multi-word tags together.

 # Examples of valid tag input "red green blue" # Three separate tags "red, green, blue" # Also three separate tags '"red apple" green' # One multi-word tag and one single tag 

If the input contains no commas or double quotes, it is treated as a space-delimited list. When commas or quotes are present, the parser uses more sophisticated rules.

Tags in the Django Admin

If you register your model in the admin, tags show up automatically. No extra configuration is required for the form itself.

However, you cannot put the TaggableManager directly in ModelAdmin.list_display. That causes an exception because of the many-to-many relationship.

The solution is a custom display method on your admin class.

 # admin.py from django.contrib import admin from .models import Food @admin.register(Food) class FoodAdmin(admin.ModelAdmin): list_display = ["name", "tag_list"] def tag_list(self, obj): """Display tags as a comma-separated string.""" return ", ".join(o.name for o in obj.tags.all()) 

The tag_list() method converts the tag objects into a readable string. It runs per row in the admin list view.

For better performance with many rows, override get_queryset() and add prefetch_related("tags"). This avoids a separate query for each row.

Using django-taggit with Django REST Framework

DRF requires special handling for the TaggableManager. The standard serializer cannot handle it directly.

django-taggit provides a TaggitSerializer and a TagListSerializerField for this purpose.

 # serializers.py from rest_framework import serializers from taggit.serializers import TaggitSerializer, TagListSerializerField from .models import Food class FoodSerializer(TaggitSerializer, serializers.ModelSerializer): tags = TagListSerializerField() class Meta: model = Food fields = ["id", "name", "tags"] 

The TaggitSerializer class handles the conversion between tag objects and JSON lists. The TagListSerializerField class defines the tags field.

With this serializer, your API accepts tag arrays in POST and PUT requests. It returns tag arrays in responses.

 # Example API request body { "name": "apple", "tags": ["red", "green", "delicious"] } 

If you are building APIs with authentication, you can pair django-taggit with a social login setup. This guide on how to set up social login with django-allauth shows how to add that layer.

Common Installation Problems

Problem: "No module named 'taggit'"

The package is not installed for the active Python interpreter. Reinstall with python -m pip install django-taggit to target the correct environment.

Problem: Migration errors after adding the field

Make sure "taggit" is in INSTALLED_APPS before running makemigrations. Without it, Django cannot resolve the tag model.

Problem: "TaggableManager is not JSON serializable" in DRF

You are using a standard ModelSerializer without the taggit serializer. Switch to the TaggitSerializer and TagListSerializerField shown above.

Problem: Tags not showing in the admin list view

You cannot put the field directly in list_display. Use a custom method like tag_list() to display tags as a string.

Problem: Slow admin page with many tagged objects

Each row makes a separate database query for tags. Add prefetch_related("tags") to the admin's queryset to batch the lookups.

Problem: Case-sensitive tag duplicates

Set TAGGIT_CASE_INSENSITIVE = True in your settings file. This makes "Red" and "red" resolve to the same tag.

Customizing Tag Behavior

django-taggit supports custom tag models and custom through models when the defaults are not enough.

You might want a custom tag model if you need to store extra data about tags, such as a description or an "official" flag. You might want a custom through model if your content model uses a non-integer primary key.

When using a custom tag or through model, you must remove "taggit" from INSTALLED_APPS. The default models are only created when the app is registered.

 # Example: custom through model from django.db import models from taggit.managers import TaggableManager from taggit.models import TaggedItemBase class TaggedFood(TaggedItemBase): content_object = models.ForeignKey("Food", on_delete=models.CASCADE) class Food(models.Model): name = models.CharField(max_length=100) tags = TaggableManager(through=TaggedFood) 

The through argument tells django-taggit to use your custom model instead of the default one. The API remains the same.

You can also provide a custom tag string parser by setting TAGGIT_TAGS_FROM_STRING and TAGGIT_STRING_FROM_TAGS in your settings file. This is useful when you need to preprocess tags, split on commas only, or reject certain characters.

Best Practices

Pin your version. Add django-taggit==6.1.0 to your requirements file for consistent behavior across environments.

Use prefetch_related for tag listings. Any page that displays tags for multiple objects should prefetch to avoid N+1 queries.

Decide on case sensitivity early. Enabling TAGGIT_CASE_INSENSITIVE after data exists creates duplicate-looking tags.

Validate tag input in forms. If your application has rules about tag length or allowed characters, add custom validation to the form.

Keep tag names short. Long tag names are hard to display and search. Enforce a reasonable maximum length.

Test your filters. Tag-based queries are easy to break during refactors. Write a few tests with real data.

If your application also uses filtering across other fields, django-taggit pairs well with query filtering tools. This guide on how to filter QuerySets with django-filter shows how to combine tag filters with other query parameters.

Conclusion

Installing django-taggit takes three steps. Run pip install django-taggit, add "taggit" to INSTALLED_APPS, and run migrations.

From there, adding tags to any model is a single line. The TaggableManager gives you a clean API for adding, removing, and filtering tags.

Tags appear automatically in forms and the admin. DRF integration needs one extra serializer class, but the setup is still minimal.

Customization is available when you need it. Custom tag models, custom through models, and custom parsers are all supported without leaving the package.

With django-taggit in place, your Django application gains flexible, searchable tagging without the overhead of building it yourself.