百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

Django+SimpleUI快速开发指南

liebian365 2024-11-22 17:15 16 浏览 0 评论

作者:七号空格
链接:https://zhuanlan.zhihu.com/p/113447102
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一、环境准备

1、创建新的django项目

2、安装simpleui

# 指定清华源安装simpleui
pip install django-simpleui -i https://pypi.tuna.tsinghua.edu.cn/simple

3、修改django后台模块默认的模板

# 修改project的setting文件,在INSTALLED_APPS 首行引入simple应用
  INSTALLED_APPS = [
      'simpleui',
      'django.contrib.admin',
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.messages',
      'django.contrib.staticfiles',
      ...
  ]

4、字符集及时区设置

# 修改project的setting文件
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False # 这里务必调整为False,否则时区设置无效

5、静态资源及debug状态设置

# django在开发环境提供bug调试功能,同时该设置影响到runserver运行时的静态资源引入,故生产环境关闭debug开关的时候,保障静态资源的正确引入需要显性定义静态资源
DEBUG = True
# 定义静态资源位置
 STATICFILES_DIRS = [
     os.path.join(BASE_DIR, "static"),
 ]

# or 通过克隆方式将静态资源克隆到项目的静态资源目录,交由ngnix调用
python3 manage.py collectstatic
# 如果克隆报错提示找不到静态目录,请先在settings.py指定静态目录
STATIC_ROOT = os.path.join(BASE_DIR, "static")

# 由于开发过程中simpleui有限通过cdn进行页面渲染,一般情况下我们需要将其调整成本地资源方式,往往生产环境是无法连接外网的
SIMPLEUI_STATIC_OFFLINE = True # 离线模式

6、数据库连接配置

# 这里以postgresql数据库为例,通常建议使用mysql数据库,多数据库连接不在此处讨论
# postgresql
## 安装postgresql驱动
pip install psycopg2-binary
#pip install psycopg2
## 这里需要设置postgresql的schema信息,通过options字典指定配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME' : 'moon',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST':'127.0.0.1',
        'PORT': '5432',
        'OPTIONS': {
                    'options': '-c search_path=myapp'
                },
    }
}

# mysql
## 安装mysql驱动
pip install pymysql
## init文件引入pymysql 用于代理django认可的mysql驱动,同时由于django的版本问题对pymysql的版本存在要求需要增加一个版本欺骗动作
import pymysql
pymysql.version_info = (1, 3, 13, "final", 0)
pymysql.install_as_MySQLdb()
## setting增加mysql连接串配置信息
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'jay_django_test',
        'HOST':'127.0.0.1',
        'USER':'root',
        'PASSWORD':'qweasd',
        'PORT':'3306',
    }
}

7、admin模块进行数据库初始化

# 执行数据库迁移
python manage.py migrate

8、创建admin模块超级管理员角色

python manage.py createsuperuser

9、检查simple是否正确引入

# 浏览器访问 127.0.0.1:8000/admin 使用admin账户登录确认是否生效

二、创建APP

1、创建app

python manage.py startapp myapp
# 将app注册到project
INSTALLED_APPS = [
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp', # 添加到末尾
]
# 说明:这里注册app是整个app的起点,包括后续涉及到数据迁移文件的生成都依赖于注册列表

2、创建model

# 在app的model创建测试用例的model
import django.utils.timezone as timezone
# Create your models here.
class job_detail(models.Model):
    ## 定义枚举值状态
    JOB_TYPE_STATUS_GP = '01'
    JOB_TYPE_STATUS_DEFAULT = '02'
    JOB_TYPE_STATUS_CHOICES = (
        (JOB_TYPE_STATUS_GP, 'Greenplum函数'),
        (JOB_TYPE_STATUS_DEFAULT, '其他'),
    )

    CREATED_BY = models.CharField('创建人',max_length=32) # 创建人
    CREATED_TIME = models.DateTimeField('创建时间',default=timezone.now) # 创建时间
    UPDATED_BY = models.CharField('更新人',max_length=32) # 更新人
    UPDATED_TIME = models.DateTimeField('更新时间',default=timezone.now)  # 更新时间
    JOB_TYPE = models.CharField('任务类型',max_length=32,
                                choices=JOB_TYPE_STATUS_CHOICES,
                                default=JOB_TYPE_STATUS_DEFAULT
                                ) # 任务类型 01:gp任务;02:datax任务;03:kafka推送任务;04:http请求任务
    JOB_NAME = models.CharField('任务名称',max_length=128) # 任务名称
    JOB_COMMENT = models.CharField('任务描述',max_length=128)  # 任务描述
    IN_PARA = models.CharField('输入参数定义',max_length=32) # 输入参数定义 参数使用英文逗号分隔
    IN_PARA_COMMENT = models.CharField('输入参数描述',max_length=1024)  # 输入参数描述
    OUT_PARA = models.CharField('输出参数定义',max_length=32)  # 输出参数定义 参数使用英文逗号分隔
    OUT_PARA_COMMENT = models.CharField('输出参数描述',max_length=1024)  # 输出参数描述
    VERSION = models.CharField('版本号',max_length=32) # 版本号
    IS_DELETE = models.CharField('是否删除',max_length=1, default='N')  # 逻辑删除 Y:删除;N:正常
    PRO_STATUS = models.CharField('发布状态',max_length=1,default='N') # 发布状态 Y:发布;N:开发

