Add `verbose_name` for rules and permissions
Adds verbose_name for rules and permissions, resolving #59.
This change should be transparent to any existing users of django-rules, but adds the new capability to add and display verbose names for rules & permissions through the use of new/updated RuleSet instance methods and shortcuts for shared and permissions rule sets.
add_rule(name, predicate, verbose_name=None): Updated to allow optionalverbose_name.set_rule(name, predicate, verbose_name=None): Updated to allow optionalverbose_namerule_verbose_name(name): A new method which returns theverbose_nameif it was supplied when adding or setting the rule. Defaults tonameif noverbose_namewas supplied.- (similar method names for
permissions)
Models can now also optionally add verbose names to permissions using the following conventions:
import rules
from rules.contrib.models import RulesModel
class Book(RulesModel):
class Meta:
rules_permissions = {
"add": rules.is_staff,
"read": {"pred": rules.is_authenticated, "verbose_name": "Can read this book"},
"delete": {"pred": rules.is_staff},
}
This would be equivalent to the following calls::
rules.add_perm("app_label.add_book", rules.is_staff)
rules.add_perm("app_label.read_book", rules.is_authenticated, verbose_name= "Can read this book")
rules.add_perm("app_label.delete_book", rules.is_staff)
Tasks:
- [x] Update code
- [x] Add and run tests
- [x] Update Readme
I welcome any feedback.
Great stuff! 👍
My only concern is we're changing the structure of the items stored in rule sets -- RuleSets used to be a map of strings to predicates, whereas now it is going to be a map of strings to dicts. This is technically a breaking change and can catch users by surprise.
Maybe override __getitem__ et al to return the predicate like it did before? The important use cases are using the rule set as a dict (ie. get, set, delete items) and iteration which should continue to behave as before. Tests that ensure that would be much appreciated.
Otherwise this looks like a great addition, thank you for that!
Glad this is seen as something beneficial, and thanks for the advice/direction.
I updated the code, returning the predicate if the dict is accessed directly (e.g.: rule_set_instance["permission_name"]), but added the option to prefix/suffix the permission name with 'get_' and '_display' respectively to return the verbose_name (e.g.: rule_set_instance["get_permission_name_display"])
I figured following a similar approach as Django's get_FOO_display() method for getting the display names of choice fields made sense here.
If that sounds sensible, I'll add tests and docs this week to finish this out.