天天看点

Django2集成xadmin详解-6-根据登录用户过滤数据

一 问题场景

上一篇博文在IDC Model里增加了user字段,并在此字段存储了创建该数据的登录用户信息。

class IDC(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, editable=False, null=True)#创建该数据的登录用户
    name = models.CharField(max_length=)
    contact = models.CharField(max_length=)
    phone = models.CharField(max_length=)
    address = models.CharField(max_length=)
    create_time = models.DateField(auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "IDC机房"
        verbose_name_plural = verbose_name
           

问题:如果仅允许登录用户查看其自己创建的IDC数据,该怎么处理?

二 解决方法

打开IdcManager目录的adminx.py,在IDCAdmin类里增加queryset方法,代码如下:

def queryset(self):
        qs = super(IDCAdmin, self).queryset()
        if self.request.user.is_superuser: #超级用户可查看所有数据
            return qs
        else:
            return qs.filter(user=self.request.user) #user是IDC Model的user字段
           

增加上述方法后,还需要改变IDCAdmin的注册方式,之前使用的是注解注册方式:

@xadmin.sites.register(IDC)
class IDCAdmin(object):
           

这种注册方式,不支持queryset方法,在xadmin系统里,点击“IDC机房”菜单,会报以下错误:

TypeError at /IdcManager/idc/

super() argument 1 must be type, not None

将注解代码@xadmin.sites.register(IDC)删除,在adminx.py末尾增加以下代码:

xadmin.sites.site.register(IDC, IDCAdmin)
           

adminx.py文件完整代码如下:

import xadmin

from .models import IDC


class IDCAdmin(object):
    list_display = ("user", "name", "contact", "phone", "address", "create_time")
    list_display_links = ("name",)

    def save_models(self):
        self.new_obj.user = self.request.user
        super().save_models()

    def queryset(self):
        qs = super(IDCAdmin, self).queryset()
        if self.request.user.is_superuser:
            return qs
        else:
            return qs.filter(user=self.request.user)


xadmin.sites.site.register(IDC, IDCAdmin)
           

完成代码后,启动系统,执行下述操作验证效果:

  1. 用超级用户登录系统;
  2. 打开“IDC机房”菜单,增加几条数据;
  3. 打开“用户”菜单,增加一个新用户;
  4. 点击新用户的用户名,进入编辑界面,勾选“职员状态”,并添加 “IDC机房”的增删改查权限;
  5. 退出超级用户,使用新用户登录;
  6. 新用户看到的效果:“IDC机房”菜单下无数据,增加数据后可看到自己增加的数据。

三 总结

本文的处理方法,同样是查看xadmin的源代码摸索而来。

首先,找到处理数据展示的代码文件,即

venv\Lib\site-packages\xadmin\views\list.py

在此文件里找到获取结果数据的方法或函数:

@filter_hook
def get_list_queryset(self):
    """
    Get model queryset. The query has been filted and ordered.
    """
    # First, get queryset from base class.
    queryset = self.queryset()


def make_result_list(self):
    # Get search parameters from the query string.
    self.base_queryset = self.queryset()
    self.list_queryset = self.get_list_queryset()
           

可以看到base_queryset、list_queryset最终都是调用的queryset()方法,该方法定义在:

venv\Lib\site-packages\xadmin\views\base.py
           

所以,覆写queryset()即为最终的解决方案。