# 生成数据库迁移文件,生产环境建议指定app进行迁移文件生成,避免未完善功能对已有正常版本的影响
python manage.py makemigrations
# 执行数据库迁移
python manage.py migrate

3、配置路由

# 常规的django的web开发一般需要在各个app中创建urls文件,并且将urls路由引入到project的urls中进行统一管理,这里我们通过admin模块的路由注册功能,注册到admin的路由中
# 应用的admin.py中进行model对象注册
from myapp.models import job_detail
admin.site.register(job_detail)

三、页面布局

1、增删改查model测试

# 此时登录到页面上可以发现,刚刚创建的数据表已经作为一个类目在页面上展示了,但同时会发现一个问题,详情页面里面显示的并不是字段信息,而是具体的表名称,此处与我们设想的内容并不匹配。通过这一步骤我们成功验证了app的注册方式。具体展示内容,下面的步骤会详细介绍

2、admin首页布局

# 如上图所示,首页基础展示项目由三个部分组成,往往我们需要对首页进行定制重写,这里我们先把这几个展示模块先关闭
# project的setting文件最后追加如下设置,即可关闭以上几个模块以及信息采集模块
SIMPLEUI_HOME_INFO = False
SIMPLEUI_HOME_QUICK = False
SIMPLEUI_HOME_ACTION = False
SIMPLEUI_ANALYSIS = False
# SIMPLEUI_HOME_TITLE = '百度一下你就知道' # 【首页】按钮文案配置
SIMPLEUI_HOME_PAGE = 'https://www.baidu.com' # 可用于嵌入其他链接,这里可以直接方便的嵌入报表链接
SIMPLEUI_HOME_ICON = 'el el-icon-platform-eleme'
# ICON 支持element-ui和fontawesome  eg:fa fa-user

# 图标ICON 样式查看
https://element.eleme.cn/#/zh-CN/component/icon
http://www.fontawesome.com.cn/cheatsheet/
# 经过实际测试,饿了么的图标稍微有点小,而且数量少

接下来我们一起看下侧边栏设置,simpleui的侧边栏支持菜单排序,动态菜单等功能

# project的setting文件中增加如下配置,icon信息可以参考http://www.fontawesome.com.cn/cheatsheet/
SIMPLEUI_CONFIG = {
    'system_keep': False, # 关闭系统菜单
    'menu_display': ['任务管理', '测试', '权限认证'],
    'dynamic': True,    # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
    'menus': [{
        'app': 'myapp',
        'name': '任务管理',
        'icon': 'fas fa-user-shield',
        'models': [{
            'name': '任务管理1',
            'icon': 'fa fa-user',
            'url': 'job_detail/'
        }]
    },{
        'app': 'auth',
        'name': '权限认证',
        'icon': 'fas fa-user-shield',
        'models': [{
            'name': '用户',
            'icon': 'fa fa-user',
            'url': 'auth/user/'
        }]
    }, {
        'name': '测试',
        'icon': 'fa fa-file',
        'models': [{
            'name': 'Baidu',
            'url': 'http://baidu.com',
            'icon': 'far fa-surprise'
        }, {
            'name': '内网穿透',
            'url': 'https://www.wezoz.com',
            'icon': 'fab fa-github'
        }]
    }]
}

