下面是使用django-guardian实现django-admin的行级权限控制的方法的完整攻略.
django-guardian是一个用于Django的第三方插件,它提供一种简单的方式来将对象级别的访问控制系统嵌入到你的应用程序中.
您可以使用pip安装django-guardian:
pip install django-guardian
然后将guardian添加到INSTALLED_APPS中:
INSTALLED_APPS = [
# ...
'guardian',
# ...
]
并且在MIDDLEWARE中添加GuardianMiddleware:
MIDDLEWARE = [
# ...
'django.contrib.auth.middleware.AuthenticationMiddleware',
'guardian.middleware.GuardianMiddleware',
# ...
]
最后,在settings.py文件中添加以下设置:
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'guardian.backends.ObjectPermissionBackend',
]
创建一个模型后台(ModelAdmin)是创建一个新的admin后台的第一步,这为您提供了一个管理特定模型的界面. 您可以针对不同的模型创建几个后台界面.
需要创建一个自定义的admin后台,即一个子类GuardedModelAdmin(位于guardian.admin中),并将其传递给模型注册装饰器:
现在,我们将为创建的文章添加用户级别的权限控制:
①首先,在models.py中,定义一个组:
from django.contrib.auth.models import Group
class Writer(Group):
class Meta:
verbose_name = "Writer"
verbose_name_plural = "Writers"
from django.db import models
from django.conf import settings
from django.urls import reverse
from guardian.shortcuts import assign_perm
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
class Writer(Group):
class Meta:
verbose_name = "Writer"
verbose_name_plural = "Writers"
# 在Post模型类中添加如下代码
class Meta:
permissions = (("can_view_post", "Can view post"),)
assign_perm("can_view_post", Writer.objects.get_or_create(name="nobody")[0])
# 在admin.py中的PostModelAdmin类中添加如下代码
from django.contrib.auth.models import Group
from django.forms import CheckboxSelectMultiple
from guardian.admin import GuardedModelAdmin
class GroupAdminForm(forms.ModelForm):
class Meta:
model = Group
fields = '__all__'
widgets = {
'permissions': CheckboxSelectMultiple,
}
permissions = forms.MultipleChoiceField(
choices=[],
widget=CheckboxSelectMultiple,
help_text=_('Permissions of the group')
)
def __init__(self, *args, **kwargs):
super(GroupAdminForm, self).__init__(*args, **kwargs)
choices = [(x.id, x.name) for x in Permission.objects.all().order_by('content_type__app_label', 'content_type__model', 'codename')]
self.fields['permissions'].choices = choices
def save(self, commit=True):
group = super(GroupAdminForm, self).save(commit)
if commit:
perms = self.cleaned_data.get('permissions', [])
permissions = Permission.objects.filter(pk__in=perms)
group.permissions.set(permissions)
return group
@admin.register(Writer)
class WriterAdmin(GuardedModelAdmin):
form = GroupAdminForm
# 在admin.py中的GroupAdminForm类中添加如下代码
from django.contrib.auth.models import Permission
class PermissionFilter(SimpleListFilter):
title = _('permissions')
parameter_name = 'permissions'
def lookups(self, request, model_admin):
perms = Permission.objects.all().order_by('content_type__app_label', 'content_type__model', 'codename')
choices = []
for perm in perms:
content_type = perm.content_type
choice = (f'{content_type.app_label}.{content_type.model}.{perm.codename}', perm.name)
if choice not in choices:
choices.append(choice)
return choices
def queryset(self, request, queryset):
if self.value():
content_type, codename = self.value().rsplit('.', 1)
queryset = queryset.filter(
permissions__content_type__app_label=content_type,
permissions__content_type__model=content_type,
permissions__codename=codename
)
return queryset
Hello
World
Today
首先,我们需要在models.py中为标题创建一个单独的模型,并将其与文章关联:
from django.db import models
from django.conf import settings
from django.urls import reverse
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post_detail', args=[str(self.id)])
class PostTitle(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='titles')
title = models.CharField(max_length=255)
def __str__(self):
return self.title
class Meta:
verbose_name = "Post Title"
verbose_name_plural = "Post Titles"
[, , ]
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm
post = Post()
post.save()
titles = ['Hello', 'World', 'Today']
for title in titles:
PostTitle.objects.create(post=post, title=title)
alice = User.objects.create(username='alice')
bob = User.objects.create(username='bob')
assign_perm('view_posttitle', alice, post.titles.all()[0])
for title in post.titles.all():
assign_perm('view_posttitle', bob, title)
这将导致以下授权:
Bob可以查看所有标题,而Alice不能.
现在,我们将修改PostTitleModelAdmin以隐藏每个区域的权限和添加我们的自定义列表视图:
创建我们的自定义模板(view_title.html)以允许我们仅显示每个标题的一部分:
{% extends "admin/base_site.html" %}
{% block content_title %}
{{ object.title|safe }}
{% endblock %}
{% block content %}
{% for title in object.post.titles.all %}
{% if title|has_perm:'view_posttitle' %}
{{ title.title|safe }}
{% endif %}
{% endfor %}
{% endblock %}
现在,当我们单击每个标题时,我们将只能看到我们已授权的部分.
详细的攻略就是这样了,希望能对你有所帮助.
以上就是土嘎嘎小编为大家整理的使用django-guardian实现django-admin的行级权限控制的方法相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!