Django Waffle

5.0.0 · active · verified Sat Apr 11

Django Waffle is a feature flipper for Django projects, allowing developers to dynamically toggle features on or off without redeploying code. It supports flags, switches, and samples, enabling use cases like A/B testing, phased rollouts, and granular control based on users, groups, or percentages. The library is actively maintained, with its current version being 5.0.0, and receives fairly steady updates.

Warnings

Install

Imports

Quickstart

To get started with Django Waffle, first install the package and add `'waffle'` to your `INSTALLED_APPS` and `'waffle.middleware.WaffleMiddleware'` to your `MIDDLEWARE` settings. Ensure `django.template.context_processors.request` is in your template context processors for template tag functionality. Run migrations (`python manage.py migrate`) to create Waffle's database tables. You can then define flags, switches, and samples via the Django Admin. In your Python code, use `waffle.flag_is_active()` or decorators like `@waffle_flag` to control logic or view access. In templates, load `waffle_tags` and use `{% flag 'name' %}` blocks to conditionally render content.

# settings.py
INSTALLED_APPS = [
    # ...
    'django.contrib.auth',
    'django.contrib.messages',
    'waffle',
    # ...
]

MIDDLEWARE = [
    # ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'waffle.middleware.WaffleMiddleware',
    # ...
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

# Terminal
# python manage.py migrate
# python manage.py createsuperuser # If you don't have one

# Then, log into Django Admin to create a Flag named 'my_new_feature'
# Set it to active for 'Superusers' or a percentage of users.

# views.py
from django.shortcuts import render
from waffle.decorators import waffle_flag
from waffle import flag_is_active

@waffle_flag('my_new_feature')
def my_feature_view(request):
    # This view will return a 404 if 'my_new_feature' flag is not active for the request.
    message = "Welcome to the new feature!"
    if flag_is_active(request, 'another_flag'):
        message += " (Another flag is also active.)"
    return render(request, 'my_app/feature_page.html', {'message': message})


def my_other_view(request):
    context = {}
    if flag_is_active(request, 'some_conditional_element'):
        context['show_element'] = True
    return render(request, 'my_app/regular_page.html', context)

# my_app/feature_page.html
{% extends 'base.html' %}
{% load waffle_tags %}

{% block content %}
    <h1>{{ message }}</h1>
    <p>This page is protected by 'my_new_feature' flag.</p>
{% endblock %}

# my_app/regular_page.html
{% extends 'base.html' %}
{% load waffle_tags %}

{% block content %}
    <h1>Regular Content</h1>
    {% flag 'some_conditional_element' %}
        <p>This element only shows if 'some_conditional_element' is active!</p>
    {% else %}
        <p>Conditional element is currently hidden.</p>
    {% endflag %}
{% endblock %}

view raw JSON →