如图所示,新配置的侧边栏已经生效,但点击我们自己创建的app的详情页面提示404错误,从异常信息得知,我们在路由配置上存在问题,系统未能找到我们的路由信息

# 问题配置
'url': 'job_detail/'
# 正确配置
'url': 'myapp/job_detail/'
# 这里大家可以思考下,url的配置与常规的urls.py文件的路由显性引入的异同点

3、页面标题及侧边栏标题定制

# 应用的admin.py文件中
admin.site.site_header = '数据中心'
admin.site.site_title = 'XXX数据中心'
admin.site.index_title = u'XXXX数据中心'

目前看index_title在simpleui中无效,检查过simpleui的template文件确实没使用到这个参数

4、列表查询页面定制

# admin文件中定义展示页面,后续方便页面管理,可以独立文件,通过import方式引入进行注册
from myapp.models import job_detail

@admin.register(job_detail)
class job_detail(admin.ModelAdmin):
    # 设置页面可以展示的字段
    list_display = ('JOB_TYPE', 'JOB_NAME','JOB_COMMENT',
              'IN_PARA','IN_PARA_COMMENT',
              'OUT_PARA','OUT_PARA_COMMENT')
    # 默认不配置的话,第一个字段会存在链接到记录编辑页面
    # list_display_links = None
    list_display_links = ('JOB_NAME',)
    # 设置过滤选项
    list_filter = ('JOB_TYPE', 'CREATED_TIME',)
    # 每页显示条目数 缺省值100
    list_per_page = 1
    # show all页面上的model数目,缺省200
    # list_max_show_all = 200
    # 设置可编辑字段 如果设置了可以编辑字段,页面会自动增加保存按钮
    list_editable = ('IN_PARA_COMMENT',)
    # 按日期月份筛选 该属性一般不用
    # date_hierarchy = 'CREATED_TIME'
    # 按发布日期降序排序
    ordering = ('-CREATED_TIME',)
    # 搜索条件设置
    search_fields = ('JOB_NAME',)

    # 表头字段显示中文名称,这里需要修改models文件,在定义字段的时候增加别名
    # eg1:JOB_NAME = models.CharField('任务名称',max_length=128)
    # eg2: name = models.CharField(max_length=30,verbose_name=u"姓名")

    # 字段关联展示
    ## 场景1、关联其他表的数据展示,此处外键展示不做演示,生产环境尽量减少外键使用

    ## 场景2、枚举信息转义展示
    ###  此处需要在model定义页面通过枚举值转义配置对应展示中文信息,参考model模块代码设置

    """
      这种禁用编辑链接的放法只是不让它在页面中显示,即把超链接去掉了,
      但是还是可以通过手动输入url的方式来进入编辑页面。
      不过可以配合设置fieldsets或者readonly_fieldss来达到目的
      注意:这里建议删除按钮要禁用掉,否则只有拥有view权限的人员依然可以进行删除动作,或者需要进行人员角色判断
    """
    def has_add_permission(self, request):
        # 禁用添加按钮
        return True

    def has_delete_permission(self, request, obj=None):
        # 禁用删除按钮
        return False

5、表单编辑页面配置

"""
这一段主要用于屏蔽 【保存并继续编辑】以及【保存并新建下一个】的按钮,不符合用户习惯
同时需要在 类的定义里面要重写
"""
from django.contrib.admin.templatetags.admin_modify import *
from django.contrib.admin.templatetags.admin_modify import submit_row as original_submit_row

@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def submit_row(context):
    ctx = original_submit_row(context)
    ctx.update({
        'show_save_and_add_another': context.get('show_save_and_add_another', ctx['show_save_and_add_another']),
        'show_save_and_continue': context.get('show_save_and_continue', ctx['show_save_and_continue'])
        })
    return ctx
# --- 分割线 ---  
class job_detail(admin.ModelAdmin):
    ... ...
    # fields 用于控制编辑页面内,需要编辑的字段,逐个显示所有的非AutoField和editable=True
    #        这里可以采用二维元组的方式进行设定对应字段是否在一行显示,可通过 浏览器开发者工具进行查看确认
    # fields = (('JOB_NAME', 'JOB_TYPE'), 'JOB_COMMENT')
    # fieldsets 是二维元组列表,用于对编辑页面的布局,与fields属性互斥
    fieldsets = (
        (None, {
            'fields': ('JOB_NAME', 'JOB_TYPE', 'JOB_COMMENT')
        }),
        ('更多操作', {
            'classes': ('wide', 'extrapretty',),
            'fields': ('IN_PARA', 'OUT_PARA'),
        }),
    )
    save_as_continue = False # 修改完成之后跳转到元素列表页面
    # 重写方法屏蔽按钮
    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['show_save_and_add_another'] = False
        extra_context['show_save_and_continue'] = False
        return super(job_detail, self).change_view(request, object_id,
            form_url, extra_context=extra_context)

