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:
self.readonly_fields = ['payment']
return self.readonly_fields
- 普通用户访问时
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c86d943953d28803eeaff0857d55fc1d.png#pic_center)
colored_name()
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
)
colored_name.short_description = '带颜色的名字'
list_display.append('colored_name')
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/22d7025f77b9d9e0a5acc609e46e60c0.png#pic_center)
get_queryset()
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
else:
return qs.filter(id__lt=2)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6b3aaa78f26078c8fc58d33059f0f67f.png#pic_center)
formfield_for_foreignkey()
class Vocation(models.Model):
...
person = models.ForeignKey(PersonInfo,on_delete=models.CASCADE)
...
def formfield_for_foreignkey(self, db_field, request, **kwargs):
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)
- 普通用户
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d43faefb64ea85c1e5b4cdecf0fe4534.png#pic_center)
formfield_for_choice_field()
- 内置函数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)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5c43df8fada98c1850cd9729222045a4.png#pic_center)
formfield_for_dbfield()
def formfield_for_dbfield(self, db_field, request, **kwargs):
if request.user.is_superuser:
if db_field.name == 'job':
if ('网页设计', '网页设计') not in db_field.choices:
db_field.choices += (('网页设计', '网页设计'),)
return super().formfield_for_dbfield(db_field, request, **kwargs)
- 超级用户
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/da797a4bb9d63f50acbaafe08e7b6a47.png#pic_center)
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)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/84de8e8bcfc8b178f6753c5aaf251ec6.png#pic_center)
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)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/439372246cd15cd5303eb041b7c841b6.png#pic_center)
get_datas()
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']
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fda495a6a09ffd80e4f0f24bc865d18d.png#pic_center)
- 非超级用户
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a67d7336a4d834de5018734ae8e5bd30.png#pic_center)
写到这了8.