Skip to content



Repository files navigation

Pinax Announcements

CircleCi Codecov

Table of Contents

About Pinax

Pinax is an open-source platform built on the Django Web Framework. It is an ecosystem of reusable Django apps, themes, and starter project templates. This collection can be found at

Important Links

Where you can find what you need:



pinax-announcements is a well tested, documented, and proven solution for any site wanting announcements for its users.


Announcements have title and content, with options for filtering their display:

  • site_wide - True or False
  • members_only - True or False
  • publish_start - date/time or none
  • publish_end - date/time or none

pinax-announcements has three options for dismissing an announcement:

  • DISMISSAL_NO - always visible
  • DISMISSAL_SESSION - dismiss for the session
  • DISMISSAL_PERMANENT - dismiss forever

Supported Django and Python Versions

Django / Python 3.6 3.7 3.8
2.2 * * *
3.0 * * *
4.0 * * *



To install pinax-announcements:

    $ pip install pinax-announcements

Add pinax.announcements to your INSTALLED_APPS setting:

        # other apps

Optionally, if you want someone other than staff to manage announcements, enable this authentication backend:

        # other backends

then enable permission "announcements.can_manage" for these managers.

Add pinax.announcements.urls to your project urlpatterns:

    urlpatterns = [
        # other urls
        url(r"^announcements/", include("pinax.announcements.urls", namespace="pinax_announcements")),


Displaying Announcements

First load the template tags:

    {% load pinax_announcements_tags %}

Then fetch announcements with the announcements template tag:


    {% announcements as announcement_list %}

    {% if announcement_list %}
        <div class="announcements">
            {% for announcement in announcement_list %}
                <div class="announcement">
                    <strong>{{ announcement.title }}</strong><br />
                    {{ announcement.content }}
            {% endfor %}
    {% endif %}

If your announcement content is too large for viewing inline then show a link to a detail view:

    <a href="{{ announcement.get_absolute_url }}">Read more...</a>

See Template Tags for detail on pinax-announcements template tags.

Dismissing Announcements

Add this markup to show a "Dismiss" link if available:

    {% if announcement.dismiss_url %}
        <form class="form ajax" data-replace-closest=".announcement" action="{{ announcement.dismiss_url }}" method="post">
            {% csrf_token %}
            <button class="btn btn-default">Clear</button>
    {% endif %}
Dismissal with Eldarion AJAX

The anchor markup shown above and the announcement dismissal view both conform to an AJAX response that eldarion-ajax understands. Furthermore, the templates that ship with this project will work seemlessly with eldarion-ajax. Include the eldarion-ajax.min.js Javascript package in your base template:

    {% load staticfiles %}
    <script src="{% static "js/eldarion-ajax.min.js" %}"></script>

and include eldarion-ajax in your site JavaScript:


This of course is optional. You can roll your own JavaScript handling as the view also returns data in addition to rendered HTML. Furthermore, if you don't want ajax at all the view will handle a regular POST and perform a redirect.



This signal is sent immediately after an announcement is created. It provides a single kwarg of announcement, the created Announcement instance. Sender is the newly created Announcement instance.


This signal is sent immediately after an announcement is updated. It provides a single kwarg of announcement, the updated Announcement instance. Sender is the newly updated Announcement instance.


This signal is sent immediately after an announcement is deleted. It provides a single kwarg of announcement, the deleted Announcement instance. Sender is None.

Template Tags


Filters announcements by publish_start and publish_end date range, including all with no publish_end value. Returns announcements matching site_wide == True and members_only == False, and which are not dismissed.

    {% announcements as announcement_list %}
    {% for announcement in announcement_list %}
            {{ announcement.title }}<br />
            {{ announcement.content }}
    {% endfor %}


Default templates are provided by the pinax-templates app in the announcements section of that project.

Reference pinax-templates installation instructions to include these templates in your project.

View live pinax-templates examples and source at Pinax Templates!

Customizing Templates

Override the default pinax-templates templates by copying them into your project subdirectory pinax/announcements/ on the template path and modifying as needed.

For example if your project doesn't use Bootstrap, copy the desired templates then remove Bootstrap and Font Awesome class names from your copies. Remove class references like class="btn btn-success" and class="icon icon-pencil" as well as bootstrap from the {% load i18n bootstrap %} statement. Since bootstrap template tags and filters are no longer loaded, you'll also need to update {{ form|bootstrap }} to {{ form }} since the "bootstrap" filter is no longer available.






Change Log


  • Support Django 4.0
  • Avoid extra queries when fetching dismissals #63


  • Drop Django 1.11, 2.0, and 2.1, and Python 2,7, 3.4, and 3.5 support
  • Add Django 2.2 and 3.0, and Python 3.6, 3.7, and 3.8 support
  • Update packaging configs
  • Direct users to community resources


  • Update pinax-templates version requirement


  • Replace pinax-theme-bootstrap test dependency with pinax-templates


  • Bump major version after completing Django 2.0 upgrade, removing <=1.10 support


  • Remove doc build


  • Standardize documentation layout
  • Drop Django v1.8, v1.10 support


  • Add Django 2.0 compatibility testing
  • Drop Django 1.9 and Python 3.3 support
  • Move documentation into README
  • Convert CI and coverage to CircleCi and CodeCov
  • Add PyPi-compatible long description


  • Fixed dismiss documentation


  • Convert to Django class-based generic views
  • Add URL namespace "pinax_announcements"
  • Add tests, including signal handler checking
  • Drop support for Django < 1.8
  • Improve documentation


  • Rename to pinax.announcements
  • Drop support for django < 1.5
  • Rewrite docs for readthedocs with markdown (template based on pinax-blog)
  • Update test config (travis, tox, coveragerc, ...)
  • Update .gitignore
  • Generate django migrations
  • Move templates to pinax/announcements/


  • fixed included templates to be compatible with Django 1.5


  • removed atom feed
  • renamed dismiss url
  • switched to
  • marked some choice field strings for translation
  • swapped view mixin override in favor of auth backend and permission checking


  • added ability to publish for periods of time
  • added model to store permanent clearings (see migration below)
  • added ability to control how announcements are cleared (no clearing, session based, or permanent) (see migration below)
  • changed view announcement_hide to dismiss
  • changed url name of announcement_hide to announcement_dismiss
  • changed template tag from fetch_announcements to announcements
  • removed send now functionality
  • removed notifications
  • removed context processor
  • removed list view
  • removed AnnouncementsManager
  • removed current_announcements_for_request


Migration scripts to move prior installations to latest version::

ALTER TABLE "announcements_announcement" ADD COLUMN "dismissal_type" int DEFAULT 2 NOT NULL;
ALTER TABLE "announcements_announcement" ADD COLUMN "publish_start" timestamp with time zone NOT NULL;
ALTER TABLE "announcements_announcement" ADD COLUMN "publish_end" timestamp with time zone;
### New Model: announcements.Dismissal
CREATE TABLE "announcements_dismissal" (
    "id" serial NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED,
    "announcement_id" integer NOT NULL REFERENCES "announcements_announcement" ("id") DEFERRABLE INITIALLY DEFERRED,
    "dismissed_at" timestamp with time zone NOT NULL
CREATE INDEX "announcements_dismissal_user_id" ON "announcements_dismissal" ("user_id");
CREATE INDEX "announcements_dismissal_announcement_id" ON "announcements_dismissal" ("announcement_id");


  • initial release


Contributing information can be found in the Pinax community health file repo.

Code of Conduct

In order to foster a kind, inclusive, and harassment-free community, the Pinax Project has a Code of Conduct. We ask you to treat everyone as a smart human programmer that shares an interest in Python, Django, and Pinax with you.

Connect with Pinax

For updates and news regarding the Pinax Project, please follow us on Twitter @pinaxproject and check out our Pinax Project blog.


Copyright (c) 2012-present James Tauber and contributors under the MIT license.


a site-wide announcement reusable app for Django



Code of conduct







  • Python 99.6%
  • Makefile 0.4%