6、页面按钮权限配置

# django admin 的权限模块 默认提供了增删改查的权限配置
curr_per_set = {'myapp.view_job_detail','myapp.delete_job_detail','myapp.add_job_detail','myapp.change_job_detail'}
# 而当我们以下图为例:仅仅给某个用户赋权 查询 权限的时候,该用户还存在新增按钮的权限,对已有数据无操作权限,此处启发我们需要去思考页面上面按钮权限如何跟具体角色进行关联
# 当然 django admin 同样支持自定义权限,此处不再讨论
# 这里演示了根据不同用户角色决定是否在页面上显示相应的功能按钮
class job_detail(admin.ModelAdmin):
    ... ...
    def has_add_permission(self, request):
        user_per_set = request.user.get_all_permissions() # 获取当前用户权限
        # 待判断的权限范围
        curr_per_set = {'myapp.view_job_detail','myapp.delete_job_detail','myapp.add_job_detail','myapp.change_job_detail'}
        if 'myapp.add_job_detail' in curr_per_set.intersection(user_per_set):
            return True
        else:
            return False

7、编辑页细致说明

前文中我们已经介绍了简单的编辑页面的排版展示功能,接下来会更加详细地介绍编辑页面的排版,方便大家按照各自功能进行定制化开发

# filesets的样式及描述文案
    fieldsets = (
        (None, {
            'fields': ('JOB_NAME', 'JOB_TYPE', 'JOB_COMMENT')
        }),
        ('更多操作', {
            'classes': ('wide', 'extrapretty',),
            'fields': ('IN_PARA', 'OUT_PARA'),
        }),
    )
# 这里我们通过classes进行fileset的样式定制,常用的主要有 collaspe和wide,collaspe是将fieldset进行折叠,wide主要是增加水平空间,但这两个参数在simpleui中无用处(可能是我们的姿势不对)

# 添加文案说明
fieldsets = (
        (None, {
            'fields': ('JOB_NAME', 'JOB_TYPE', 'JOB_COMMENT')
        }),
        ('更多操作', {
            'classes': ('collaspe',),
            'fields': ('IN_PARA', 'OUT_PARA'),
            'description': '<h1>输入输出参数描述文案</h1>',
        }),
    )
# 这里可以发现 其实我们可以填充html语法,页面同样会直接进行渲染

# 那针对每个单元格的描述应该怎么操作呢?这里我们需要通过对models的help_text的属性添加,一般这个功能用于针对某个具体的字段的使用说明上
IN_PARA = models.CharField('输入参数定义',max_length=32,help_text=u'例如:按照这个样子')
# 多对多选择框 一般用于增加标签等方式上,但需要注意的是这个针对的many-to-many类型字段
## 这里务必要重写__str__方法,否则页面将不会展示具体内容
class job_tags(models.Model):
    title = models.CharField(max_length=30)
    def __str__(self):
        return self.title

class job_detail(models.Model):
    ... ...
    TAG = models.ManyToManyField(job_tags)
## 此时进行数据库迁移操作,系统会同时创建一张关系表

# admin.py中添加
filter_horizontal = ('TAG',)
# 列表页面如何显示 多对多 这种类型的字段,通过自定义函数进行返回详情以及描述
    def tag_list(self):
        return ', '.join([a.title for a in self.TAG.all()])
    tag_list.short_description = '标签'

# admin.py
list_display = ('JOB_TYPE', 'JOB_NAME','JOB_COMMENT',
              'IN_PARA','IN_PARA_COMMENT',
              'OUT_PARA','OUT_PARA_COMMENT','tag_list')
