In web development, the management of feature flags is vital for facilitating the gradual introduction of new features, executing A/B tests, and ensuring that your application can quickly adapt to the evolving business requirements without the need for new code deployment.

In Django, django-flags is an application that provides such features.


What is Django-Flags?

Django-Flags is an application designed specifically for Django, which empowers developers to utilize feature flags in their Django projects. This app offers a dynamic approach to controlling the visibility and behavior of various features within web applications.

By integrating Django-Flags into a project, developers gain the ability to toggle feature flags on and off with ease. This can be accomplished through multiple methods, including the user-friendly admin interface, database records, or by configuring settings in the settings.py file.

With Django-Flags, developers can streamline the process of enabling or disabling specific features without having to modify and redeploy the codebase. This results in a more efficient development workflow, as well as the ability to adapt quickly to changing project requirements or user preferences.

It also facilitates the implementation of targeted feature rollouts, A/B testing, and other experimentation strategies, ultimately leading to improved user experiences and more successful web applications.


Getting Started with Django-Flags

To get started with django-flags, you'll first need to install it. You can easily add it to your Django project by running the following command:

pip install django-flags

After installing, add flags to your INSTALLED_APPS in your settings.py:

INSTALLED_APPS = [
    ...
    'flags',
    ...
]

Then, add the built-in django.template.context_processors.request to the TEMPLATES context_processors setting so that the request variable is available:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # …
        'OPTIONS': {
            # …
            'context_processors': [
                # …
                'django.template.context_processors.request',
                # …
            ],
            # …
        },
        # …
    },
]

Finally, run migrations:

python manage.py migrate

Excited to dive deeper into the world of Python programming? Look no further than my latest ebook, "Python Tricks - A Collection of Tips and Techniques".

Get the eBook

Inside, you'll discover a plethora of Python secrets that will guide you through a journey of learning how to write cleaner, faster, and more Pythonic code. Whether it's mastering data structures, understanding the nuances of object-oriented programming, or uncovering Python's hidden features, this ebook has something for everyone.

Defining Feature Flags

Feature flags can be defined in your Django settings (settings.py) by adding a FLAGS dictionary. Here's an example of how to define a feature flag:

FLAGS = {
    'MY_FEATURE': [{'condition': 'boolean', 'value': True}],
}

In this example, MY_FEATURE is the name of the feature flag, and it is currently set to a boolean condition with the value set as True, meaning the feature is enabled.

Checking Flags in Views

To check the status of a flag within a view, you can use the flag_enabled function. This allows you to conditionally execute code based on the flag's status:

from flags.state import flag_enabled

def my_view(request):
    if flag_enabled('MY_FEATURE', request=request):
        # The feature is enabled, do something
        pass
    else:
        # The feature is disabled, do something else
        pass

Using Flags in Templates

Django-Flags also provides template tags for checking feature flags. First, load the feature_flags template tags in your template and establish a flag condition:

{% load feature_flags %}
{% flag_enabled 'MY_FLAG' as my_flag %}

Then, you can use the my_flag variable to conditionally display parts of your template:

{% if my_flag %}
    <!-- The feature is enabled, display something -->
{% else %}
    <!-- The feature is disabled, display something else -->
{% endif %}

Managing Flags in Admin Interface

If you want to manage feature flags through the Django admin interface, you'll need to create a FlagState model instance for each flag you wish to control.

Like this:

Managing flags in the Django Admin interface

Advanced Configuration of Flags

In addition to the simple boolean condition shown earlier, django-flags allows you to define more complex conditions for a feature flag.

For example, you can enable a feature only for specific users:

FLAGS = {
  'MY_FLAG': [{'condition': 'user', 'value': 'jane.doe'}]
}

In this configuration, MY_FLAG is only enabled if the user is "jane.doe".

Using Flags with View Decorators

For a cleaner approach in controlling access to entire views based on feature flags, django-flags offers view decorators. This method encapsulates the feature flag check, making your view code more readable and concise.

Here’s how you can use the @flag_required decorator to protect a view:

from flags.decorators import flag_required

@flag_required('MY_ADVANCED_FEATURE', fallback_view='fallback_view_name')
def my_protected_view(request):
    # This view is only accessible if MY_ADVANCED_FEATURE is enabled
    ...

If the flag is not enabled, the request will be redirected to the specified fallback_view_name. This allows you to gracefully degrade functionality or provide alternative content when a feature is not available.

Integrating Flags into Your Deployment Workflow

Feature flags can play a vital role in your deployment and release strategy, allowing for canary releases, A/B testing, and more. django-flags supports various methods for defining and toggling flags, including through the Django admin interface, in your settings file, or even through environment variables and database records, providing the flexibility needed to integrate feature flags into your CI/CD pipeline.

For instance, to control a feature flag through an environment variable, you might define the flag like this:

import os

FLAGS = {
    'MY_ENV_FEATURE': [{'condition': 'boolean', 'value': os.environ.get('ENABLE_MY_ENV_FEATURE', 'False') == 'True'}],
}

This setup allows you to enable or disable the MY_ENV_FEATURE flag by setting the ENABLE_MY_ENV_FEATURE environment variable in your deployment environment, facilitating easy feature toggles without code changes.


Conclusion

Django-Flags is a tool for managing feature flags within Django applications, providing you with greater control over your application's features and release cycle.

Feature flags enable selective activation or deactivation of specific features without the need for application redeployment, which is particularly useful when conducting experiments, executing gradual feature rollouts, or temporarily disabling certain application components.

However, it is essential to recognize that feature flags can introduce additional complexity to your application. To maintain a clean and manageable codebase, it's crucial to use feature flags prudently and establish a strategy for handling and ultimately removing outdated flags.


Thank you for reading and I will see you on the Internet.

This post is public so feel free to share it.

If you like my free articles and would want to support my work, consider buying me a coffee:


Are you working on a project that’s encountering obstacles, or are you envisioning the next groundbreaking web application?

If Python, Django, and AI are the tools you're exploring but you need more in-depth knowledge, you're in the right place!

Get in touch for a 1-hour consultation where I can address your specific challenges.

Developer Service Blog - 1 Hour Consulting - Nuno Bispo
Are you working on a project that’s hitting roadblocks or simply dreaming up the next big web application?

Tagged in: