欢迎访问宙启技术站
智能推送

django.contrib.admin.models的数据权限控制方法

发布时间:2024-01-19 03:17:53

Django提供了一种简单而强大的数据权限控制方法,可以通过使用django.contrib.admin.models模块中的ModelAdmin类和User类来实现。

ModelAdmin类是Django自带的管理员模块中的一个重要类,它用于管理模型的展示、编辑和删除等操作。我们可以通过继承ModelAdmin类,并设置一些属性和方法来实现数据权限控制。

下面是一个使用例子,详细说明了如何使用ModelAdmin类和User类来实现数据权限控制。

# models.py

from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)

首先,我们创建了一个简单的模型Post,其中author字段是一个外键,关联到User模型。

# admin.py

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.admin.models import LogEntry

from .models import Post

class PostAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        # 获取当前登录用户
        user = request.user

        # 如果当前用户是超级管理员,返回全部数据
        if user.is_superuser:
            return super().get_queryset(request)
        
        # 否则,只返回当前用户的数据
        return super().get_queryset(request).filter(author=user)
    
    def save_model(self, request, obj, form, change):
        # 保存模型时添加作者信息
        if not obj.author:
            obj.author = request.user
        obj.save()

admin.site.unregister(User)
admin.site.unregister(LogEntry)
admin.site.register(User, UserAdmin)
admin.site.register(Post, PostAdmin)

然后,在admin.py文件中,我们创建了一个PostAdmin类,继承自ModelAdmin类。在该类中,我们定义了两个方法:get_querysetsave_model

- get_queryset方法用于返回查询集,在该方法中,我们首先获取当前登录的用户。如果用户是超级管理员,我们调用父类的get_queryset方法返回全部数据;否则,我们调用父类的get_queryset方法返回当前用户的数据。

- save_model方法用于保存模型时对数据进行处理,在该方法中,我们首先判断模型的author字段是否为空,如果为空,则将当前用户设置为作者,并保存模型。

最后,我们通过调用admin.site.register方法注册Post模型和PostAdmin类,将其展示在Django的管理后台中。同时,我们还调用admin.site.unregister方法取消注册系统自带的UserLogEntry模型,以使用我们自定义的UserAdmin类和PostAdmin类。

使用以上的权限控制方法后,用户在登录后访问Django的管理后台时,只能看到自己创建的Post模型数据,并且在创建新的Post时,默认将登录的用户设置为作者。这样就实现了简单的数据权限控制。

需要注意的是,在上述的代码中,我们是通过在get_queryset方法中过滤数据来实现数据权限控制的。但是这种方法只是简单地过滤了查询结果,并没有对用户的操作进行权限验证。如果需要更为复杂的数据权限控制,可以使用Django的@permission_required装饰器或自定义Permission类来实现。