Skip to main content

A reusable application to create your own badge engine using Django

Project description

This Django application will help you to create your own badge system on your website.

It has been used on Ulule to create our own badge mechanism.

Build Status

Installation

$ pip install django-badgify

Usage

Add badgify to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = (
    # ...
    'badgify',
)

Synchronize the database:

$ python manage.py migrate badgify

Create a badgify_recipes.py file in your Django application:

$ cd path/to/your/django/app
$ touch badgify_recipes.py

Open this file and import badgify.recipe.BaseRecipe class and badgify module:

from badgify.recipe import BaseRecipe
import badgify

Create and register your recipe classes:

class PythonLoverRecipe(BaseRecipe):
    pass


class JSLoverRecipe(BaseRecipe):
    pass


# Per class
badgify.register(PythonLoverRecipe)
badgify.register(JSLoverRecipe)

# All at once in a list
badgify.register([PythonLoverRecipe, JSLoverRecipe])

A recipe class must implement:

  • name class attribute

    The badge name (humanized).

  • image property

    The badge image/logo as a file object.

A recipe class may implement:

  • slug class attribute

    The badge slug (used internally and in URLs). If not provided, it will be auto-generated based on the badge name.

  • description class attribute

    The badge description (short). It not provided, value will be blank.

  • user_ids property

    QuerySet returning User IDs likely to be awarded. You must return a QuerySet and not just a Python list or tuple. You can use values_list('id', flat=True).

  • db_read class attribute

    The database alias on which to perform read queries. Defaults to django.db.DEFAULT_DB_ALIAS.

  • batch_size class attribute

    How many Award objects to create at once. Defaults to BADGIFY_BATCH_SIZE (500).

Example:

from django.contrib.staticfiles.storage import staticfiles_storage

from badgify.recipe import BaseRecipe
import badgify

from .models import MyCustomUser


class PythonLoverRecipe(BaseRecipe):
    """
    People loving Python.
    """
    name = 'Python Lover'
    slug = 'python-lover'
    description = 'People loving Python programming language'

    @property
    def image(self):
        return staticfiles_storage.open('python-lover.png')

    @property
    def user_ids(self):
        return (MyCustomUser.objects.filter(love_python=True)
                                    .values_list('id', flat=True))


class JSLoverRecipe(BaseRecipe):
    """
    People loving JS.
    """
    name = 'JS Lover'
    slug = 'js-lover'
    description = 'People loving JS programming language'

    @property
    def image(self):
        return staticfiles_storage.open('js-lover.png')

    @property
    def user_ids(self):
        return (MyCustomUser.objects.filter(love_js=True)
                                    .values_list('id', flat=True))


class JavaLoverRecipe(BaseRecipe):
    """
    People loving Java.
    """
    name = 'Java Lover'
    slug = 'java-lover'
    description = 'People loving Java programming language'

    @property
    def image(self):
        return staticfiles_storage.open('java-lover.png')


badgify.register([
    PythonLoverRecipe,
    JSLoverRecipe,
    JavaLoverRecipe,
])

Once you have implemented and registered your recipe classes, you can invoke available commands bellow:

# Create badges from recipes
$ python manage.py badgify_sync badges

# Update badges from recipes
$ python manage.py badgify_sync badges --update

# Create awards
$ python manage.py badgify_sync awards

# Create awards bypassing signals (improve performances)
$ python manage.py badgify_sync awards --disable-signals

# Only create awards for "python" badge
$ python manage.py badgify_sync awards --badges python

# Only create awards for "python" and "go" badges
$ python manage.py badgify_sync awards --badges "python go"

# Create awards for all badges, except "php"
$ python manage.py badgify_sync awards --exclude-badges php

# Create awards for all badges, except "php" and "java"
$ python manage.py badgify_sync awards --exclude-badges "php java"

# Denormalize Badge.users.count() into Badge.users_count field
$ python manage.py badgify_sync counts

# Only denormalize counts for "python" badge
$ python manage.py badgify_sync counts --badges python

# Denormalize counts for all badges, except "php"
$ python manage.py badgify_sync counts --exclude-badges php

# Denormalize counts for all badges, except "php" and "java"
$ python manage.py badgify_sync counts --exclude-badges "php java"

# Typical workflow for best performances
$ python manage.py badgify_sync badges
$ python manage.py badgify_sync awards --disable-signals
$ python manage.py badgify_sync counts

# WARNING: if you delete awards to start again with a fresh table
# don't forget to update Badge.users_count field. Or use this command:
$ python manage.py badgify_reset