# 只读字段
readonly_fields = ("CREATED_BY",'CREATED_TIME',)
# 自动填充字段 eg:修改某条记录时,自动填充修改人为登录用户
# 时间字段处理,需要在model中指定,例如自动更新时间需要增加 auto_now属性,django使用的时间函数 timezone.now
    CREATED_BY = models.CharField('创建人',max_length=32) # 创建人
    CREATED_TIME = models.DateTimeField('创建时间',default=timezone.now) # 创建时间
    UPDATED_BY = models.CharField('更新人',max_length=32) # 更新人
    UPDATED_TIME = models.DateTimeField('更新时间',auto_now = True)  # 更新时间
# 获取登录人员信息,进行填充,需要重写save_model方法,同时记得设定成只读字段
    def save_model(self, request, obj, form, change):
        if change: # 判断当前是修改状态还是新增状态
            obj.UPDATED_BY = request.user.username
            obj.save()
        else:
            obj.CREATED_BY = request.user.username
            obj.UPDATED_BY = request.user.username
            obj.save()
    readonly_fields = ("CREATED_BY",'CREATED_TIME','UPDATED_BY','UPDATED_TIME',) 
## 这里需要注意的是 获取request人员属性的方法
# 级联修改 一对多关联 一般用于维度表配置展示
## 利用外键,在多的一方,字段指定外键即可,但定义一对多的关系时候需要指定删除方式
new_column = models.ForeignKey('Rela_table', on_delete=models.PROTECT)
## models.CASCADE 此为默认值,级联删除,会删除关联数据
## models.PROTECT 只要存在关联数据就不能删除
## models.DO_NOTHING 什么也不做
### 子表中定义外键
rela_id = models.ForeignKey("job_rela", on_delete=models.DO_NOTHING,default=9999, verbose_name="选择唯一一个父亲")
### 定义依赖的父表
class job_rela(models.Model):
    rela_name = models.CharField('依赖名称',max_length=128) # 任务名称
    rela_id = models.CharField('任务编号', max_length=32)  # 任务名称
    def __str__(self):
        return self.rela_name
### admin中增加显示该字段即可      

# 特殊的一对多,例如:行政区划
parent = models.ForeignKey('self', verbose_name='上级行政区划')
# 只显示当前登录用户自己的数据,超出范围不允许查看
    def get_queryset(self, request):
        qs = super(job_detail, self).get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(CREATED_BY=request.user.username)
# 列表页部分展示字段显示不同颜色
## model中定义字段颜色,通过函数定义
    def colored_name(self):
        if self.PRO_STATUS == 'Y':
            cl_name = 'red'
        else:
            cl_name = 'blue'
        return format_html(
            '<span style="color: {};">{}</span>',
            cl_name,
            self.PRO_STATUS,
        )
    colored_name.short_description = '状态'
## admin中直接引入即可 这里一个大括号代表一个入参

8、集成富文本编辑器实现数据字典展示功能

# 创建数据字典的model信息,包含主表以及字段表,其中主表跟字段表通过主外键进行一对多的关联
class dict_table(models.Model):
    table_name = models.CharField(max_length=64,verbose_name='表名称')
    table_comment = models.CharField(max_length=256,verbose_name='描述')
    table_short_desc = models.CharField(max_length=128,verbose_name='简述')
    create_time = models.DateTimeField(verbose_name='创建时间',default=timezone.now())
    owner = models.CharField(verbose_name='归属人',default='admin',max_length=64)
    update_time = models.DateTimeField(verbose_name='修改时间',auto_now=True)
    description = models.TextField(verbose_name='备注')
    def __str__(self):
        return self.table_name
    class Meta:
        verbose_name = '字典表'
        verbose_name_plural = '字典表'

class dict_columns(models.Model):
    table_id = models.ForeignKey('dict_table',on_delete=models.CASCADE,verbose_name='关联表主键')
    column_name = models.CharField(max_length=128,verbose_name='字段名称')
    column_comment = models.CharField(max_length=128,verbose_name='字段含义及说明')
    def __str__(self):
        return ''
    class Meta:
        verbose_name = '字段详情'
        verbose_name_plural = '字段详情'

# 添加测试记录
# admin文件中创建表名的列表页并且注册到路由中
class dict_columns(admin.TabularInline):
    model = dict_columns
    can_delete = False
    show_change_link = False
    extra = 1
    editable_fields = []
    list_display = ['column_name','column_comment']
    list_display_links = ()
    readonly_fields = ['column_name','column_comment']
    original = False
    def has_add_permission(self, request,obj=None):
        user_per_set = request.user.get_all_permissions() # 获取当前用户权限
        # 待判断的权限范围
        curr_per_set = {'myapp.view_dict_columns','myapp.delete_dict_columns','myapp.add_dict_columns','myapp.change_dict_columns'}
        if 'myapp.add_dict_columns' in curr_per_set.intersection(user_per_set):
            return True
        else:
            return False

