The purpose of this app is to allow adding dynamic conditions to relations between objects.
“Clausula” means “condition” in Latin.
Let’s say you develop an application that will present content to user based on various conditions. Gamification comes to mind. Let’s say you want to set the conditions on a per-user or per-group basis. For example girls get happy hours on Saturday and boys get them on Thursdays. Hardcoding that would be a bit tricky if you tend to change your mind frequently.
After installing the package and adding ‘clausula’ to INSTALLED_APPS you should define some abstract conditions you’d like to use.
Do this by creating a file conditions.py in your app. Then you need to import clauses registry, define your conditions and register them.
Each condition is simply a function that fullows these rules:
The object is guaranteed to have a param attribute which holds a string which can be used to compute returned boolean value. There can also be some relations available as Condition subclasses django.db.models.Model. Feel free to experiment and find some hackish uses for this package.
You run a virutal pub and want to have lower prices on one day.
1 2 3 4 5 6 7 8 9 10 | from clausula import clauses
def day_of_week_clause(obj, *args, **kwargs):
import datetime
weekday = datetime.date.today().weekday()
if weekday == int(obj.param):
return True
return False
clauses.register(day_of_week_clause, "checks day of week")
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from django.db import models
from clausula.models import Condition
class Beverage(models.Model):
name = models.CharField(max_length=30)
normal_price = models.DecimalField(max_digits=7, decimal_places=2)
def __unicode__(self):
return self.name
class Redeem(models.Model):
value = models.DecimalField(max_digits=7, decimal_places=2)
beverage = models.ForeignKey(Beverage)
condition = models.ForeignKey(Condition)
def __unicode__(self):
return "%s %s %s" % (self.value, self.beverage, self.condition)
|
1 2 3 4 5 6 7 8 9 10 11 12 | from django.contrib import admin
from .models import (Beverage, Redeem)
class RedeemInline(admin.TabularInline):
model = Redeem
class BeverageAdmin(admin.ModelAdmin):
inlines = [RedeemInline]
admin.site.register(Beverage, BeverageAdmin)
|
Then you should run ./manage.py syncdb && ./manage.py runserver, go to the admin page and add a Condition. You’ll see “checks day of week” in Clause list. Fill the name and give a day number.
You should also add a Beverage with redeem triggered by your On Sunday condition.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {% load clausula_tags %}
{% for brew in beverages %}
{{ brew.name }}:
{% if brew.redeem_set.all %}
{% for redeem in brew.redeem_set.all %}
{% check redeem.condition as result %}
{% if result %}
(condition met)
{% else %}
(condition not met)
{% endif %}
{% endfor %}
{% else %}
(no redeems)
{% endif %}
{% endfor %}
|
All that’s left is urls.py to tie it all together - let it be an exercise for you ;) Anyway you can always just fire ./manage.py runserver from the example_project directory and browse to http://127.0.0.1:8000/brew/ :)
Now play with param and check if it works properly. Add some more objects. Try writing another function and swap it with the one you used in example. Does it trigger properly? Experiment.
If you have any ideas how to extend functionality of this little package, fork it on github and make a pull request or simply file a feature request.
I’d like to follow Semantic Version guidelines.
Releases will be numbered with the following format:
<major>.<minor>.<patch>
And constructed with the following guidelines:
For more information on SemVer, please visit http://semver.org/.