django-rules icon indicating copy to clipboard operation
django-rules copied to clipboard

Add `verbose_name` for rules and permissions

Open jacklinke opened this issue 4 years ago • 2 comments

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 optional verbose_name.
  • set_rule(name, predicate, verbose_name=None): Updated to allow optional verbose_name
  • rule_verbose_name(name): A new method which returns the verbose_name if it was supplied when adding or setting the rule. Defaults to name if no verbose_name was 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.

jacklinke avatar Nov 28 '21 21:11 jacklinke

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!

dfunckt avatar Nov 29 '21 16:11 dfunckt

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.

jacklinke avatar Nov 30 '21 02:11 jacklinke