Django之Admin常见的二次开发

Django之Admin常见的二次开发

时隔半年多,第二次回过头再看了一遍Django实战开发这本书,收获还是很多。由于工作没有用上django,很多知识点都忘记了。还是得写写博客记录一下吧。
重写函数目的
get_readonly_fields()给隐私数据设置权限
clolred_name()在models.py中设置字体颜色
get_queryset()设置查询权限
formfield_for_foreignkey()设置外键的下拉框的权限
formfiled_for_choice_field()设置非外键的下拉框权限(但不能增加字段)
formfield_for_dbfield()增加非外键下拉框字段
save_model()数据修改/保存的操作写入日志
delete_model()数据删除写入日志
get_datas()自定义函数名导出数据
  • 函数重写在app(index)下的admin.py中
get_readonly_fields()
  • 超级用户和普通用户访问数据时,一些隐私数据要设置成可读。
def get_readonly_fields(self, request, obj=None):
        # 判断超级用户
        if request.user.is_superuser:
            self.readonly_fields = []
        else:
        	# 普通用户访问时 不可休息 payment字段
            self.readonly_fields = ['payment']
        return self.readonly_fields      
  • 普通用户访问时
    在这里插入图片描述
colored_name()
  • 在app下的models中的某个模型类中写
## moedls.py 
   
   from django.utils.html import format_html
   # 自定义字体颜色
    def colored_name(self):
        if 'tom' in self.person.name:
            color_code = 'red'
        else:
            color_code = 'blue'
        return format_html(
            '<span style="color:{};">{}</span>',
            color_code,self.person.name
        )
  #设置admin 的字段名称
    colored_name.short_description = '带颜色的名字'
    ## 在admin.py中添加这个字段 '带颜色的名字'
    list_display.append('colored_name') 

在这里插入图片描述

get_queryset()
  • 设置不同用户的查询权限
 ##  admin.py 
   def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        else:
        	# 非超级用户只能查一条数据
            return qs.filter(id__lt=2)

在这里插入图片描述

formfield_for_foreignkey()
  • 修改外键下拉框的可选值
## models.py
class Vocation(models.Model):
	...
    person = models.ForeignKey(PersonInfo,on_delete=models.CASCADE)
    ...
 ## admin.py
 def formfield_for_foreignkey(self, db_field, request, **kwargs):
        ## 判断是否为外键 person 为外键
        if db_field.name == 'person':
            if not request.user.is_superuser:
                v = Vocation.objects.filter(id__lt=2)
                kwargs['queryset'] = PersonInfo.objects.filter(id__in=v)
        return super().formfield_for_foreignkey(db_field,request,**kwargs)
  • 普通用户
    在这里插入图片描述
formfield_for_choice_field()
  • 内置函数formfield_for_choice_field虽然能新增下拉框的选项内容,但在保存数据的过程中,Django会提示新增的选项内容是无效的,因此该函数常用于过滤已存在的选项。
## 改变非外键字段下拉框的数据
# 内置函数formfield_for_choice_field虽然能新增下拉框的选项内容,
# 但在保存数据的过程中,Django会提示新增的选项内容是无效的,因此该函数常用于过滤已存在的选项。
def formfield_for_choice_field(self, db_field, request, **kwargs):
   if not request.user.is_superuser:
       if db_field.name == 'job':
            kwargs['choices'] = (('软件开发', '软件开发'),
                                ('软件测试', '软件测试'),)
   return super().formfield_for_choice_field(db_field,request,**kwargs)

在这里插入图片描述

formfield_for_dbfield()
  • 新增下拉属性
 # 如果要对字段的下拉框新增内容,可以重新定义formfield_for_dbfield函数
    # Django首先执行formfield_for_dbfield,然后再执行formfield_for_choice_field
    # 如果我们都重写了formfield_for_dbfield和formfield_for_choice_field
    # 最后下拉框的选项以formfield_for_choice_field为准
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        if request.user.is_superuser:
            if db_field.name == 'job':
                # 必须判断选项内容是否已存在db_field.choices,如果不判断,则会重复新增选项
                if ('网页设计', '网页设计') not in db_field.choices:
                    db_field.choices += (('网页设计', '网页设计'),)
        return super().formfield_for_dbfield(db_field, request, **kwargs)
  • 超级用户
    在这里插入图片描述
save_model()
  • 在新增或者修改数据的时候 增加的操作 写入日志
 ## 在保存修改的save_model 中加点功能
    def save_model(self, request, obj, form, change):
        time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        user_root = '超级用户' if request.user.is_superuser else '普通用户'
        change_msg = ""
        # 获取当前用户名
        user = request.user.username
        # 获取表单数据
        new_msg = form.cleaned_data
        if change:
            print('修改数据')
            # 使用模型获取数据
            job = self.model.objects.get(pk=obj.pk).job
            old_msg = self.model.objects.filter(pk=obj.pk).values()
            old_msg = list(old_msg)[0]
            new_msg['person_id'] =form.cleaned_data['person'].id
            for k,v in new_msg.items():
            	# 判读修改的数据
                if k in old_msg and new_msg[k] != old_msg[k]:
                    change_msg += k + "字段" + str(old_msg[k]) + ' 修改为 ' + str(new_msg[k])
            # 使用表单获取数据
            person = form.cleaned_data['person'].name
            res = user_root + ' ' + user + '在'+ str(time) +'将' +job + person + '的' + change_msg +'\r\n'
        else:
            print('新增数据')
            for k, v in new_msg.items():
                change_msg += k + ':' + str(new_msg[k]) + '\n'
            res = user_root + ' ' + user + '在' + str(time) + '新增\n'+change_msg + '\r\n'
        # 写入日志
        f = open('d://log.txt', 'a')
        f.write(res)
        f.close()
        super().save_model(request,obj,form,change)

在这里插入图片描述

delete_model()
  • 删除数据的时候 写入日志
 ## 重写delete_model() 来记录删除的数据
    def delete_model(self, request, obj):
        print('delete')
        message = ""
        user_root = '超级用户' if request.user.is_superuser else '普通用户'
        user_name = request.user.username
        time = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        d = self.model.objects.filter(pk=obj.pk).values()
        d = list(d)[0]
        for k,v in d.items():
            message +=  k + ':' + str(d[k]) + '\n'
        res = user_root + ' ' + user_name + '在' + str(time) + '删除\n'+message + '\r\n'
        # 写入日志
        f = open('d://log.txt', 'a')
        f.write(res)
        f.close()
        super().delete_model(request,obj)

在这里插入图片描述

get_datas()
  • 导出数据
# 在admin.py中导入messages
from django.contrib import messages
@admin.register(Vocation)
class VocationAdmin(admin.ModelAdmin):
## 数据批量操作
    def get_datas(self,request, queryset):
    	# 判断超级用户
        if request.user.is_superuser:
            temp = []
            for d in queryset:
                t = [d.job,d.title,str(d.payment),d.person.name]
                temp.append(t)
            f = open('d://data.txt','a')
            for t in temp:
                f.write(','.join(t) + '\r\n')
            f.close()
            # 设置提示信息
            self.message_user(request,'数据导出成功!')
        else:
        	# 非超级用户提示警告
            self.message_user(request, '数据导出失败,没有权限!',level=messages.WARNING)
    ## 设置函数的显示名称
    get_datas.short_description = '导出所选数据'
    # 添加到动作栏
    actions = ['get_datas']

在这里插入图片描述

  • 非超级用户
    在这里插入图片描述

写到这了8.

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值