1.xadmin会自动发现我们自定义的用户表并自动生成
class UserProfile(AbstractUser):
nick_name = models.CharField(max_length=50, verbose_name="昵称", default="")
birthday = models.DateField(verbose_name="生日", null=True, blank=True)
gender = models.CharField(verbose_name="性别", choices=GENDER_CHOICES, max_length=6)
address = models.CharField(max_length=100, verbose_name="地址", default="")
mobile = models.CharField(max_length=11, verbose_name="手机号码")
image = models.ImageField(verbose_name="用户头像", upload_to="head_image/%Y/%m", default="default.jpg")
class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name
2.使用
2.1简单使用
# 自定义后台管理类
from apps.organizations.models import Teacher
class CityAdmin(object):
# 列表页的显示
list_display = ["id", "name", "desc"]
# 搜索框的显示极其范围
search_fields = ["name", "desc"]
# 过滤器的显示极其范围
# 如果City这个模型类存在外键如country,那么可以使用country__外键的字段来指明过滤范围
list_filter = ["name", "desc", "add_time"]
# 字段是否可编辑
list_editable = ["name", "desc"]
# 注册后台管理类
xadmin.site.register(City, CityAdmin)
2.2全局配置
class GlobalSettings(object):
# 设置标题
site_title = "慕学后台管理系统"
# 设置页脚
site_footer = "慕学在线网"
# 设置左侧导航栏是否可以展开
# menu_style = "accordion"
class BaseSettings(object):
# 设置主题
enable_themes = True
use_bootswatch = True
3.更高级的使用
3.1自定义表的详情页面
1.重写get_form_layout方法
class NewCourseAdmin(object):
...
list_display = ['name', 'desc', 'show_image', 'go_to', 'detail', 'degree', 'learn_times', 'students']
search_fields = ['name', 'desc', 'detail', 'degree', 'students']
list_filter = ['name', 'teacher__name', 'desc', 'detail', 'degree', 'learn_times', 'students']
...
def get_form_layout(self):
# self.org_obj判断是否是编辑页面,如果是编辑页面则返回True
if self.org_obj:
self.form_layout = (
# 中间主体内容
Main(
# 划分区域,每个字段独立一行
Fieldset("讲师信息",
'teacher', 'course_org',
# 不显示讲师信息字样
css_class='unsort no_title'
),
# 调用Row()的字段在同一行
Fieldset("基本信息",
'name', 'desc',
Row('learn_times', 'degree'),
Row('category', 'tag'),
'youneed_know', 'teacher_tell', 'detail',
),
),
# 右侧部分
Side(
Fieldset("访问信息",
'fav_nums', 'click_nums', 'students', 'add_time'
),
),
Side(
Fieldset("选择信息",
'is_banner', 'is_classics'
),
)
)
return super(NewCourseAdmin, self).get_form_layout()
3.2组和权限的概念
- 可以给每个用户设置权限,不同的权限对应不同的功能;如果需要对多个用户设置权限,则需要添加一个组,对组配置权限,再将用户选中为某个组,那么该用户便有了那个组的权限
3.3不同用户登录时返回不同的数据
1.重写queryset方法
class NewCourseAdmin(object):
...
list_display = ['name', 'desc', 'show_image', 'go_to', 'detail', 'degree', 'learn_times', 'students']
search_fields = ['name', 'desc', 'detail', 'degree', 'students']
list_filter = ['name', 'teacher__name', 'desc', 'detail', 'degree', 'learn_times', 'students']
...
def queryset(self):
# 获取所有数据
qs = super().queryset()
# 判断该用户是否为超级管理员用户
if not self.request.user.is_superuser:
# 不是超级管理员则对数据进行筛选
# 这边teacher和user是一对一的关系
qs = qs.filter(teacher=self.request.user.teacher)
return qs
普通用户界面
超级管理员用户界面
3.4新增一条数据时的拦截
1.重写save_models方法
class UserCourseAdmin(object):
...
list_display = ['user', 'course', 'add_time']
search_fields = ['user', 'course']
list_filter = ['user', 'course', 'add_time']
...
# 当新增或者修改一条数据时,调用
def save_models(self):
# obj为UserCourse的实例
obj = self.new_obj
# 判断是否为新增数据,如果obj.id为None时,则新增一条数据
if not obj.id:
# 保存当前新增对象
obj.save()
# 当新增一条数据时,学生人数加1
course = obj.course
course.students += 1
course.save()
3.5多个管理器管理同一张表
1.models.py中新建一个类,该类继承要管理的那张表
class BannerCourse(Course):
class Meta:
verbose_name = "轮播课程"
verbose_name_plural = verbose_name
# 设置proxy=True,做migration不会生成一张表,但是具有了管理表的功能(继承Course)
proxy = True
2.adminx.py中新建一个管理器,重写queryset方法
class BannerCourseAdmin(object):
list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']
search_fields = ['name', 'desc', 'detail', 'degree', 'students']
list_filter = ['name', 'teacher__name', 'desc', 'detail', 'degree', 'learn_times', 'students']
list_editable = ["degree", "desc"]
def queryset(self):
qs = super().queryset()
# 筛选出是否为广告位的课程
qs = qs.filter(is_banner=True)
return qs
3.注册管理类
xadmin.site.register(BannerCourse, BannerCourseAdmin)
3.6为列表页图片字段,显示图片
1.自定义方法
class Course(BaseModel):
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE, verbose_name="讲师")
course_org = models.ForeignKey(CourseOrg, null=True, blank=True, on_delete=models.CASCADE, verbose_name="课程机构")
name = models.CharField(verbose_name="课程名", max_length=50)
desc = models.CharField(verbose_name="课程描述", max_length=300)
learn_times = models.IntegerField(default=0, verbose_name="学习时长(分钟数)")
degree = models.CharField(verbose_name="难度", choices=(("cj", "初级"), ("zj", "中级"), ("gj", "高级")), max_length=2)
students = models.IntegerField(default=0, verbose_name='学习人数')
fav_nums = models.IntegerField(default=0, verbose_name='收藏人数')
click_nums = models.IntegerField(default=0, verbose_name="点击数")
notice = models.CharField(verbose_name="课程公告", max_length=300, default="")
category = models.CharField(default=u"后端开发", max_length=20, verbose_name="课程类别")
tag = models.CharField(default="", verbose_name="课程标签", max_length=10)
youneed_know = models.CharField(default="", max_length=300, verbose_name="课程须知")
teacher_tell = models.CharField(default="", max_length=300, verbose_name="老师告诉你")
is_classics = models.BooleanField(default=False, verbose_name="是否经典")
detail = UEditorField(verbose_name="课程详情", width=600, height=300, imagePath="courses/ueditor/images/",
filePath="courses/ueditor/files/", default="")
is_banner = models.BooleanField(default=False, verbose_name="是否广告位")
image = models.ImageField(upload_to="courses/%Y/%m", verbose_name="封面图", max_length=100)
class Meta:
verbose_name = "课程信息"
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 自定义方法
# 显示图片
def show_image(self):
from django.utils.safestring import mark_safe
# 自定义html标签
return mark_safe("<img src='{}'>".format(self.image.url))
# 为该方法添加一个属性,作为列表页名称
show_image.short_description = "图片"
# 自定义方法
# 跳转到课程链接
def go_to(self):
from django.utils.safestring import mark_safe
return mark_safe("<a href='/course/{}'>跳转</a>".format(self.id))
# 为该方法添加一个属性,作为列表页名称
go_to.short_description = "跳转"
2.管理器中在list_display 添加该方法
class NewCourseAdmin(object):
...
list_display = ['name', 'desc', 'show_image', 'go_to', 'detail', 'degree', 'learn_times', 'students']
...
3.7编辑页面某些字段设置为只读
1.在管理器类中添加属性readonly_fields ,在该属性中添加字段
class NewCourseAdmin(object):
...
readonly_fields = ["students", "add_time"]
...
3.8编辑页面隐藏某些字段
1.在管理器类中添加属性exclude,在该属性中添加字段
class NewCourseAdmin(object):
...
# 隐藏某些字段,字段不能与readonly_fields中的字段相同,否则以readonly_fields中的字段为主,必填字段不得添加
# exclude中有的字段在form_layout中不要出现
exclude= ["students", "add_time"]
...
3.9用户进入列表页的默认排序
1.在管理器类中添加属性ordering,在该属性中添加字段
class NewCourseAdmin(object):
...
ordering = ["click_nums"]
...
3.10自定义后台管理图标
class NewCourseAdmin(object):
...
# 格式:fa fa-xxxxxx
model_icon = 'fa fa-addres'
...
自定义更多图标
百度:awesome font—> 找到中文链接—>下载,解压—>拷贝css,fonts至xadmin的原始路径下—>xadmin/static/xadmin/vendor/font-awesome
3.11一个页面修改多个页面的信息
1.在adminx.py自定义一个类
class LessonInline(object):
# 定义的该模型类必须有一个外键指向下面管理器锁管理的模型类
model = Lesson
# 设置样式为标签
# style = "tab"
extra = 0
exclude = ["add_time"]
class NewCourseAdmin(object):
...
# 配置同一个编辑页面同时可以编辑其他页面的信息
inlines = [LessonInline,]
# 注册管理器
xadmin.site.register(Course, NewCourseAdmin)
...
默认显示在编辑页面的最下方处
3.12 集成ueditor富文本编辑器到xadmin中
3.12.1依赖
pip install DjangoUeditor
3.12.2配置
在settings.py中
在INSTALL_APPS里面增加DjangoUeditor app,如下:
INSTALLED_APPS = (
#........
'DjangoUeditor',
)
在urls.py中
url(r'^ueditor/',include('DjangoUeditor.urls' )),
3.12.3在model中的使用
from DjangoUeditor.models import UEditorField
class Blog(models.Model):
Name=models.CharField(,max_length=100,blank=True)
Content=UEditorField('内容 ',width=600, height=300, toolbars="full", imagePath="", filePath="", upload_settings={"imageMaxSize":1204000},
settings={},command=None,event_handler=myEventHander(),blank=True)
参数含义详见:https://github.com/zhangfisher/DjangoUeditor
3.12.4给xadmin安装一个ueditor相关插件
将ueditor拷贝到xadmin下的plugins文件夹下,并且在__init__.py中的PLUGINS注册插件
3.12.5集成xadmin
class NewCourseAdmin(object):
# 配置detail字段显示为富文本
style_fields = {
"detail": "ueditor"
}
在templates中可能要使用:
{% autoescape off%}…{% endautoescape %}:关闭django转义
3.13 xadmin数据的导入和导出
3.13.1 依赖
- pip install django-import-export
3.13.2 注册app
INSTALLED_APPS = [
…
# xadmin的导入和导出功能
‘import_export’,
…
]
3.13.3 使用
class MyResource(resources.ModelResource):
class Meta:
model = Course
# fields = ('name', 'description',)
# exclude = ()
class NewCourseAdmin(object):
...
# 配置导入和导出按钮
import_export_args = {'import_resource_class': MyResource, 'export_resource_class': MyResource}
...
如果要去掉自带的导出功能,到xadmin下的 plugins的__init__注释掉export