# Typical workflow for best performances if you want to recompute awards
$ python manage.py badgify_reset
$ python manage.py badgify_sync awards --disable-signals
$ python manage.py badgify_sync counts

Templatetags

badgify_badges

Takes two optional arguments:

  • user: a User object

  • username: a User username

Without any argument, displays all badges. Otherwise, badges awarded by the given user.

{% load badgify_tags %}

{% badgify_badges as badges %}
{% badgify_badges username="johndoe" as badges %}
{% badgify_badges user=user as badges %}

{% for badge in badges %}
    {{ badge.name }}
{% endfor %}

Views

django-badgify provides two views:

  • badgify.views.BadgifyListView: displays all badges as paginated list

  • badgify.views.BadgifyDetailView: displays awarded users as paginated list for a given badge

This application does not include templates. It lets you implement templates as you like (see example project).

To include these two views, include the provided badgify.urls:

# -*- coding: utf-8 -*-
from django.conf.urls import include, url

urlpatterns = [
    # Your other includes
    url(r'^badges/', include('badgify.urls')),
]

See example project for more details.

Custom Models

django-badgify lets you define your own model classes for Badge and Award models. That can be pretty useful for i18n stuff (example: django-transmetta support), adding custom fields, methods or properties.

Your models must inherit from badgify.models.base model classes:

# yourapp.models

from badgify.models import base


class Badge(base.Badge):
    # you own fields / logic here
    class Meta(base.Badge.Meta):
        abstract = False


class Award(base.Award):
    # you own fields / logic here
    class Meta(base.Award.Meta):
        abstract = False

Then tell the application to use them in place of default ones in your settings.py module:

# yourapp.settings

BADGIFY_BADGE_MODEL = 'yourapp.models.Badge'
BADGIFY_AWARD_MODEL = 'yourapp.models.Award'

Settings

You can altere the application behavior by defining settings in your settings.py module.

All application settings are prefixed with BADGIFY_.

BADGIFY_BADGE_IMAGE_UPLOAD_ROOT

The root path for Badge model ImageField.

BADGIFY_BADGE_IMAGE_UPLOAD_URL

The URL Badge model ImageField.

BADGIFY_BADGE_IMAGE_UPLOAD_STORAGE

Your own django.core.files.storage storage instance.

BADGIFY_BADGE_LIST_VIEW_PAGINATE_BY

Number of badges to display on the badge list page.

BADGIFY_BADGE_DETAIL_VIEW_PAGINATE_BY

Number of awarded users to display on the badge detail page.

BADGIFY_BADGE_MODEL

Your own concrete Badge model class as module path.

Example: yourapp.models.Badge.

BADGIFY_AWARD_MODEL

Your own concrete Award model class as module path.

Example: yourapp.models.Award.

BADGIFY_BATCH_SIZE

Maximum number of Award objects to create at once.

Defaults to 500.

Contribute

# Don't have pip?
$ sudo easy_install pip

# Don't already have virtualenv?
$ sudo pip install virtualenv

# Clone and install dependencies
$ git clone https://github.com/ulule/django-badgify.git
$ cd django-badgify
$ make install

# Launch tests
$ make test

# Launch example project
$ make create_fixtures
$ make serve

Compatibility

  • python 2.7: Django 1.9, 1.10

  • Python 3.4: Django 1.9, 1.10

  • Python 3.5: Django 1.9, 1.10

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-badgify-lab-0.2.0.tar.gz (25.6 kB view details)

Uploaded Source

Built Distribution

django_badgify_lab-0.2.0-py3-none-any.whl (38.4 kB view details)

Uploaded Python 3

File details

Details for the file django-badgify-lab-0.2.0.tar.gz.

File metadata

File hashes

Hashes for django-badgify-lab-0.2.0.tar.gz
Algorithm Hash digest
SHA256 fdbd75862dd85621928ee4a78accc2333213d613a0cf154a4e08f455f2378836
MD5 abb44d4f741856dce4e70afd4741a697
BLAKE2b-256 f9b4807955e321e5ac2ec7346caaaec98c2478f39b1248219c2a10441bd2d3f3

See more details on using hashes here.

File details

Details for the file django_badgify_lab-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_badgify_lab-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 830514cc96cb48bbabcd74e7553d270124ccbef89b0c0858a6b51ca5e3c2a110
MD5 92f52f7ce23d6ff42c7c3deaeeb456db
BLAKE2b-256 faa2da63bfb7e66eb9a90e4e9c71239d98ea82db3b893a364ca865b0d8f56560

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page