0
# User Management and Permissions
1
2
Django CMS provides a comprehensive permission system with granular control over pages, placeholders, and plugins, along with user management utilities that integrate seamlessly with Django's authentication system.
3
4
## Capabilities
5
6
### User Management
7
8
Create and manage CMS-specific users with appropriate permissions and group assignments.
9
10
```python { .api }
11
def create_page_user(
12
created_by,
13
user,
14
can_add_page=True,
15
can_view_page=True,
16
can_change_page=True,
17
can_delete_page=True,
18
can_publish_page=True,
19
can_add_pageuser=True,
20
can_change_pageuser=True,
21
can_delete_pageuser=True,
22
can_add_pagepermission=True,
23
can_change_pagepermission=True,
24
can_delete_pagepermission=True,
25
grant_all=False
26
):
27
"""
28
Create a page user for the provided user with specified permissions.
29
30
Args:
31
created_by (User): The user creating this page user
32
user (User): The user to create the page user from
33
can_add_page (bool): Permission to add pages
34
can_view_page (bool): Permission to view pages
35
can_change_page (bool): Permission to change pages
36
can_delete_page (bool): Permission to delete pages
37
can_publish_page (bool): Permission to publish pages
38
can_add_pageuser (bool): Permission to add page users
39
can_change_pageuser (bool): Permission to change page users
40
can_delete_pageuser (bool): Permission to delete page users
41
can_add_pagepermission (bool): Permission to add page permissions
42
can_change_pagepermission (bool): Permission to change page permissions
43
can_delete_pagepermission (bool): Permission to delete page permissions
44
grant_all (bool): Grant all permissions
45
46
Returns:
47
PageUser: Created page user instance
48
"""
49
50
def assign_user_to_page(
51
page,
52
user,
53
grant_on=ACCESS_PAGE_AND_DESCENDANTS,
54
can_add=False,
55
can_change=False,
56
can_delete=False,
57
can_change_advanced_settings=False,
58
can_publish=None,
59
can_change_permissions=False,
60
can_move_page=False,
61
can_recover_page=True,
62
can_view=False,
63
grant_all=False,
64
global_permission=False
65
):
66
"""
67
Assign user permissions to a specific page.
68
69
Args:
70
page (Page): Target page
71
user (User): User to grant permissions
72
grant_on (int): Permission scope (ACCESS_PAGE_AND_DESCENDANTS, etc.)
73
can_add (bool): Permission to add child pages
74
can_change (bool): Permission to edit page
75
can_delete (bool): Permission to delete page
76
can_change_advanced_settings (bool): Permission to change advanced settings
77
can_publish (bool, optional): Permission to publish page
78
can_change_permissions (bool): Permission to change page permissions
79
can_move_page (bool): Permission to move page
80
can_recover_page (bool): Permission to recover deleted page
81
can_view (bool): Permission to view page
82
grant_all (bool): Grant all permissions
83
global_permission (bool): Apply as global permission
84
85
Returns:
86
PagePermission: Created permission instance
87
"""
88
```
89
90
### Permission Checking
91
92
Comprehensive functions to check user permissions for various CMS operations.
93
94
```python { .api }
95
def can_change_page(request):
96
"""
97
Check if current user can change pages.
98
99
Args:
100
request (HttpRequest): Current request
101
102
Returns:
103
bool: Permission status
104
"""
105
106
def user_can_add_page(user, site=None):
107
"""
108
Check if user can add pages.
109
110
Args:
111
user (User): User to check
112
site (Site, optional): Target site
113
114
Returns:
115
bool: Permission granted
116
"""
117
118
def user_can_add_subpage(user, target, site=None):
119
"""
120
Check if user can add subpages to target.
121
122
Args:
123
user (User): User to check
124
target (Page): Parent page
125
site (Site, optional): Target site
126
127
Returns:
128
bool: Permission granted
129
"""
130
131
def user_can_change_page(user, page, site=None):
132
"""
133
Check if user can edit specific page.
134
135
Args:
136
user (User): User to check
137
page (Page): Target page
138
site (Site, optional): Target site
139
140
Returns:
141
bool: Permission granted
142
"""
143
144
def user_can_delete_page(user, page, site=None):
145
"""
146
Check if user can delete specific page.
147
148
Args:
149
user (User): User to check
150
page (Page): Target page
151
site (Site, optional): Target site
152
153
Returns:
154
bool: Permission granted
155
"""
156
157
def user_can_publish_page(user, page, site=None):
158
"""
159
Check if user can publish specific page.
160
161
Args:
162
user (User): User to check
163
page (Page): Target page
164
site (Site, optional): Target site
165
166
Returns:
167
bool: Permission granted
168
"""
169
170
def user_can_view_page(user, page, site=None):
171
"""
172
Check if user can view specific page.
173
174
Args:
175
user (User): User to check
176
page (Page): Target page
177
site (Site, optional): Target site
178
179
Returns:
180
bool: Permission granted
181
"""
182
```
183
184
### Thread-Local User Management
185
186
Utilities for managing current user context in thread-local storage for permission checking.
187
188
```python { .api }
189
def get_current_user():
190
"""
191
Get current user from thread-local storage.
192
193
Returns:
194
User: Current user or None
195
"""
196
197
def set_current_user(user):
198
"""
199
Set current user in thread-local storage.
200
201
Args:
202
user (User): User to set as current
203
"""
204
205
def current_user(user):
206
"""
207
Context manager for temporary user switching.
208
209
Args:
210
user (User): User to temporarily set
211
212
Returns:
213
ContextManager: Context manager for user scope
214
"""
215
```
216
217
### Plugin and Advanced Permissions
218
219
Permission checking for plugin operations and advanced CMS functionality.
220
221
```python { .api }
222
def has_plugin_permission(user, plugin_type, permission_type):
223
"""
224
Check if user has plugin-specific permissions.
225
226
Args:
227
user (User): User to check
228
plugin_type (str): Plugin type identifier
229
permission_type (str): Permission type ("add", "change", "delete")
230
231
Returns:
232
bool: Permission granted
233
"""
234
235
def get_user_permission_level(user, site=None):
236
"""
237
Get user's permission hierarchy level.
238
239
Args:
240
user (User): User to check
241
site (Site, optional): Target site
242
243
Returns:
244
int: Permission level (0=no access, 1=limited, 2=full)
245
"""
246
247
def get_subordinate_users(user, site=None):
248
"""
249
Get users under current user's management.
250
251
Args:
252
user (User): Managing user
253
site (Site, optional): Target site
254
255
Returns:
256
QuerySet: Subordinate users
257
"""
258
259
def get_subordinate_groups(user, site=None):
260
"""
261
Get groups under current user's management.
262
263
Args:
264
user (User): Managing user
265
site (Site, optional): Target site
266
267
Returns:
268
QuerySet: Subordinate groups
269
"""
270
```
271
272
## Usage Examples
273
274
### Creating Users and Assigning Permissions
275
276
```python
277
from cms.api import create_page_user, assign_user_to_page, create_page
278
from cms.models import ACCESS_PAGE_AND_DESCENDANTS
279
280
# First create regular Django users
281
from django.contrib.auth import get_user_model
282
User = get_user_model()
283
284
editor_user = User.objects.create_user(
285
username="editor",
286
email="editor@example.com",
287
password="secure_password"
288
)
289
290
manager_user = User.objects.create_user(
291
username="manager",
292
email="manager@example.com",
293
password="secure_password"
294
)
295
296
# Create page users from Django users
297
admin_user = User.objects.filter(is_superuser=True).first()
298
299
editor = create_page_user(
300
created_by=admin_user,
301
user=editor_user,
302
can_add_page=True,
303
can_change_page=True,
304
can_view_page=True
305
)
306
307
manager = create_page_user(
308
created_by=admin_user,
309
user=manager_user,
310
grant_all=True
311
)
312
313
# Create a page hierarchy
314
home_page = create_page(
315
title="Home",
316
template="homepage.html",
317
language="en"
318
)
319
320
blog_section = create_page(
321
title="Blog",
322
template="page.html",
323
language="en",
324
parent=home_page
325
)
326
327
# Grant editor limited permissions on blog section
328
assign_user_to_page(
329
page=blog_section,
330
user=editor,
331
grant_on=ACCESS_PAGE_AND_DESCENDANTS,
332
can_add=True,
333
can_change=True,
334
can_view=True
335
)
336
337
# Grant manager full permissions on entire site
338
assign_user_to_page(
339
page=home_page,
340
user=manager,
341
grant_all=True,
342
grant_on=ACCESS_PAGE_AND_DESCENDANTS
343
)
344
```
345
346
### Permission Checking in Views
347
348
```python
349
from django.shortcuts import get_object_or_404, redirect
350
from django.contrib.auth.decorators import login_required
351
from cms.models import Page
352
from cms.utils.permissions import (
353
user_can_change_page,
354
user_can_publish_page,
355
user_can_add_subpage
356
)
357
358
@login_required
359
def edit_page_view(request, page_id):
360
page = get_object_or_404(Page, id=page_id)
361
362
# Check if user can edit this page
363
if not user_can_change_page(request.user, page):
364
return redirect('permission_denied')
365
366
# Process page editing
367
return render(request, 'edit_page.html', {'page': page})
368
369
@login_required
370
def publish_page_view(request, page_id):
371
page = get_object_or_404(Page, id=page_id)
372
373
# Check publishing permissions
374
if not user_can_publish_page(request.user, page):
375
return redirect('permission_denied')
376
377
# Note: Publishing has been removed from Django CMS core v4+
378
# Use djangocms-versioning or similar packages for publishing
379
380
return redirect('page_list')
381
382
def add_subpage_view(request, parent_id):
383
parent_page = get_object_or_404(Page, id=parent_id)
384
385
# Check if user can add subpages
386
if not user_can_add_subpage(request.user, parent_page):
387
return redirect('permission_denied')
388
389
# Show add page form
390
return render(request, 'add_page.html', {'parent': parent_page})
391
```
392
393
### Thread-Local User Context
394
395
```python
396
from cms.utils.permissions import current_user, get_current_user, set_current_user
397
from django.contrib.auth import get_user_model
398
399
User = get_user_model()
400
401
# Set current user for permission context
402
admin_user = User.objects.get(username='admin')
403
set_current_user(admin_user)
404
405
# Get current user
406
current = get_current_user()
407
print(f"Current user: {current.username}")
408
409
# Temporarily switch user context
410
editor_user = User.objects.get(username='editor')
411
412
with current_user(editor_user):
413
# Operations here run with editor permissions
414
current = get_current_user()
415
print(f"Temporary user: {current.username}")
416
417
# Check permissions as editor
418
can_edit = user_can_change_page(current, some_page)
419
420
# Back to original user context
421
current = get_current_user()
422
print(f"Back to: {current.username}")
423
```
424
425
### Plugin Permission Checking
426
427
```python
428
from cms.utils.permissions import has_plugin_permission
429
430
# Check if user can add specific plugin types
431
can_add_text = has_plugin_permission(request.user, "TextPlugin", "add")
432
can_add_image = has_plugin_permission(request.user, "PicturePlugin", "add")
433
can_change_video = has_plugin_permission(request.user, "VideoPlugin", "change")
434
435
# Filter available plugins based on permissions
436
available_plugins = []
437
for plugin_type in ["TextPlugin", "PicturePlugin", "VideoPlugin"]:
438
if has_plugin_permission(request.user, plugin_type, "add"):
439
available_plugins.append(plugin_type)
440
```
441
442
### Permission Management in Templates
443
444
```html
445
{% load cms_tags %}
446
447
<!-- Check permissions in templates -->
448
{% if request.user.is_staff %}
449
<div class="admin-toolbar">
450
{% cms_toolbar %}
451
452
<!-- Show edit links only if user can change page -->
453
{% if page|can_change_page:request.user %}
454
<a href="{% cms_admin_url 'admin:cms_page_change' page.id %}">
455
Edit Page
456
</a>
457
{% endif %}
458
459
<!-- Show publish link only if user can publish -->
460
{% if page|can_publish_page:request.user %}
461
<a href="{% url 'publish_page' page.id %}">
462
Publish Page
463
</a>
464
{% endif %}
465
</div>
466
{% endif %}
467
468
<!-- Render model editing only if user has permissions -->
469
{% if request.user.is_staff %}
470
{% render_model article "title" %}
471
{% else %}
472
<h1>{{ article.title }}</h1>
473
{% endif %}
474
```
475
476
## Types
477
478
```python { .api }
479
class PageUser:
480
"""
481
CMS-specific user model extending Django's User.
482
483
Attributes:
484
language: User interface language preference
485
created_by: User who created this account
486
can_add_page: Global page addition permission
487
can_change_page: Global page change permission
488
can_delete_page: Global page deletion permission
489
"""
490
491
class PagePermission:
492
"""
493
Page-specific user permissions.
494
495
Attributes:
496
user: Associated user
497
group: Associated group (alternative to user)
498
page: Target page
499
grant_on: Permission scope (page only vs descendants)
500
can_add: Can add child pages
501
can_change: Can edit page content
502
can_delete: Can delete page
503
can_publish: Can publish page changes
504
can_move: Can move page in tree
505
can_view: Can view page (for restricted content)
506
"""
507
508
class GlobalPagePermission:
509
"""
510
Site-wide user permissions.
511
512
Attributes:
513
user: Associated user
514
group: Associated group
515
can_add: Global page addition permission
516
can_change: Global page change permission
517
can_delete: Global page deletion permission
518
can_publish: Global page publishing permission
519
can_move: Global page moving permission
520
can_view: Global page viewing permission
521
sites: Sites where permissions apply
522
"""
523
524
class PageUserGroup:
525
"""
526
CMS-specific user groups.
527
528
Attributes:
529
name: Group name
530
created_by: User who created group
531
users: Group members
532
"""
533
534
# Permission constants
535
ACCESS_PAGE_AND_DESCENDANTS: int # Apply permissions to page and all descendants
536
ACCESS_PAGE: int # Apply permissions to page only
537
ACCESS_DESCENDANTS: int # Apply permissions to descendants only
538
```