准备环境
安装MySQL
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
#如果需要安装MySQL 5.7 修改 /etc/yum.repo.d/mysql-community.repo 把版本 enable gpgcheck 改为 0 1 把要安装的版本改为 1 1
yum -y install mysql-community-server
systemctl start mysqld
cat /var/log/mysql.log |grep password #查看密码
alter user root@localhost identified by ‘你的密码’
create database django default charset utf8; #创建数据库
1
2
3
4
5
6
7
8
9
安装Redis
yum -y install gcc-c++
wget https://download.redis.io/releases/redis-6.0.8.tar.gz
tar xzf redis-6.0.8.tar.gz
cd redis-6.0.8
make && make install
1
2
3
4
5
注释掉以下内容
路径:redis-6.0.8/utils/install_server.sh
#_pid_1_exe=“KaTeX parse error: Expected 'EOF', got '#' at position 28: … /proc/1/exe)" #̲if [ "{_pid_1_exe##*/}” = systemd ]
#then
#fi
1
2
3
4
5
6
7
脚本安装
sh ./install _server.sh
1
直接回车 默认为6379端口
直接回车 配置文件默认路径/etc/redis/6379.conf
直接回车 日志默认路径/var/log/redis_6379.log
直接回车 数据库目录文件 /var/lib/redis/6379
redis添加密码
vim /etc/redis/6379.conf
…
requirepass 123456
…
redis杀掉重新启动
redis-cli shutdown
redis-server /etc/redis/6379.conf
1
2
安装Nginx
wget https://nginx.org/download/nginx-1.20.1.tar.gz
yum install -y pcre-devel pcre zlib zlib-devel openssl openssl-devel wget gcc gcc-c++ unzip
useradd -s /sbin/nologin nginx
tar -xvf nginx-1.20.1.tar.gz
cd nginx-1.20.1/
sed -i ‘49s/nginx/Microsoft-IIS/’ src/http/ngx_http_header_filter_module.c
sed -i ‘50s/: /: Microsoft-IIS/’ src/http/ngx_http_header_filter_module.c
sed -i ‘51s/: /: Microsoft-IIS/’ src/http/ngx_http_header_filter_module.c
./configure --user=nginx --group=nginx --prefix=/opt/nginx --with-http_ssl_module --with-http_stub_status_module --with-stream --with-http_realip_module --with-http_realip_module
make && make install
cp -r /opt/nginx/sbin/nginx /usr/sbin/nginx
mkdir /opt/nginx/conf.d
mv /opt/nginx/conf/nginx.conf /opt/nginx/conf/nginx.bak.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
修改 nginx 配置文件
vim /opt/nginx/conf/nginx.conf
worker_processes auto;
error_log logs/error.log error;
pid logs/nginx.pid;
events {
worker_connections 65535;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
keepalive_timeout 60;
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Max-Age '3628800';
add_header Access-Control-Allow-Credentials 'true';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header Access-Control-Allow-Methods 'GET,POST,PUT,OPTIONS';
underscores_in_headers on;
client_header_buffer_size 32k;
client_body_buffer_size 20m;
client_max_body_size 120M;
client_header_timeout 1m;
client_body_timeout 1m;
proxy_connect_timeout 600;
proxy_read_timeout 600;
proxy_send_timeout 600;
large_client_header_buffers 4 32k;
fastcgi_buffers 4 128k;
fastcgi_buffer_size 128k;
fastcgi_busy_buffers_size 256k;
server_tokens off;
tcp_nopush on;
tcp_nodelay on;
sendfile on;
gzip on; #开启gzip
#gzip_static on;
gzip_vary on;
gzip_min_length 1k;
gzip_buffers 8 32k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_proxied any;
gzip_types application/javascript application/json text/css image/png;
real_ip_header X-Real-IP;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
include /opt/nginx/conf.d/*.conf;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
创建一个django.conf(/opt/nginx/conf.d/django.conf)
server {
listen 80;
server_name localhost;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3210;
uwsgi_read_timeout 180s;
uwsgi_connect_timeout 180s; #
uwsgi_send_timeout 180s; #默认60s;
index index.html index.htm;
}
location /static {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias /opt/app/static/; #写项目的的静态路径,如果不开启debug 执行python3 manage.py collectstatic 有自动创建项目下static路径
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
##注: 先不要启动nginx
创建一个Django项目
yum install python3-devel mysql-devel libcurl-devel
mkdir /opt/app #新建
python3 -m venv /opt/app/venv #创建虚拟环境
source /opt/app/venv/bin/activate #进入虚拟环境 (windows下venv\Scripts\activate)
pip install django #安装django
pip simpleui #安装simpleui
pip3 install django_redis #安装django-redis
pip3 install mysqlclient #mysql客户端
pip install django-cors-headers #跨域请求头
django-admin startproject webapp #创建新的Django项目
1
2
3
4
5
6
7
8
9
10
安装Uwsgi
pip install uwsgi #安装 uwsgi
1
添加uwsgi文件 到项目下
vim /opt/app/webapp/webapp/uwsgi.ini
[uwsgi]
socket = 127.0.0.1:8871
chdir = /opt/app
module = webapp.wsgi
master = true
processes = 4 #4进程
enable-threads = true #允许多线程
#threads = 1 #默认1线程
vacuum = true #退出后清理目录
max-requests = 5000
harakiri = 180 #服务器响应时间
socket-timeout = 180 #连接超时
pidfile = app.wsgi.pid #启动的pid
daemonize =/var/log/uwsgi.log #日志
env = LANG=en_US.UTF-8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
启动命令
uwsgi --ini uwsgi #初始化启动
uwsgi --reload uwsig #重启uwsgi配置
#如果修改了Django项目模块只需:
uwsgi --reload app.wsgi.pid
1
2
3
4
修改配置文件引入SimpleUI
INSTALLED_APPS = [
‘simpleui’, #添加simpleui
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
…
]
#配置请求头跨域
MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘corsheaders.middleware.CorsMiddleware’, #放在 SessionMiddleware 下面
‘django.middleware.common.CommonMiddleware’,
#‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.mysql’,
‘NAME’:‘django’,
‘HOST’:‘127.0.0.1’,
‘USER’:‘root’,
‘PASSWORD’:‘qweasd#.a434’,
‘PORT’:‘3306’,
}
}
#Redis 配置
CACHES = {
“default”: {
“BACKEND”: “django_redis.cache.RedisCache”,
“LOCATION”: “redis://127.0.0.1:6379”,
“OPTIONS”: {
“CLIENT_CLASS”: “django_redis.client.DefaultClient”,
“PASSWORD”:‘123456’,
“SERIALIZER”: “django_redis.serializers.json.JSONSerializer”,
}
}
}
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
‘DELETE’,
‘GET’,
‘OPTIONS’,
‘PATCH’,
‘POST’,
‘PUT’,
)
CORS_ALLOW_HEADERS = (
‘accept-encoding’,
‘authorization’,
‘content-type’,
‘dnt’,
‘origin’,
‘user-agent’,
‘x-csrftoken’,
‘x-requested-with’,
)
LANGUAGE_CODE = ‘zh-hans’
TIME_ZONE = ‘Asia/Shanghai’
USE_TZ = False # 这里务必调整为False,否则时区设置无效
DEBUG = True
STATIC_ROOT = os.path.join(BASE_DIR, “static”)
#simpleui静态资源更改为离线模式
SIMPLEUI_STATIC_OFFLINE = True # 离线模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
2. 收集静态资源
cd /opt/app/webapp
python manage.py collectstatic
1
2
3.启动测试
cd /opt/app/webapp
python manager.py runserver 0.0.0.0:80
1
2
显示成功页面 ---- 显示中文
INSTALLED_APPS = [
‘simpleui’, #添加simpleui
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘myapp’, # 添加到末尾
]
1
2
3
4
5
6
7
8
9
10
11
2. 添加app的模型model
vim /opt/app/webapp/myapp/models.py
1
from django.db import models
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.TextField()('任务描述',max_length=128) # 任务描述
IN_PARA = models.CharField('输入参数定义',max_length=32) # 输入参数定义 参数使用英文逗号分隔
IN_PARA_COMMENT = models.TextField()('输入参数描述',max_length=1024) # 输入参数描述
OUT_PARA = models.CharField('输出参数定义',max_length=32) # 输出参数定义 参数使用英文逗号分隔
OUT_PARA_COMMENT = models.TextField()('输出参数描述',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:开发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
3. 执行数据库迁移
python manage.py makemigrations
python manage.py migrate
1
2
4. 修改myapp/admin.py文件 注册到admin后台以及job_detail 内容的显示
vim /opt/app/webapp/myapp/admin.py
1
from django.contrib import admi
from myapp.models import job_detail
#更改 admin的title header 和名称
admin.site.site_header = ‘项目管理’
admin.site.site_title = ‘管理系统’
admin.site.index_title = u’管理系统
@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 = 10
# 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’,)
#增加自定义按钮
actions = ['custom_button','upload_file']
fieldsets=(
('基本信息',{
'fields': ('JOB_TYPE', 'JOB_NAME','JOB_COMMENT',
'IN_PARA','IN_PARA_COMMENT',
'OUT_PARA','OUT_PARA_COMMENT')
}),
('STATUS',{
'fields': ('PRO_STATUS',)
}),
('参数描述', {
'fields': ('REQUIREMENTS2',)
}),
('任务描述', {
'fields': ('JOB_COMMENT','KIDS')
}),
)
#导出数据
def custom_button(self,request,queryset):
response = HttpResponse(content_type='text/csv',charset='GBK')
time_now = time.strftime('%Y%m%d')
#自定义命名
filename = 'job_detail'+time_now
# 添加header,attachment表示以附件方式下载
response['Content-Disposition'] = f'attachment; filename="{filename}.csv"'
#生成一个对象
writer = csv.writer(response)
#定义表头
writer.writerow(["创建人","任务描述","xxxx"...]) #补充完整要导出的字段名称
#添加数据
for i in queryset.values():
writer.writerow([i['CREATED_BY'],i['JOB_TYPE'],i['JOB_NAME']....]) #补充完整数据库导出查询字段
# 响应下载
return response
custom_button.short_description='导出数据'
# icon,参考element-ui icon与https://fontawesome.com
custom_button.icon='fas fa-audio-description'
# 给按钮追加自定义的颜色
custom_button.style='color:black;'
# 指定element-ui的按钮类型,参考https://element.eleme.cn/#/zh-CN/component/button
custom_button.type='info'
#上传csv文件
def upload_file(self, request,queryset):
# 这里的upload 就是和params中配置的key一样
upload= request.FILES[‘upload’]
print(upload)
upload_file.short_description = ‘上传数据’
upload_file.type = ‘success’
upload_file.icon = ‘el-icon-upload’
upload_file.enable = True
upload_file.layer = {
‘params’: [{
‘type’: ‘file’,
‘key’: ‘upload’,
‘label’: ‘CSV文件’
}]
# def has_add_permission(self, request):
# # 禁用添加按钮
# return True
# def has_delete_permission(self, request, obj=None):
# # 禁用删除按钮
# return Fals
#只读字段
readonly_fields=("CREATED_BY",'CREATED_TIME','UPDATED_BY','UPDATED_TIME',
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
5. 修改SimpleUI自定义菜单栏(修改项目 setting.py)
#在文件末尾添加
#菜单栏,图片查考
SIMPLEUI_CONFIG = {
‘system_keep’: False, # 关闭系统菜单
‘menu_display’: [‘任务管理’, ‘信息管理’,‘网站管理’, ‘认证和授权’],
‘dynamic’: True, # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
‘menus’: [{
‘app’: ‘myapp’,
‘name’: ‘项目管理’,
‘icon’: ‘fab fa-app-store-ios’,
‘models’: [{
‘name’: ‘JOB’,
‘icon’: ‘fa fa-user’,
‘url’: ‘myapp/job_detail/’
}, {
‘name’: ‘XXXXXXX’,
‘icon’: ‘el-icon-video-camera-solid’,
‘url’: ‘myapp/event/’,
}]},
{
‘app’: ‘xxx’,
‘name’: ‘网站管理’,
‘icon’: ‘fa fa-th-list’,
‘models’: [{
‘name’: ‘XXXX’,
‘icon’: ‘el-icon-message-solid’,
‘url’: ‘XXX/XXXX/’
}, {
‘name’: ‘OKOK’,
‘icon’: ‘el-icon-picture’,
‘url’: ‘XXXXX’
}
]},
{
‘app’: ‘auth’,
‘name’: ‘认证和授权’,
‘icon’: ‘fas fa-shield-alt’,
‘models’: [{
‘name’: ‘用户’,
‘icon’: ‘far fa-user’,
‘url’: ‘auth/user/’
}, {
‘name’: ‘组’,
‘icon’: ‘fas fa-users-cog’,
‘url’: ‘auth/group/’,
}]
}]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
6. 测试是否菜单栏实现
python manager.py runserver 0.0.0.0:80
http://127.0.0.1:80/admin
1
2
最后:项目上线启动
#启动nginx
nginx
#redis 此处没有使用到
#启动uwsgi
uwsgi --ini uwsgi.ini