上一篇博文在IDC Model里增加了user字段,并在此字段存储了创建该数据的登录用户信息。
class IDC(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, editable=False, null=True)#创建该数据的登录用户
name = models.CharField(max_length=64)
contact = models.CharField(max_length=32)
phone = models.CharField(max_length=32)
address = models.CharField(max_length=128)
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)
完成代码后,启动系统,执行下述操作验证效果:
本文的处理方法,同样是查看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()即为最终的解决方案。