From 1e48c816667258249eb47252fa2e03246ee7caca Mon Sep 17 00:00:00 2001 From: Martin Hauser Date: Tue, 28 Jul 2026 15:17:11 +0200 Subject: [PATCH] docs(permissions): Add note about JSON escaping in constraint definitions Clarifies that backslashes in constraint values must be escaped in JSON. Includes example showing regex pattern escaping and adds table entry demonstrating regex constraint usage. Fixes #22498 --- docs/administration/permissions.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/administration/permissions.md b/docs/administration/permissions.md index 0b7b88bcd..53cd28621 100644 --- a/docs/administration/permissions.md +++ b/docs/administration/permissions.md @@ -31,6 +31,9 @@ Some models have registered actions that appear as checkboxes in the "Actions" s Constraints are expressed as a JSON object or list representing a [Django query filter](https://docs.djangoproject.com/en/stable/ref/models/querysets/#field-lookups). This is the same syntax that you would pass to the QuerySet `filter()` method when performing a query using the Django ORM. As with query filters, double underscores can be used to traverse related objects or invoke lookup expressions. Some example queries and their corresponding definitions are shown below. +!!! note + Constraint definitions must be valid JSON. Because a backslash (`\`) is an escape character in a JSON string, a backslash that is part of a string value must itself be escaped. For example, a regular expression containing `\.` must be entered as `\\.` in the constraint definition. + All attributes defined within a single JSON object are applied with a logical AND. For example, suppose you assign a permission for the site model with the following constraints. ```json @@ -83,6 +86,7 @@ While permissions are typically assigned to specific groups and/or users, it is | `{"status": "active", "role": "testing"}` | Status is active **AND** role is testing | | `{"name__startswith": "Foo"}` | Name starts with "Foo" (case-sensitive) | | `{"name__iendswith": "bar"}` | Name ends with "bar" (case-insensitive) | +| `{"name__regex": "^foo\\.bar$"}` | Name matches the regular expression `^foo\.bar$` | | `{"vid__gte": 100, "vid__lt": 200}` | VLAN ID is greater than or equal to 100 **AND** less than 200 | | `[{"vid__lt": 200}, {"status": "reserved"}]` | VLAN ID is less than 200 **OR** status is reserved |