Django Waffle: Quick intro for dynamic feature toggling
I have recently discovered the power of Django Waffle. This is the quickstart tutorial I wish I had.
Published: July 10, 2021 Sponsored App StoreBefore we look at Django Waffle let's briefly talk about what "feature flags" mean.
What are feature flags?
Feature flags (also known as toggles and switches) are feature that lets you turn features of your app on and off. This can be simple admin toggle, or more sophisticated logic like showing new feature to 20 % of your users. The key is that you don't need to release new version of your app to do these modifications.
Installing Django Waffle
First steps towards feature flags with Django Waffle is the installation.
pip install django-waffle
And then we add waffle
to the INSTALLED_APPS
in settings.
INSTALLED_APPS = [
'waffle',
]
And also to middleware:
MIDDLEWARE = [
'waffle.middleware.WaffleMiddleware',
]
And as a last preparation step, run the migrations:
python3 manage.py migrate
Using Django Waffle switches
Switches are powerful yet easy to configure and use. Switch needs just a name and whether it is active or not.
Let's make this a practical example. First step is to define the switch in Django Admin. I am going to use show_new_sidebar
for the demonstration.
Once the switch is created, I can base logic in views and templates based on whether it is active or not.
Using switches in templates
There are two steps to use Django Waffle in templates. First you need to load the tags:
{% load waffle_tags %}
And now we can use switch
block to wrap template content we want to control.
{% switch 'show_new_sidebar' %}
<h1>Heads up! Switch is active!</h1>
{% endswitch %}
The usage is pretty straightforward. If switch show_new_sidebar
is active, content inside the block will be rendered.
Using switches in views
First step is import:
import waffle
And then we would do something like this:
if waffle.switch_is_active('show_new_sidebar'):
# load objects for use in the sidebar
Waffle does not require the request
so you can use it in helper classes and elsewhere without issues.
Creating switches automatically
Another nice feature of Django Waffle is that it will create new switch in the database when it encounters new one. But you need to enable this in settings.py
:
WAFFLE_CREATE_MISSING_SWITCHES = True
Using Django Waffle flags
Another feature of Django Waffle package are flags. These offer much more than switches. This offers you a lot of control over who sees features behind flags. Explaining everything would be for another two posts, so we will look quickly at the basic usage.
Flag can be set to be active for 10 % of your users for example. You can also always activate it for Superusers, testing sessions and more. Or you can set flags based on languages, for groups of users and more. Check the docs for details.
Using flags in templates
The first step is once again to load the tags:
{% load waffle_tags %}
And the actual usage mirrors switches:
{% flag 'dynamic_search' %}
{% endflag %}
Note that with both switches and flags you can have {% else %}
block inside to render content which should be visible only if switch or flag is off.
Using flags in views
For completeness, let's look at how to use flags in views or Python code to be precise. If you guessed that it is very similar to switches, you are correct.
import waffle
And then we would do something like this:
if waffle.flag_is_active(request, flag_name='dynamic_search'):
# extra logic
Toggling entire views with Django Waffle
To wrap up, there is another cool feature this package provides. With the use of a decorators, we can control visibility of specific views. When the switch or flag are inactive, the view will return 404.
from waffle.decorators import waffle_switch
@waffle_switch('stats_page_visible')
def stats_view(request):
# View code
And to really end this post (😁), here is the same as above, but using flag:
from waffle.decorators import waffle_flag
@waffle_flag('stats_page_visible')
def stats_view(request):
# View code