@admin.register(dict_table)
class dict_table(admin.ModelAdmin):
    list_display = ('table_name', 'table_short_desc', 'create_time',
                    'owner')
    list_display_links = ('table_name',)
    list_filter = ('table_name',)
    def has_add_permission(self, request,obj=None):
        user_per_set = request.user.get_all_permissions() # 获取当前用户权限
        # 待判断的权限范围
        curr_per_set = {'myapp.view_dict_table','myapp.delete_dict_table','myapp.add_dict_table','myapp.change_dict_table'}
        if 'myapp.add_dict_table' in curr_per_set.intersection(user_per_set):
            return True
        else:
            return False

    def has_delete_permission(self, request, obj=None):
        return False

    save_as_continue = False  # 修改完成之后跳转到元素列表页面

    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['show_save_and_add_another'] = False
        extra_context['show_save_and_continue'] = False
        return super(dict_table, self).change_view(request, object_id,
                                                   form_url, extra_context=extra_context)

    fieldsets = (
        ('基本信息', {
            'fields': ('table_name', 'create_time', 'owner','update_time')
        }),
        ('说明', {
            'fields': ('description', )
        }),
    )
    readonly_fields = ("table_name", 'create_time', 'owner', 'update_time',)
    inlines = [dict_columns,]

9、自定义按钮实现导入导出功能

# 出处:参考simpleui官方文档
        # 增加自定义按钮
    actions = ['custom_button']

    def custom_button(self, request, queryset):
        pass

    # 显示的文本,与django admin一致
    custom_button.short_description = '测试按钮'
    # icon,参考element-ui icon与https://fontawesome.com
    custom_button.icon = 'fas fa-audio-description'

    # 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
    custom_button.type = 'danger'

    # 给按钮追加自定义的颜色
    custom_button.style = 'color:black;'

    # 链接按钮,设置之后直接访问该链接
    # 3中打开方式
    # action_type 0=当前页内打开,1=新tab打开,2=浏览器tab打开
    # 设置了action_type,不设置url,页面内将报错
    # 设置成链接类型的按钮后,custom_button方法将不会执行。

    custom_button.action_type = 1
    custom_button.action_url = 'http://www.baidu.com'

10、Echart组件引入以及页面个性化调整

# django admin 支持自定义template,大部分情况下我们是需要重新修改 change页面
class RecordAdmin(admin.ModelAdmin):
    change_form_template = 'admin/extras/record_change_form.html'
    ...
# 这个我们定义的页面需要继承 {% extends "admin/change_form.html" %}
# 在urls.py中添加一条对应的url信息以及对应的view函数进行处理渲染

四、应用部署步骤

Step1、安装ngnix

Step2、安装uwsgi

Step3、配置uwsgi

Step4、配置ngnix

Step5、启动服务


至此,我们已经基本上把django+simpleui的快速开发方式介绍了一遍,基本上能够满足一个创业团队或者小型团队的快速工具化的需求。其余基于django使用技巧以及部分源码解读也会在后续其他文章中放出。

相关推荐

“版本末期”了?下周平衡补丁!国服最强5套牌!上分首选

明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...

VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符&quot;

首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...

东营交警实名曝光一批酒驾人员名单 88人受处罚

齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...

Qt界面——搭配QCustomPlot(qt platform)

这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...

大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写

老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...

测试谷歌VS Code AI 编程插件 Gemini Code Assist

用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...

顾爷想知道第4.5期 国服便利性到底需优化啥?

前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...

掌握Visual Studio项目配置【基础篇】

1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...

还嫌LED驱动设计套路深?那就来看看这篇文章吧

随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...

Visual Studio Community 2022(VS2022)安装图文方法

直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...

Qt添加MSVC构建套件的方法(qt添加c++11)

前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...

Qt为什么站稳c++GUI的top1(qt c)

为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...

qt开发IDE应该选择VS还是qt creator

如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...

Qt 5.14.2超详细安装教程,不会来打我

Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...

Cygwin配置与使用(四)——VI字体和颜色的配置

简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...

取消回复欢迎 发表评论: