I、Admin界面显示优化
Ein.内置优化
由于用户表比较特殊,为系统中存在的,Django内置了一个UserAdmin对显示用户信息做了优化
我们在apps/users/admin.py内重写所有代码
# 导入UserAdmin
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from apps.users.models import UserProfile
admin.site.register(UserProfile, UserAdmin)
启动项目,进入http://127.0.0.1:8000/admin/ 观察用户信息界面的变化
Zwei.利用Xadmin优化
a.安装xadmin
接下来我们使用xadmin对用户信息界面进行优化(对应的Django2.2版本的xadmin,注:不同版本的Django需要在Github上下载对应版本的xadmin)下载链接 (百度云提取码:6fm7)
首先我们打开将xadmin下载并解压后粘贴到项目根目录内,然后打开xadmin/xadmin的配置.txt阅读内容
1. 下载xadmin源码
2. 在settings的INSTALLED_APPS中添加
crispy_forms 和 xadmin
3. 安装xadmin的依赖包
4. 通过migrate生成xadmin需要的表
我们按步骤进行,由于我们已经完成了下载,所以进行第二步,打开settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'apps.users.apps.MxOnlineConfig',
'apps.courses.apps.CoursesConfig',
'crispy_forms',
# 注册xadmin
'xadmin',
]
按照第三步,我们打开xadmin/requirements.txt,利用pip install -r requirements.txt进行安装依赖(一个个安装也没有问题)。
注意当前我们使用的python版本为3.7。
按照第四步,我们进行数据迁移打开manage.py Task
migrate xadmin
此时可能会报错内容为:ImportError: No module named ‘DjangoUeditor’,我们安装DjangoUeditor包,重新migrate,继续报错ImportError: No module named ‘widgets’,这是由于DjangoUeditor对python3的支持存在问题,我们需下载一个新的DjangoUeditor下载链接(百度云提取码:ju2n),解压新下载的DjangoUeditor,复制该文件夹,找到自己虚拟环境的创建的位置我的为E:\PythonVenv\py_mxonline\Lib\site-packages,粘贴进该文件夹,并替换重复文件即可解决问题。(这是其中一种常见错误,其余错误请自行搜索解决)
解决该问题后我们重新migrate xadmin(不需要makemigrations的原因是xadmin内已经生成完迁移文件了。)
之后在MxOnline/urls.py内给xadmin分配url
# 导入xadmin
import xadmin
# 在urlpatterns内添加
path('xadmin/', xadmin.site.urls),
这里介绍一种问题的解决办法
问题:已经迁移过数据,重新迁移时无法刷新表或在迁移内有错需要重新对部分应用进行迁移解决办法:
1.打开对应数据库,删除django_migrations表以及需要重新迁移生成的表。
2.删除对应应用已存在的迁移文件
3.打开manage.py Task 输入 migrate --fake(该语句会生成并刷新django_migrations表)
4.对需要重新迁移的应用进行makemigrations [appname] 后直接 migrate [appname] 即可
b.应用xadmin
这里以courses应用举例说明如何应用,请读者根据文末提示自行完成organizations应用的xadmin优化
首先打开apps/courses/models.py,我们先编写模型:
from django.db import models
from apps.users.models import BaseModel
# Create your models here.
class Course(BaseModel):
name = models.CharField(verbose_name="课程名", max_length=50)
desc = models.CharField(verbose_name="课程描述", max_length=300)
learn_times = models.IntegerField(default=0, verbose_name="学习时长/min")
degree = models.CharField(verbose_name="课程难度",
choices=(('primary', '初级'), ('intermediate', '中级'), ('advanced', '高级')), max_length=20)
students = models.IntegerField(verbose_name="学习人数", default=0)
fav_nums = models.IntegerField(verbose_name="收藏人数", default=0)
click_nums = models.IntegerField(verbose_name="点击量", default=0)
notice = models.CharField(verbose_name="课程公告", max_length=300, default="")
category = models.CharField(verbose_name="课程类别", max_length=20, default="后端开发")
tag = models.CharField(verbose_name="标签", max_length=10, default="")
course_notes = models.CharField(verbose_name="课程须知", max_length=300, default="")
teacher_notice = models.CharField(verbose_name="教师通告", max_length=300, default="")
is_classic = models.BooleanField(default=False, verbose_name="是否经典")
is_banner = models.BooleanField(default=False, verbose_name="是否广告位")
course_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
class Lesson(BaseModel):
# on_delete 表示对应的外键数据被删除后当前数据如何执行
course = models.ForeignKey(Course, verbose_name="课程", on_delete=models.CASCADE)
chapter_name = models.CharField(verbose_name="章节名", max_length=100)
learn_times = models.IntegerField(default=0, verbose_name="学习时长/min")
class Meta:
verbose_name = "课程章节"
verbose_name_plural = verbose_name
def __str__(self):
return self.chapter_name
class Video(BaseModel):
lesson = models.ForeignKey(Lesson, verbose_name="章节", on_delete=models.CASCADE)
video_name = models.CharField(max_length=100, verbose_name="视频名称")
learn_times = models.IntegerField(default=0, verbose_name="学习时长/min")
url = models.CharField(max_length=1000, verbose_name="访问地址")
class Meta:
verbose_name = "课程章节"
verbose_name_plural = verbose_name
def __str__(self):
return self.video_name
class CourseResource(BaseModel):
course = models.ForeignKey(Course, verbose_name="课程", on_delete=models.CASCADE)
resource_name = models.CharField(max_length=100, verbose_name="名称")
file_url = models.FileField(max_length=200, verbose_name="下载地址", upload_to="courses/resourse%Y/%m")
class Meta:
verbose_name = "课程资源"
verbose_name_plural = verbose_name
def __str__(self):
return self.resource_name
然后,对courses应用进行数据迁移
迁移完成后,在apps/courses文件夹下新建一个名为adminx.py的文件(注:文件名不可变),编写显示逻辑
import xadmin
from apps.courses.models import Course
# Register your models here.
# 无需继承admin.ModelAdmin
class CourseAdmin(object):
# 显示字段
list_display = ["id", "name", "desc", "learn_times", "degree"]
# 搜索字段
search_fields = ["name"]
# 过滤器
list_filter = ["id", "name", "desc", "learn_times", "degree"]
xadmin.site.register(Course, CourseAdmin)
补充apps/courses/apps.py内容
from django.apps import AppConfig
class CoursesConfig(AppConfig):
name = 'apps.courses'
# 补充的代码,为了显示的直观
verbose_name = "课程管理"
然后我们运行项目,在http://127.0.0.1:8000/xadmin/ 内打开xadmin页面
点击课程信息,我们可以添加课程
II、实现organizations应用的xadmin显示优化的若干提示
下面是organizations应用models内容的相应提示,请按照下列类以及属性提示编写model层
Class | Attributes(verbose_name) | Remarks |
---|---|---|
City | --- | Meta:城市信息 |
^ | 城市名 | |
^ | 城市描述 | --- |
CourseOrg | --- | Meta:机构信息 |
^ | 机构名称 | --- |
^ | 机构标签 | --- |
^ | 机构类别 | 用choice实现类别:个人,高校,培训机构三个选项 |
^ | 点击量 | --- |
^ | 收藏人数 | --- |
^ | logo | 图片的加载路径"org/%Y/%m" |
^ | 机构地址 | --- |
^ | 学习人数 | --- |
^ | 课程数 | --- |
^ | 是否认证 | --- |
^ | 是否金牌 | --- |
^ | 所在城市 | 需要外键关联City类 |
Teacher | --- | Meta:教师信息 |
^ | 用户 | 一对一关联UserProfile |
^ | 所属机构 | 外键关联CourseOrg |
^ | 教师名 | --- |
^ | 工作年限 | --- |
^ | 就职公司 | --- |
^ | 公司职位 | --- |
^ | 教学特点 | --- |
^ | 收藏人数 | --- |
^ | 点击量 | --- |
^ | 年龄 | --- |
^ | 头像 | 图片的加载路径"teacher/%Y/%m" |
以及对于运行结果的示例如下:
为了完成下列显示,我们也需要编写对应的apps.py和adminx.py来完成显示
在此之前,我们需要完备的熟悉courses示例
该项目已在github基本完成大体内容,还有些细枝末节的内容未实现,以及由于时间原因,django的笔记暂停更新,之后会整理后进行接续