diff --git a/backend/application/settings.py b/backend/application/settings.py index 5d0fbc9..0f4be4a 100644 --- a/backend/application/settings.py +++ b/backend/application/settings.py @@ -45,7 +45,7 @@ INSTALLED_APPS = [ 'corsheaders', 'captcha', # 自定义app - 'apps.system', + 'apps.permission', ] MIDDLEWARE = [ @@ -275,7 +275,7 @@ AUTHENTICATION_BACKENDS = ( 'utils.backends.CustomBackend', 'utils.backends.SessionAuthentication', ) -AUTH_USER_MODEL = 'system.UserProfile' +AUTH_USER_MODEL = 'permission.UserProfile' # ================================================= # # ************** 登录验证码配置 ************** # diff --git a/backend/application/urls.py b/backend/application/urls.py index 0cd0d90..c551e84 100644 --- a/backend/application/urls.py +++ b/backend/application/urls.py @@ -25,7 +25,7 @@ from django.urls import re_path, include from django.views.static import serve from rest_framework.views import APIView -from apps.system.views import GetUserView, GetRouters +from apps.permission.views import GetUserView, GetRouters from utils.login import LoginView, LogoutView from utils.response import SuccessResponse diff --git a/backend/apps/system/__init__.py b/backend/apps/permission/__init__.py similarity index 100% rename from backend/apps/system/__init__.py rename to backend/apps/permission/__init__.py diff --git a/backend/apps/system/admin.py b/backend/apps/permission/admin.py similarity index 100% rename from backend/apps/system/admin.py rename to backend/apps/permission/admin.py diff --git a/backend/apps/permission/apps.py b/backend/apps/permission/apps.py new file mode 100644 index 0000000..283d777 --- /dev/null +++ b/backend/apps/permission/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class PermissionConfig(AppConfig): + name = 'permission' + verbose_name = "权限管理" diff --git a/backend/apps/system/filters.py b/backend/apps/permission/filters.py similarity index 100% rename from backend/apps/system/filters.py rename to backend/apps/permission/filters.py diff --git a/backend/apps/system/libs/__init__.py b/backend/apps/permission/libs/__init__.py similarity index 100% rename from backend/apps/system/libs/__init__.py rename to backend/apps/permission/libs/__init__.py diff --git a/backend/apps/permission/models/__init__.py b/backend/apps/permission/models/__init__.py new file mode 100644 index 0000000..1cbbbe2 --- /dev/null +++ b/backend/apps/permission/models/__init__.py @@ -0,0 +1,5 @@ +from ..models.dept import Dept +from ..models.menu import Menu +from ..models.post import Post +from ..models.role import Role +from ..models.users import UserProfile diff --git a/backend/apps/permission/models/dept.py b/backend/apps/permission/models/dept.py new file mode 100644 index 0000000..b933130 --- /dev/null +++ b/backend/apps/permission/models/dept.py @@ -0,0 +1,21 @@ +from django.db.models import SET_DEFAULT + +from utils import fields +from utils.BaseModels import CoreModel + + +class Dept(CoreModel): + name = fields.CharField(null=False, max_length=64, verbose_name="部门名称") + orderNum = fields.IntegerField(verbose_name="显示排序") + owner = fields.CharField(max_length=32, verbose_name="负责人") + phone = fields.CharField(max_length=32, verbose_name="联系电话") + email = fields.CharField(max_length=32, verbose_name="邮箱") + status = fields.BooleanField(default=False, verbose_name="部门状态") + parentId = fields.ForeignKey(to='Dept', on_delete=SET_DEFAULT, default=False, verbose_name="上级部门") + + class Meta: + verbose_name = '部门管理' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name}" diff --git a/backend/apps/permission/models/menu.py b/backend/apps/permission/models/menu.py new file mode 100644 index 0000000..f40c8cf --- /dev/null +++ b/backend/apps/permission/models/menu.py @@ -0,0 +1,42 @@ +from django.db.models import SET_DEFAULT + +from utils import fields +from utils.BaseModels import CoreModel + + +class Menu(CoreModel): + MENU_TYPE_CHOICES = ( + (0, "目录"), + (1, "菜单"), + (2, "按钮"), + ) + METHOD_CHOICE = ( + ('GET', 'GET'), + ('POST', 'POST'), + ('PUT', 'PUT'), + ('PATCH', 'PATCH'), + ('DELETE', 'DELETE'), + ('HEAD', 'HEAD'), + ('OPTIONS', 'OPTIONS'), + ('TRACE', 'TRACE'), + ) + name = fields.CharField(null=False, max_length=64, verbose_name="菜单名称") + icon = fields.CharField(max_length=64, verbose_name="菜单图标") + orderNum = fields.IntegerField(verbose_name="显示排序") + menuType = fields.IntegerField(choices=MENU_TYPE_CHOICES, verbose_name="菜单类型") + status = fields.BooleanField(default=False, verbose_name="菜单状态") + visible = fields.BooleanField(default=False, verbose_name="显示状态") + isFrame = fields.BooleanField(default=False, verbose_name="是否外链") + web_path = fields.CharField(max_length=128, verbose_name="前端路由地址") + component_path = fields.CharField(max_length=128, verbose_name="组件路径") + interface_path = fields.CharField(max_length=256, verbose_name="接口路径") + interface_method = fields.CharField(choices=METHOD_CHOICE, max_length=16, verbose_name="接口请求方式") + isCache = fields.BooleanField(default=False, verbose_name="是否外链") + parentId = fields.ForeignKey(to='Menu', on_delete=SET_DEFAULT, default=False, verbose_name="上级菜单") + + class Meta: + verbose_name = '菜单管理' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name}" diff --git a/backend/apps/permission/models/post.py b/backend/apps/permission/models/post.py new file mode 100644 index 0000000..932e0be --- /dev/null +++ b/backend/apps/permission/models/post.py @@ -0,0 +1,17 @@ +from utils import fields +from utils.BaseModels import CoreModel + + +class Post(CoreModel): + name = fields.CharField(null=False, max_length=64, verbose_name="岗位名称") + web_path = fields.CharField(max_length=32, verbose_name="岗位编码") + orderNum = fields.IntegerField(verbose_name="岗位顺序") + status = fields.BooleanField(default=False, verbose_name="岗位状态") + remark = fields.TextField(verbose_name="备注", help_text="备注") + + class Meta: + verbose_name = '岗位管理' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name}" diff --git a/backend/apps/permission/models/role.py b/backend/apps/permission/models/role.py new file mode 100644 index 0000000..9073373 --- /dev/null +++ b/backend/apps/permission/models/role.py @@ -0,0 +1,26 @@ +from utils import fields +from utils.BaseModels import CoreModel + + +class Role(CoreModel): + PURVIEW_CHOICES = ( + (0, "全部数据权限"), + (1, "自定数据权限"), + (2, "本部门数据权限"), + (3, "本部门及以下数据权限"), + (4, "仅本人数据权限"), + ) + name = fields.CharField(null=False, max_length=64, verbose_name="角色名称") + orderNum = fields.IntegerField(verbose_name="角色顺序") + status = fields.BooleanField(default=False, verbose_name="角色状态") + purview = fields.IntegerField(default=0, choices=PURVIEW_CHOICES, verbose_name="权限范围") + remark = fields.TextField(verbose_name="备注", help_text="备注") + dept = fields.ManyToManyField(to='Dept', verbose_name='数据权限-关联部门') + menu = fields.ManyToManyField(to='Menu', verbose_name='关联菜单权限') + + class Meta: + verbose_name = '角色管理' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name}" diff --git a/backend/apps/permission/models/users.py b/backend/apps/permission/models/users.py new file mode 100644 index 0000000..51a36de --- /dev/null +++ b/backend/apps/permission/models/users.py @@ -0,0 +1,41 @@ +from uuid import uuid4 + +from django.contrib.auth.models import UserManager, AbstractUser + +from utils import fields + + +class UserProfile(AbstractUser): + GENDER_CHOICES = ( + (0, "女"), + (1, "男"), + (2, "未知"), + ) + USER_TYPE_CHOICES = ( + (0, "后台用户"), + (1, "前台用户"), + ) + objects = UserManager() + username = fields.CharField(max_length=150, unique=True, db_index=True, verbose_name='用户账号') + secret = fields.CharField(max_length=255, default=uuid4, verbose_name='加密秘钥') + email = fields.CharField(max_length=255, verbose_name="邮箱") + mobile = fields.CharField(max_length=255, verbose_name="电话") + avatar = fields.TextField(verbose_name="头像") + name = fields.CharField(max_length=40, verbose_name="姓名") + gender = fields.IntegerField(default=2, choices=GENDER_CHOICES, verbose_name="性别") + remark = fields.TextField(verbose_name="备注") + user_type = fields.IntegerField(default=2, choices=GENDER_CHOICES, verbose_name="用户类型") + post = fields.ForeignKey(to='Post', verbose_name='关联岗位') + role = fields.ForeignKey(to='Role', verbose_name='关联角色') + dept = fields.ForeignKey(to='Dept', verbose_name='归属部门') + create_datetime = fields.CreateDateTimeField() + update_datetime = fields.UpdateDateTimeField() + + class Meta: + verbose_name = '用户管理' + verbose_name_plural = verbose_name + + def __str__(self): + if self.name: + return f"{self.username}({self.name})" + return f"{self.username}" diff --git a/backend/apps/system/serializers.py b/backend/apps/permission/serializers.py similarity index 80% rename from backend/apps/system/serializers.py rename to backend/apps/permission/serializers.py index 61a4371..1435bb2 100644 --- a/backend/apps/system/serializers.py +++ b/backend/apps/permission/serializers.py @@ -1,6 +1,6 @@ from rest_framework import serializers -from apps.system.models import UserProfile +from apps.permission.models import UserProfile class GetUserInfoSerializer(serializers.ModelSerializer): diff --git a/backend/apps/system/tasks.py b/backend/apps/permission/tasks.py similarity index 100% rename from backend/apps/system/tasks.py rename to backend/apps/permission/tasks.py diff --git a/backend/apps/system/tests.py b/backend/apps/permission/tests.py similarity index 100% rename from backend/apps/system/tests.py rename to backend/apps/permission/tests.py diff --git a/backend/apps/system/urls.py b/backend/apps/permission/urls.py similarity index 100% rename from backend/apps/system/urls.py rename to backend/apps/permission/urls.py diff --git a/backend/apps/system/views.py b/backend/apps/permission/views.py similarity index 98% rename from backend/apps/system/views.py rename to backend/apps/permission/views.py index 1e9e6ac..607f508 100644 --- a/backend/apps/system/views.py +++ b/backend/apps/permission/views.py @@ -3,9 +3,6 @@ import json from rest_framework.response import Response from rest_framework.views import APIView -from system.serializers import GetUserInfoSerializer -from utils.response import SuccessResponse - class GetUserView(APIView): """ @@ -18,6 +15,7 @@ class GetUserView(APIView): data = json.loads(data) return Response(data) + class GetRouters(APIView): """ 获取用户详细信息 diff --git a/backend/apps/system/apps.py b/backend/apps/system/apps.py deleted file mode 100644 index 5dc4d64..0000000 --- a/backend/apps/system/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class SystemConfig(AppConfig): - name = 'system' diff --git a/backend/apps/system/models/__init__.py b/backend/apps/system/models/__init__.py deleted file mode 100644 index e1e8fa6..0000000 --- a/backend/apps/system/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from ..models.users import UserProfile diff --git a/backend/apps/system/models/users.py b/backend/apps/system/models/users.py deleted file mode 100644 index 83d5cf9..0000000 --- a/backend/apps/system/models/users.py +++ /dev/null @@ -1,38 +0,0 @@ -from uuid import uuid4 - -from django.contrib.auth.models import UserManager, AbstractUser -from django.db import models - - -class UserProfile(AbstractUser): - GENDER_CHOICES = ( - ("女", "女"), - ("男", "男"), - ("未知", "未知"), - ) - objects = UserManager() - username = models.CharField(max_length=150, unique=True, db_index=True, - verbose_name='username', help_text='用户昵称') - secret = models.CharField(max_length=255, default=uuid4, verbose_name='加密秘钥') - email = models.CharField(max_length=255, null=True, blank=True, verbose_name="邮箱") - mobile = models.CharField(max_length=255, null=True, blank=True, verbose_name="电话") - avatar = models.TextField(null=True, blank=True, verbose_name="头像", help_text="头像") - - name = models.CharField(max_length=40, unique=False, null=True, - blank=True, verbose_name="姓名") - gender = models.CharField(max_length=2, default=GENDER_CHOICES[2][0], choices=GENDER_CHOICES, - verbose_name="性别", help_text="性别") - remark = models.TextField(null=True, blank=True, verbose_name="备注", help_text="备注") - create_datetime = models.DateTimeField(auto_now_add=True, null=True, blank=True, - verbose_name=u'创建时间', help_text=u"创建时间") - update_datetime = models.DateTimeField(auto_now=True, null=True, blank=True, - verbose_name=u'更新时间', help_text=u"更新时间") - - class Meta: - verbose_name = '用户' - verbose_name_plural = verbose_name - - def __str__(self): - if self.name: - return f"{self.username}({self.name})" - return f"{self.username}" diff --git a/backend/utils/BaseModels.py b/backend/utils/BaseModels.py new file mode 100644 index 0000000..6ac7e37 --- /dev/null +++ b/backend/utils/BaseModels.py @@ -0,0 +1,35 @@ +from django.db import models + +from .fields import CreateDateTimeField, DescriptionField, CreatorCharField, \ + ModifierCharField, UpdateDateTimeField + + +class BaseModel(models.Model): + """ + 标准抽象模型模型,可直接继承使用 + """ + description = DescriptionField() # 描述 + update_datetime = UpdateDateTimeField() # 修改时间 + create_datetime = CreateDateTimeField() # 创建时间 + + class Meta: + abstract = True + verbose_name = '基本模型' + verbose_name_plural = verbose_name + + +class CoreModel(models.Model): + """ + 核心标准抽象模型模型,可直接继承使用 + 增加审计字段, 覆盖字段时, 字段名称请勿修改, 必须统一审计字段名称 + """ + description = DescriptionField() # 描述 + creator = CreatorCharField() # 创建者 + modifier = ModifierCharField() # 修改者 + update_datetime = UpdateDateTimeField() # 修改时间 + create_datetime = CreateDateTimeField() # 创建时间 + + class Meta: + abstract = True + verbose_name = '核心模型' + verbose_name_plural = verbose_name diff --git a/backend/utils/fields.py b/backend/utils/fields.py new file mode 100644 index 0000000..64b8dc1 --- /dev/null +++ b/backend/utils/fields.py @@ -0,0 +1,286 @@ +from django.contrib.auth import get_user_model +from django.db import models +from django.db.models import SET_NULL + +from .string_util import uuid_8, uuid_16, uuid_32, uuid_36 + + +class IdField(models.CharField): + """ + id = IdField() + """ + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 8) + kwargs['primary_key'] = kwargs.get('primary_key', True) + kwargs['unique'] = kwargs.get('unique', True) + kwargs['db_index'] = kwargs.get('db_index', True) + kwargs['default'] = kwargs.get('default', uuid_8) + kwargs['null'] = kwargs.get('null', False) + kwargs['blank'] = kwargs.get('blank', False) + kwargs['verbose_name'] = kwargs.get('verbose_name', 'ID') + kwargs['help_text'] = kwargs.get('help_text', 'ID') + super().__init__(*args, **kwargs) + + +class UUID8Field(models.CharField): + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 8) + kwargs['default'] = kwargs.get('default', uuid_8) + kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID') + kwargs['help_text'] = kwargs.get('help_text', 'UUID') + super().__init__(*args, **kwargs) + + +class UUID16Field(models.CharField): + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 16) + kwargs['default'] = kwargs.get('default', uuid_16) + kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID') + kwargs['help_text'] = kwargs.get('help_text', 'UUID') + super().__init__(*args, **kwargs) + + +class UUID32Field(models.CharField): + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 32) + kwargs['default'] = kwargs.get('default', uuid_32) + kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID') + kwargs['help_text'] = kwargs.get('help_text', 'UUID') + super().__init__(*args, **kwargs) + + +class UUID36Field(models.CharField): + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 36) + kwargs['unique'] = kwargs.get('unique', True) + kwargs['default'] = kwargs.get('default', uuid_36) + kwargs['verbose_name'] = kwargs.get('verbose_name', 'UUID') + kwargs['help_text'] = kwargs.get('help_text', 'UUID') + super().__init__(*args, **kwargs) + + +class DescriptionField(models.TextField): + """ + description = DescriptionField() + """ + + def __init__(self, *args, **kwargs): + kwargs['default'] = kwargs.get('default', '') + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + kwargs['verbose_name'] = kwargs.get('verbose_name', '描述') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '描述') + super().__init__(*args, **kwargs) + + +class TextField(models.TextField): + """ + xxx = TextField() + """ + + def __init__(self, *args, **kwargs): + kwargs['default'] = kwargs.get('default', '') + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + super().__init__(*args, **kwargs) + + +class CharField(models.CharField): + """ + xxx = CharField() + """ + + def __init__(self, *args, **kwargs): + kwargs['default'] = kwargs.get('default', '') + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + super().__init__(*args, **kwargs) + + +class IntegerField(models.IntegerField): + """ + xxx = IntegerField() + """ + + def __init__(self, *args, **kwargs): + kwargs['default'] = kwargs.get('default', 0) + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + super().__init__(*args, **kwargs) + + +class BooleanField(models.BooleanField): + """ + xxx = BooleanField() + """ + + def __init__(self, *args, **kwargs): + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + super().__init__(*args, **kwargs) + + +class DateField(models.DateField): + """ + xxx = DateField() + """ + + def __init__(self, *args, **kwargs): + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(*args, **kwargs) + + +class DateTimeField(models.DateTimeField): + """ + xxx = DateTimeField() + """ + + def __init__(self, *args, **kwargs): + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(*args, **kwargs) + + +class ForeignKey(models.ForeignKey): + """ + xxx = ForeignKey() + """ + + def __init__(self, to=None, on_delete=None, related_name=None, related_query_name=None, limit_choices_to=None, + parent_link=False, to_field=None, db_constraint=False, **kwargs): + if on_delete is None: + on_delete = SET_NULL + if to_field is None: + to_field = 'id' + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(to, on_delete, related_name, related_query_name, limit_choices_to, parent_link, to_field, + db_constraint, **kwargs) + + +class OneToOneField(models.OneToOneField): + """ + xxx = OneToOneField() + """ + + def __init__(self, *args, on_delete=None, to_field=None, db_constraint=False, **kwargs): + if on_delete is None: + on_delete = SET_NULL + if to_field is None: + to_field = 'id' + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + kwargs['editable'] = kwargs.get('default', None) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(*args, on_delete=on_delete, to_field=to_field, db_constraint=db_constraint, **kwargs) + + +class ManyToManyField(models.ManyToManyField): + """ + xxx = ManyToManyField() + """ + + def __init__(self, *args, db_constraint=False, **kwargs): + kwargs['verbose_name'] = kwargs.get('verbose_name', '') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + super().__init__(*args, db_constraint=db_constraint, **kwargs) + + +class UserForeignKeyField(models.ForeignKey): + """ + user = UserForeignKeyField() + """ + + def __init__(self, to=None, on_delete=None, related_name=None, related_query_name=None, limit_choices_to=None, + parent_link=False, to_field=None, db_constraint=False, **kwargs): + if to is None: + to = get_user_model() + if to_field is None: + to_field = 'id' + if on_delete is None: + on_delete = SET_NULL + kwargs['verbose_name'] = kwargs.get('verbose_name', '关联的用户') + kwargs['help_text'] = kwargs.get('help_text', '') or kwargs.get('verbose_name', '关联的用户') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(to, on_delete, related_name, related_query_name, limit_choices_to, parent_link, to_field, + db_constraint, **kwargs) + + +class UpdateDateTimeField(models.DateTimeField): + """ + update_datetime = ModifyDateTimeField() + """ + + def __init__(self, verbose_name=None, name=None, auto_now=True, auto_now_add=False, **kwargs): + verbose_name = verbose_name or '修改时间' + kwargs['help_text'] = kwargs.get('help_text', '修改时间') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(verbose_name, name, auto_now, auto_now_add, **kwargs) + + +class CreateDateTimeField(models.DateTimeField): + """ + create_datetime = CreateDateTimeField() + """ + + def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=True, **kwargs): + verbose_name = verbose_name or '创建时间' + kwargs['help_text'] = kwargs.get('help_text', '创建时间') + kwargs['editable'] = kwargs.get('default', False) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['null'] = kwargs.get('null', True) + super().__init__(verbose_name, name, auto_now, auto_now_add, **kwargs) + + +class CreatorCharField(CharField): + """ + creator = CreatorCharField() + """ + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 255) + kwargs['null'] = kwargs.get('null', True) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['verbose_name'] = kwargs.get('verbose_name', '创建者') + kwargs['help_text'] = kwargs.get('help_text', '该记录的创建者') + super().__init__(*args, **kwargs) + + +class ModifierCharField(CharField): + """ + modifier = ModifierCharField() + """ + + def __init__(self, *args, **kwargs): + kwargs['max_length'] = kwargs.get('max_length', 255) + kwargs['null'] = kwargs.get('null', True) + kwargs['blank'] = kwargs.get('blank', True) + kwargs['verbose_name'] = kwargs.get('verbose_name', '修改者') + kwargs['help_text'] = kwargs.get('help_text', '该记录最后修改者') + super().__init__(*args, **kwargs)