mirror of
https://github.com/himool/HimoolERP.git
synced 2024-12-25 16:33:14 +08:00
feat: 调整
This commit is contained in:
parent
0708ad2c29
commit
519e25a682
21 changed files with 234 additions and 144 deletions
2
Pipfile
2
Pipfile
|
@ -15,6 +15,8 @@ pillow = "*"
|
|||
pendulum = "*"
|
||||
number-precision = "*"
|
||||
openpyxl = "*"
|
||||
uvicorn = "*"
|
||||
gunicorn = "*"
|
||||
|
||||
[dev-packages]
|
||||
autopep8 = "*"
|
||||
|
|
65
Pipfile.lock
generated
65
Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "b2ec2d879fcb44eef57c547812ae911702fc346b27259c3eba01f17e1f5d7765"
|
||||
"sha256": "b9799aee9ec6f6b223f92a087a9cdd7143d93c31b9effc4996968bcd9976d9cf"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -32,13 +32,21 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
|
||||
"version": "==21.2.0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3",
|
||||
"sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==8.0.3"
|
||||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:51284300f1522ffcdb07ccbdf676a307c6678659e1284f0618e5a774127a6a08",
|
||||
"sha256:e22c9266da3eec7827737cde57694d7db801fedac938d252bf27377cec06ed1b"
|
||||
"sha256:59304646ebc6a77b9b6a59adc67d51ecb03c5e3d63ed1f14c909cdfda84e8010",
|
||||
"sha256:d5a8a14da819a8b9237ee4d8c78dfe056ff6e8a7511987be627192225113ee75"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.2.9"
|
||||
"version": "==4.0"
|
||||
},
|
||||
"django-debug-toolbar": {
|
||||
"hashes": [
|
||||
|
@ -50,11 +58,11 @@
|
|||
},
|
||||
"django-extensions": {
|
||||
"hashes": [
|
||||
"sha256:50de8977794a66a91575dd40f87d5053608f679561731845edbd325ceeb387e3",
|
||||
"sha256:5f0fea7bf131ca303090352577a9e7f8bfbf5489bd9d9c8aea9401db28db34a0"
|
||||
"sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a",
|
||||
"sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.3"
|
||||
"version": "==3.1.5"
|
||||
},
|
||||
"django-filter": {
|
||||
"hashes": [
|
||||
|
@ -82,11 +90,11 @@
|
|||
},
|
||||
"drf-spectacular": {
|
||||
"hashes": [
|
||||
"sha256:af8a0c7c46e82c68aa70c474e3b23fa23bb16e4600270184af8230f5bd76aabb",
|
||||
"sha256:cbc43c8b67bd52a4ff31c4c950419be5257b8a4718cb966e7d2876371692edc1"
|
||||
"sha256:08357eefd71359ac522f3006c979f845ba09ec53638b84b8f9e920fa208dca92",
|
||||
"sha256:72bf0c122a51f1431d44570b8a68e5da1bc0e961d8a895ab3a83861fef65565d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.20.2"
|
||||
"version": "==0.21.0"
|
||||
},
|
||||
"et-xmlfile": {
|
||||
"hashes": [
|
||||
|
@ -96,6 +104,22 @@
|
|||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
"sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e",
|
||||
"sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==20.1.0"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6",
|
||||
"sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"inflection": {
|
||||
"hashes": [
|
||||
"sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417",
|
||||
|
@ -106,11 +130,11 @@
|
|||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:2b563117f3659a7f433dffe1371c88f52115b79133493f376f15724b9caa7efa",
|
||||
"sha256:e2d3601321ac74d38214e2853300ae740cd07e53d919a15862b8c71f9d840574"
|
||||
"sha256:2a0f162822a64d95287990481b45d82f096e99721c86534f48201b64ebca6e8c",
|
||||
"sha256:390713469ae64b8a58698bb3cbc3859abe6925b565a973f87323ef21b09a27a8"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==4.2.0"
|
||||
"version": "==4.2.1"
|
||||
},
|
||||
"number-precision": {
|
||||
"hashes": [
|
||||
|
@ -245,13 +269,6 @@
|
|||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.8.2"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c",
|
||||
"sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"
|
||||
],
|
||||
"version": "==2021.3"
|
||||
},
|
||||
"pytzdata": {
|
||||
"hashes": [
|
||||
"sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540",
|
||||
|
@ -322,6 +339,14 @@
|
|||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.1.1"
|
||||
},
|
||||
"uvicorn": {
|
||||
"hashes": [
|
||||
"sha256:d8c839231f270adaa6d338d525e2652a0b4a5f4c2430b5c4ef6ae4d11776b0d2",
|
||||
"sha256:eacb66afa65e0648fcbce5e746b135d09722231ffffc61883d4fac2b62fbea8d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.16.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
|
|
|
@ -9,7 +9,7 @@ from apps.data.models import *
|
|||
from apps.goods.models import *
|
||||
|
||||
|
||||
class WarehouseViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class WarehouseViewSet(ModelViewSet):
|
||||
"""仓库"""
|
||||
|
||||
serializer_class = WarehouseSerializer
|
||||
|
@ -68,7 +68,7 @@ class WarehouseViewSet(BaseViewSet, ReadWriteMixin):
|
|||
return Response(data=serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ClientViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class ClientViewSet(ModelViewSet):
|
||||
"""客户"""
|
||||
|
||||
serializer_class = ClientSerializer
|
||||
|
@ -95,7 +95,7 @@ class ClientViewSet(BaseViewSet, ReadWriteMixin):
|
|||
return Response(data={'number': number}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class SupplierViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class SupplierViewSet(ModelViewSet):
|
||||
"""供应商"""
|
||||
|
||||
serializer_class = SupplierSerializer
|
||||
|
@ -122,7 +122,7 @@ class SupplierViewSet(BaseViewSet, ReadWriteMixin):
|
|||
return Response(data={'number': number}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class AccountViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class AccountViewSet(ModelViewSet):
|
||||
"""结算账户"""
|
||||
|
||||
serializer_class = AccountSerializer
|
||||
|
@ -148,7 +148,7 @@ class AccountViewSet(BaseViewSet, ReadWriteMixin):
|
|||
return Response(data={'number': number}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ChargeItemViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class ChargeItemViewSet(ModelViewSet):
|
||||
"""收支项目"""
|
||||
|
||||
serializer_class = ChargeItemSerializer
|
||||
|
@ -159,7 +159,7 @@ class ChargeItemViewSet(BaseViewSet, ReadWriteMixin):
|
|||
queryset = ChargeItem.objects.all()
|
||||
|
||||
|
||||
class ClientCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class ClientCategoryViewSet(ModelViewSet):
|
||||
"""客户分类"""
|
||||
|
||||
serializer_class = ClientCategorySerializer
|
||||
|
@ -169,7 +169,7 @@ class ClientCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
|||
queryset = ClientCategory.objects.all()
|
||||
|
||||
|
||||
class SupplierCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class SupplierCategoryViewSet(ModelViewSet):
|
||||
"""供应商分类"""
|
||||
|
||||
serializer_class = SupplierCategorySerializer
|
||||
|
@ -179,7 +179,7 @@ class SupplierCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
|||
queryset = SupplierCategory.objects.all()
|
||||
|
||||
|
||||
class GoodsCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class GoodsCategoryViewSet(ModelViewSet):
|
||||
"""商品分类"""
|
||||
|
||||
serializer_class = GoodsCategorySerializer
|
||||
|
@ -189,7 +189,7 @@ class GoodsCategoryViewSet(BaseViewSet, ReadWriteMixin):
|
|||
queryset = GoodsCategory.objects.all()
|
||||
|
||||
|
||||
class GoodsUnitViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class GoodsUnitViewSet(ModelViewSet):
|
||||
"""商品单位"""
|
||||
|
||||
serializer_class = GoodsUnitSerializer
|
||||
|
|
|
@ -9,7 +9,7 @@ from apps.goods.models import *
|
|||
from apps.data.models import *
|
||||
|
||||
|
||||
class GoodsViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class GoodsViewSet(ModelViewSet):
|
||||
"""商品"""
|
||||
|
||||
serializer_class = GoodsSerializer
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.contrib import admin
|
|||
from apps.system.models import *
|
||||
|
||||
|
||||
admin.site.register([Team, PermissionType, Permission, Role, User])
|
||||
admin.site.register([Team, PermissionGroup, Permission, Role, User])
|
||||
|
|
|
@ -52,7 +52,7 @@ class UserSerializer(BaseSerializer):
|
|||
return instances
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['password'] = make_password(self.team.number)
|
||||
validated_data['password'] = make_password(validated_data['username'])
|
||||
return super().create(validated_data)
|
||||
|
||||
def save(self, **kwargs):
|
||||
|
|
|
@ -3,7 +3,7 @@ from apps.system.views import *
|
|||
|
||||
|
||||
router = BaseRouter()
|
||||
router.register('permission_types', PermissionTypeViewSet, 'permission_type')
|
||||
router.register('permission_groups', PermissionGroupViewSet, 'permission_group')
|
||||
router.register('roles', RoleViewSet, 'role')
|
||||
router.register('users', UserViewSet, 'user')
|
||||
router.register('user', UserActionViewSet, 'user_action')
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from django.contrib.auth.hashers import make_password, check_password
|
||||
from rest_framework_simplejwt.exceptions import TokenError
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
from extensions.common.base import *
|
||||
from extensions.common.schema import *
|
||||
from extensions.permissions import *
|
||||
from extensions.exceptions import *
|
||||
from extensions.viewsets import *
|
||||
|
@ -9,29 +11,54 @@ from apps.system.schemas import *
|
|||
from apps.system.models import *
|
||||
|
||||
|
||||
class PermissionTypeViewSet(GenericViewSet, ListModelMixin):
|
||||
"""权限类型"""
|
||||
class PermissionGroupViewSet(BaseViewSet, ListModelMixin):
|
||||
"""权限分组"""
|
||||
|
||||
serializer_class = PermissionTypeSerializer
|
||||
serializer_class = PermissionGroupSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
pagination_class = None
|
||||
ordering = ['id']
|
||||
queryset = PermissionType.objects.all()
|
||||
queryset = PermissionGroup.objects.all()
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().prefetch_related('permissions')
|
||||
|
||||
|
||||
class RoleViewSet(BaseViewSet, ReadWriteMixin):
|
||||
class RoleViewSet(ModelViewSet):
|
||||
"""角色"""
|
||||
|
||||
serializer_class = RoleSerializer
|
||||
permission_classes = [IsAuthenticated, IsManagerPermission]
|
||||
search_fields = ['name', 'remark']
|
||||
search_fields = ['name']
|
||||
queryset = Role.objects.all()
|
||||
|
||||
@transaction.atomic
|
||||
def perform_update(self, serializer):
|
||||
role = serializer.save()
|
||||
|
||||
class UserViewSet(BaseViewSet, ReadWriteMixin):
|
||||
# 同步用户权限
|
||||
users = role.users.prefetch_related('roles', 'roles__permissions').all()
|
||||
for user in users:
|
||||
permissions = {permission.code for role in user.roles.all()
|
||||
for permission in role.permissions.all()}
|
||||
user.permissions = list(permissions)
|
||||
else:
|
||||
User.objects.bulk_update(users, ['permissions'])
|
||||
|
||||
@transaction.atomic
|
||||
def perform_destroy(self, instance):
|
||||
users = instance.users.all()
|
||||
instance.delete()
|
||||
|
||||
# 同步用户权限
|
||||
for user in users.prefetch_related('roles', 'roles__permissions').all():
|
||||
permissions = {permission.code for role in user.roles.all()
|
||||
for permission in role.permissions.all()}
|
||||
user.permissions = list(permissions)
|
||||
else:
|
||||
User.objects.bulk_update(users, ['permissions'])
|
||||
|
||||
|
||||
class UserViewSet(ModelViewSet):
|
||||
"""用户"""
|
||||
|
||||
serializer_class = UserSerializer
|
||||
|
@ -56,7 +83,7 @@ class UserViewSet(BaseViewSet, ReadWriteMixin):
|
|||
"""重置密码"""
|
||||
|
||||
instance = self.get_object()
|
||||
instance.password = make_password(self.team.number)
|
||||
instance.password = make_password(self.user.username)
|
||||
instance.save(update_fields=['password'])
|
||||
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
@ -131,5 +158,5 @@ class UserActionViewSet(FunctionViewSet):
|
|||
|
||||
|
||||
__all__ = [
|
||||
'PermissionTypeViewSet', 'RoleViewSet', 'UserViewSet', 'UserActionViewSet',
|
||||
'PermissionGroupViewSet', 'RoleViewSet', 'UserViewSet', 'UserActionViewSet',
|
||||
]
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
|
||||
DEBUG = True
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
DATABASES = {
|
||||
'default': {
|
6
configs/gunicorn.py
Normal file
6
configs/gunicorn.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import multiprocessing
|
||||
|
||||
|
||||
bind = '0.0.0.0:8000'
|
||||
workers = multiprocessing.cpu_count() * 2 + 1
|
||||
reload = True
|
23
configs/nginx.conf
Normal file
23
configs/nginx.conf
Normal file
|
@ -0,0 +1,23 @@
|
|||
server {
|
||||
listen 12222;
|
||||
charset utf-8;
|
||||
gzip_static on;
|
||||
|
||||
location / {
|
||||
root /home/oms/frontend/dist/;
|
||||
index index.html index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://localhost:12223/api/;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /media/ {
|
||||
proxy_pass http://localhost:12223/media/;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
|
@ -27,4 +27,5 @@ python manage.py runscript init_permission
|
|||
python manage.py runscript create_user
|
||||
python manage.py runscript create_test_data
|
||||
python manage.py runserver
|
||||
gunicorn project.asgi:application -c configs/gunicorn.py -k uvicorn.workers.UvicornWorker
|
||||
```
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# 角色权限
|
||||
|
||||
- 权限列表:
|
||||
[/api/permission_types]
|
||||
[/api/permission_groups]
|
||||
|
||||
- 查询创建角色:
|
||||
[/api/roles/]
|
||||
|
|
|
@ -8,8 +8,8 @@ from django.conf import settings
|
|||
class BaseAuthentication(JWTAuthentication):
|
||||
|
||||
def authenticate(self, request):
|
||||
# if settings.DEBUG:
|
||||
# return User.objects.all().first(), {}
|
||||
if settings.DEBUG:
|
||||
return User.objects.all().first(), {}
|
||||
|
||||
if (header := self.get_header(request)) is None:
|
||||
return None
|
||||
|
|
|
@ -11,10 +11,7 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
|
|||
"""
|
||||
|
||||
from datetime import timedelta
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
from configs.django import *
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
|
@ -23,9 +20,6 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = 'django-insecure-v0ujuj#$uwo-cv&4@2=-0g3fi@av13=*g9%+jryd@5m568+93+'
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
|
||||
|
@ -46,18 +40,18 @@ INSTALLED_APPS = [
|
|||
'debug_toolbar',
|
||||
|
||||
'apps.system',
|
||||
'apps.data',
|
||||
'apps.goods',
|
||||
'apps.purchase',
|
||||
'apps.sales',
|
||||
'apps.stock_in',
|
||||
'apps.stock_out',
|
||||
'apps.stock_check',
|
||||
'apps.stock_transfer',
|
||||
'apps.flow',
|
||||
'apps.finance',
|
||||
'apps.statistic',
|
||||
'apps.option',
|
||||
# 'apps.data',
|
||||
# 'apps.goods',
|
||||
# 'apps.purchase',
|
||||
# 'apps.sales',
|
||||
# 'apps.stock_in',
|
||||
# 'apps.stock_out',
|
||||
# 'apps.stock_check',
|
||||
# 'apps.stock_transfer',
|
||||
# 'apps.flow',
|
||||
# 'apps.finance',
|
||||
# 'apps.statistic',
|
||||
# 'apps.option',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -92,19 +86,6 @@ TEMPLATES = [
|
|||
WSGI_APPLICATION = 'project.wsgi.application'
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
|
||||
from configs.database import DATABASES
|
||||
|
||||
# DATABASES = {
|
||||
# 'default': {
|
||||
# 'ENGINE': 'django.db.backends.sqlite3',
|
||||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
|
||||
|
||||
|
|
|
@ -32,16 +32,16 @@ urlpatterns = [
|
|||
*static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT),
|
||||
|
||||
path('api/', include('apps.system.urls')),
|
||||
path('api/', include('apps.data.urls')),
|
||||
path('api/', include('apps.goods.urls')),
|
||||
path('api/', include('apps.purchase.urls')),
|
||||
path('api/', include('apps.sales.urls')),
|
||||
path('api/', include('apps.stock_in.urls')),
|
||||
path('api/', include('apps.stock_out.urls')),
|
||||
path('api/', include('apps.stock_check.urls')),
|
||||
path('api/', include('apps.stock_transfer.urls')),
|
||||
path('api/', include('apps.flow.urls')),
|
||||
path('api/', include('apps.finance.urls')),
|
||||
path('api/', include('apps.statistic.urls')),
|
||||
path('api/', include('apps.option.urls')),
|
||||
# path('api/', include('apps.data.urls')),
|
||||
# path('api/', include('apps.goods.urls')),
|
||||
# path('api/', include('apps.purchase.urls')),
|
||||
# path('api/', include('apps.sales.urls')),
|
||||
# path('api/', include('apps.stock_in.urls')),
|
||||
# path('api/', include('apps.stock_out.urls')),
|
||||
# path('api/', include('apps.stock_check.urls')),
|
||||
# path('api/', include('apps.stock_transfer.urls')),
|
||||
# path('api/', include('apps.flow.urls')),
|
||||
# path('api/', include('apps.finance.urls')),
|
||||
# path('api/', include('apps.statistic.urls')),
|
||||
# path('api/', include('apps.option.urls')),
|
||||
]
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
asgiref==3.4.1
|
||||
attrs==21.2.0
|
||||
autopep8==1.6.0
|
||||
Django==3.2.9
|
||||
click==8.0.3
|
||||
Django==4.0
|
||||
django-debug-toolbar==3.2.2
|
||||
django-extensions==3.1.3
|
||||
django-extensions==3.1.5
|
||||
django-filter==21.1
|
||||
djangorestframework==3.12.4
|
||||
djangorestframework-simplejwt==5.0.0
|
||||
drf-spectacular==0.20.2
|
||||
drf-spectacular==0.21.0
|
||||
et-xmlfile==1.1.0
|
||||
gunicorn==20.1.0
|
||||
h11==0.12.0
|
||||
inflection==0.5.1
|
||||
jsonschema==4.2.0
|
||||
jsonschema==4.2.1
|
||||
number-precision==2021.1.30
|
||||
openpyxl==3.0.9
|
||||
pendulum==2.1.2
|
||||
|
@ -26,3 +29,4 @@ six==1.16.0
|
|||
sqlparse==0.4.2
|
||||
toml==0.10.2
|
||||
uritemplate==4.1.1
|
||||
uvicorn==0.16.0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from apps.system.models import PermissionType, Permission
|
||||
from apps.system.models import PermissionGroup, Permission
|
||||
|
||||
|
||||
PERMISSIONS = [
|
||||
|
@ -12,9 +12,9 @@ PERMISSIONS = [
|
|||
|
||||
|
||||
def run(*args):
|
||||
PermissionType.objects.all().delete()
|
||||
PermissionGroup.objects.all().delete()
|
||||
|
||||
for permission_type_item in PERMISSIONS:
|
||||
permission_type = PermissionType.objects.create(name=permission_type_item['name'])
|
||||
Permission.objects.bulk_create([Permission(type=permission_type, name=item['name'], code=item['code'])
|
||||
for item in permission_type_item['permissions']])
|
||||
for permission_group_item in PERMISSIONS:
|
||||
permission_group = PermissionGroup.objects.create(name=permission_group_item['name'])
|
||||
Permission.objects.bulk_create([Permission(group=permission_group, name=item['name'], code=item['code'])
|
||||
for item in permission_group_item['permissions']])
|
||||
|
|
|
@ -5,8 +5,8 @@ BASE_DIR = Path.cwd()
|
|||
|
||||
def run():
|
||||
create_nginx_config()
|
||||
create_database_config()
|
||||
create_uwsgi_config()
|
||||
create_django_config()
|
||||
create_gunicorn_config()
|
||||
|
||||
|
||||
def create_nginx_config():
|
||||
|
@ -16,8 +16,8 @@ def create_nginx_config():
|
|||
server_port = input('请输入 Django 启动端口:\n')
|
||||
static_path = BASE_DIR / 'frontend/dist/'
|
||||
|
||||
with open('/etc/nginx/sites-enabled/default', 'w') as file:
|
||||
file.write(f"""
|
||||
with open('configs/nginx.conf', 'w') as file:
|
||||
file.write(f"""\
|
||||
server {{
|
||||
listen {listen_port};
|
||||
charset utf-8;
|
||||
|
@ -44,17 +44,40 @@ server {{
|
|||
""")
|
||||
|
||||
|
||||
def create_database_config():
|
||||
is_need_create = input('是否需要创建 数据库 配置文件吗? (y/n)\n')
|
||||
if is_need_create == 'y':
|
||||
database_type = input('配置数据库: (sqlite: 0, mysql: 1)\n')
|
||||
if database_type == '1':
|
||||
host = input('请输入 host:\n')
|
||||
user = input('请输入 user:\n')
|
||||
passowrd = input('请输入 passowrd:\n')
|
||||
database_name = input('请输入 数据库名称:\n')
|
||||
def create_django_config():
|
||||
is_production_environment = input('是否为生产环境? (y/n)\n')
|
||||
if is_production_environment == 'y':
|
||||
file_content = """\
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
|
||||
DEBUG = False
|
||||
|
||||
"""
|
||||
else:
|
||||
file_content = """\
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
|
||||
DEBUG = True
|
||||
|
||||
"""
|
||||
|
||||
database_type = input('配置数据库: (sqlite: 0, mysql: 1)\n')
|
||||
if database_type == '1':
|
||||
host = input('请输入 host:\n')
|
||||
user = input('请输入 user:\n')
|
||||
passowrd = input('请输入 passowrd:\n')
|
||||
database_name = input('请输入 数据库名称:\n')
|
||||
|
||||
file_content += f"""
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
|
||||
text = f"""
|
||||
DATABASES = {{
|
||||
'default': {{
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
|
@ -67,10 +90,10 @@ DATABASES = {{
|
|||
}}
|
||||
}}
|
||||
"""
|
||||
else:
|
||||
text = f"""
|
||||
from pathlib import Path
|
||||
|
||||
else:
|
||||
file_content += f"""
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
DATABASES = {{
|
||||
|
@ -80,34 +103,23 @@ DATABASES = {{
|
|||
}}
|
||||
}}
|
||||
"""
|
||||
with open(BASE_DIR / 'configs/database.py', 'w') as file:
|
||||
file.write(text)
|
||||
with open(BASE_DIR / 'configs/django.py', 'w') as file:
|
||||
file.write(file_content)
|
||||
|
||||
|
||||
def create_uwsgi_config():
|
||||
is_need_create = input('是否需要创建 uwsgi 配置文件吗? (y/n)\n')
|
||||
def create_gunicorn_config():
|
||||
is_need_create = input('是否需要创建 Gunicorn 配置文件吗? (y/n)\n')
|
||||
if is_need_create == 'y':
|
||||
http_port = input('请输入项目端口:\n')
|
||||
pidfile_path = BASE_DIR / 'logs/master.pid'
|
||||
daemonize_path = BASE_DIR / 'logs/worker.log'
|
||||
pidfile_path.touch()
|
||||
daemonize_path.touch()
|
||||
bind_address = input('请输入 Django 启动地址:\n')
|
||||
|
||||
with open(BASE_DIR / 'configs/uwsgi.ini', 'w') as file:
|
||||
file.write(f"""
|
||||
[uwsgi]
|
||||
chdir = {BASE_DIR}
|
||||
module = project.wsgi:application
|
||||
master = True
|
||||
processes = 8
|
||||
max-requests = 5000
|
||||
harakiri = 60
|
||||
http = :{http_port}
|
||||
uid = root
|
||||
gid = root
|
||||
pidfile = {pidfile_path}
|
||||
daemonize = {daemonize_path}
|
||||
vacuum = True
|
||||
with open('configs/gunicorn.py', 'w') as file:
|
||||
file.write(f"""\
|
||||
import multiprocessing
|
||||
|
||||
|
||||
bind = '{bind_address}'
|
||||
workers = multiprocessing.cpu_count() * 2 + 1
|
||||
reload = True
|
||||
""")
|
||||
|
||||
|
||||
|
|
|
@ -14,10 +14,12 @@ for app in (project_path / 'apps').iterdir():
|
|||
if file.is_file() and file.name != '__init__.py':
|
||||
file.unlink()
|
||||
|
||||
# Python3 manage.py
|
||||
# Python3 manage.py
|
||||
print('构建数据库')
|
||||
os.chdir(project_path)
|
||||
os.system('python manage.py reset_db --noinput')
|
||||
os.system('python manage.py makemigrations')
|
||||
os.system('python manage.py migrate')
|
||||
|
||||
print('初始化权限')
|
||||
os.system('python manage.py runscript init_permission')
|
||||
|
|
Loading…
Reference in a new issue