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.
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
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_badgify-0.5.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d616358c255ece11d3bba9e7cc1a47a1d102dd361a626de8c7289aacfa5dc167 |
|
MD5 | c732f74e70828d7f14c8af1b1fb22719 |
|
BLAKE2b-256 | 9cc6dc6d31a12f166067ffe88eaf93100617aad8939f976472a7ba09dfd3c40b |