def gen_route(project_name_settings, user_label_list): init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] path_list = [] gen_labels = SYS_LABELS + user_label_list gen_labels = [one for one in gen_labels if one != "contenttypes"] for one in django.apps.apps.get_models(): if one._meta.app_label in gen_labels: model_name = trans(one._meta.verbose_name) url = "/xadmin/" + get_lower_case_name(one._meta.model.__name__) one = "{" + f""" name: '{model_name}', icon: 'smile', path: '{url}', component: './AutoGenPage/{one._meta.model.__name__}List', """ + "}" # print(one) path_list.append(one) inner_before_list = """ [ { name: '首页', path: '/xadmin/index', icon: 'dashboard', component: './TyAdminBuiltIn/DashBoard' }, """ inner_after_list = """ ,{ name: 'Tyadmin内置', icon: 'VideoCamera', path: '/xadmin/sys', routes: [ { name: 'TyAdmin日志', icon: 'smile', path: '/xadmin/sys/ty_admin_sys_log', component: './TyAdminBuiltIn/TyAdminSysLogList' }, { name: 'TyAdmin验证', icon: 'smile', path: '/xadmin/sys/ty_admin_email_verify_record', component: './TyAdminBuiltIn/TyAdminEmailVerifyRecordList' } ] }] """ with open(f'{settings.BASE_DIR}/tyadmin_api/menu.json', 'w', encoding='utf-8') as fw: fw.write(inner_before_list + ",".join(path_list) + inner_after_list) with open(f'{settings.BASE_DIR}/tyadmin/config/auto_menu.json', 'w', encoding='utf-8') as fw: fw.write(inner_before_list + ",".join(path_list) + inner_after_list)
def migration_from_xadmin(project_name_settings): init_django_env(project_name_settings) import xadmin for one, item in xadmin.site._registry.items(): print(one._meta.object_name) print(item.list_display) print(item.list_filter) print(item.search_fields)
def gen_view(project_name_settings): init_django_env(project_name_settings) import django from django.conf import settings model_list = [] app_name = "tyadmin_api" model_search_dict = {} app_model_import_dict = {} sys_label = ['admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django'] for one in django.apps.apps.get_models(): model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label not in sys_label: try: app_model_import_dict[app_label].append(model_name) except KeyError: app_model_import_dict[app_label] = [model_name] search_list = [] model_list.append(model_name) for filed in one.objects.model._meta.fields: name = filed.name ver_name = filed.verbose_name if isinstance(filed, CharField): search_list.append('"' + name + '"') elif isinstance(filed, CharField): search_list.append('"' + name + '"') model_search_dict[model_name] = search_list serializers_list = [one + "Serializer" for one in model_list] filters_list = [one + "Filter" for one in model_list] viewset_txt = f""" from rest_framework import viewsets from tyadmin_api.custom import XadminViewSet $model_import占位$ from {app_name}.auto_serializers import {", ".join(serializers_list)} from {app_name}.auto_filters import {", ".join(filters_list)} """ model_import_rows = [] print(app_model_import_dict) for app, m_list in app_model_import_dict.items(): txt = f'from {app}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) viewset_txt = viewset_txt.replace("$model_import占位$", "".join(model_import_rows)) for model_name in model_list: viewset_txt += f""" class {model_name}ViewSet(XadminViewSet): serializer_class = {model_name}Serializer queryset = {model_name}.objects.all() filter_class = {model_name}Filter search_fields = [{",".join(model_search_dict[model_name])}] """ if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_views.py'): print("已存在views跳过") else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_views.py', 'w', encoding='utf-8') as fw: fw.write(viewset_txt)
def handle(self, *args, **options): try: setting_value = options['settings'] except KeyError: raise ValueError("请设置settings") init_django_env(setting_value) # print(settings.BASE_DIR) print("###"*20) init_tyadmin_api(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), settings.BASE_DIR) init_tyadmin(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), settings.BASE_DIR) print("###"*20)
def gen_route(project_name_settings): init_django_env(project_name_settings) import django from django.conf import settings path_list = [] sys_label = [ 'admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django' ] for one in django.apps.apps.get_models(): if one._meta.app_label not in sys_label: url = "/xadmin/" + get_lower_case_name(one._meta.model.__name__) one = "{" + f""" name: '{one._meta.verbose_name}', icon: 'smile', path: '{url}', component: './AutoGenPage/{one._meta.model.__name__}List', """ + "}" # print(one) path_list.append(one) inner_before_list = """ [ { name: '首页', path: '/xadmin/index', icon: 'dashboard', component: './TyAdminBuiltIn/DashBoard' }, """ inner_after_list = """ ,{ name: 'Tyadmin内置', icon: 'VideoCamera', path: '/xadmin/sys', routes: [ { name: 'TyAdmin日志', icon: 'smile', path: '/xadmin/sys/ty_admin_sys_log', component: './TyAdminBuiltIn/TyAdminSysLogList' }, { name: 'TyAdmin验证', icon: 'smile', path: '/xadmin/sys/ty_admin_email_verify_record', component: './TyAdminBuiltIn/TyAdminEmailVerifyRecordList' } ] }] """ with open(f'{settings.BASE_DIR}/tyadmin_api/menu.json', 'w') as fw: fw.write(inner_before_list + ",".join(path_list) + inner_after_list) with open(f'{settings.BASE_DIR}/tyadmin/config/auto_menu.json', 'w') as fw: fw.write(inner_before_list + ",".join(path_list) + inner_after_list)
def gen_table_display(project_name_settings, list_display, focus_model): init_django_env(project_name_settings) import django for one in django.apps.apps.get_models(): if one._meta.model.__name__ == focus_model: print("{") for field in one.objects.model._meta.fields: if field.name in list_display: pass else: print("""%s: { show: false, },""" % (field.name)) print("}")
def handle(self, *args, **options): try: setting_value = options['settings'] except KeyError: raise ValueError("请设置settings") init_django_env(setting_value) # print(settings.BASE_DIR) print("###" * 20) init_tyadmin_api( os.path.dirname(os.path.dirname(os.path.dirname(__file__))), settings.BASE_DIR) init_tyadmin( os.path.dirname(os.path.dirname(os.path.dirname(__file__))), settings.BASE_DIR) print("###" * 20) loop = asyncio.get_event_loop() loop.run_until_complete(gen_all(setting_value, SYS_LABELS, True)) loop.close()
def gen_url(project_name_settings): init_django_env(project_name_settings) import django from django.conf import settings model_list = [] model_fk_dict = {} app_model_import_dict = {} sys_label = [ 'admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django' ] for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label not in sys_label: model_list.append(model_name) url_txt = f"""from tyadmin_api import auto_views from django.urls import re_path, include, path from rest_framework.routers import DefaultRouter router = DefaultRouter(trailing_slash=False) """ for model_name in model_list: url_txt += f""" router.register('{get_lower_case_name(model_name)}/?', auto_views.{model_name}ViewSet) """ url_txt += """ urlpatterns = [ re_path('^', include(router.urls)), ] """ if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_url.py'): print("已存在urls跳过") else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_url.py', 'w', encoding='utf-8') as fw: fw.write(url_txt)
def gen_url(project_name_settings, user_label_list): init_django_env(project_name_settings) import django from django.conf import settings model_list = [] model_fk_dict = {} app_model_import_dict = {} gen_labels = SYS_LABELS + user_label_list for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label in gen_labels: model_list.append(model_name) url_txt = f"""from tyadmin_api import auto_views from django.urls import re_path, include, path from rest_framework.routers import DefaultRouter router = DefaultRouter(trailing_slash=False) """ for model_name in model_list: url_txt += f""" router.register('{get_lower_case_name(model_name)}', auto_views.{model_name}ViewSet) """ url_txt += """ urlpatterns = [ re_path('^', include(router.urls)), ] """ # if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_url.py'): # print("已存在urls跳过") # else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_url.py', 'w', encoding='utf-8') as fw: fw.write(url_txt)
def gen_serializer(project_name_settings, user_label_list): init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] model_list = [] model_fk_dict = {} model_many_2_many_dict = {} app_model_import_dict = {} gen_labels = SYS_LABELS + user_label_list finish_model_list = [] finish_many_list = [] for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label import_path = get_model_import_path(one) if app_label in gen_labels: fk_field_list = [] try: app_model_import_dict[import_path].append(model_name) except KeyError: app_model_import_dict[import_path] = [model_name] for field in one.objects.model._meta.fields: name = field.name ver_name = field.verbose_name if isinstance(field, ForeignKey): field_object_name = field.target_field.model._meta.object_name fk_field_list.append(name + "$分割$" + field_object_name) model_fk_dict[model_name] = fk_field_list model_list.append(model_name) many_2_many_list = [] for field in one.objects.model._meta.many_to_many: name = field.name rela_model = field.related_model._meta.object_name # print("&&&" * 30) # print(one._meta.app_label, one._meta.model.__name__, rela_model) many_2_many_list.append(name + "$分割$" + rela_model) # print("&&&" * 30) model_many_2_many_dict[one._meta.model.__name__] = many_2_many_list # status_text = serializers.CharField(source="status.text", read_only=True) # print(model_fk_dict) # print(model_many_2_many_dict) app_name = "tyadmin_api" serializers_txt = f"""from rest_framework import serializers $model_import占位$""" model_import_rows = [] for import_path, m_list in app_model_import_dict.items(): txt = f'from {import_path}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) serializers_txt = serializers_txt.replace("$model_import占位$", "".join(model_import_rows)) # print(model_fk_dict) wait_model_list = list(model_fk_dict.keys()) for (model, fk_field_l), (_, many_2) in zip(model_fk_dict.items(), model_many_2_many_dict.items()): fk_display_p = inner_deal_foreign(model, fk_field_l, many_2) fk_list = model_fk_dict[model] my_list = model_many_2_many_dict[model] if len(fk_list) == 0 and len(my_list) == 0: serializers_txt = gen_ser_txt(serializers_txt, model, fk_display_p) wait_model_list.remove(model) finish_model_list.append(model) finish_many_list.append(model) for model in wait_model_list: fk_display_p = inner_deal_foreign(model, model_fk_dict[model], model_many_2_many_dict[model]) serializers_txt = gen_ser_txt(serializers_txt, model, fk_display_p) # serializers_txt = deal_write(finish_model_list, model_fk_dict, model_many_2_many_dict, serializers_txt, wait_model_list, finish_many_list) # # if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_serializers.py'): # print("已存在serializers跳过") # else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_serializers.py', 'w', encoding='utf-8') as fw: fw.write(serializers_txt)
def gen_antd_pages(project_name_settings, user_label_list, focus_model=None, template_type="base"): # focus_model = 'HistoricalNetworkDevice' init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] gen_labels = SYS_LABELS + user_label_list # focus_model = "CourseResource" model_pic_dict = {} model_date_dict = {} model_service_dict = {} user = get_user_model() from django.utils.translation import gettext as _ model_list = django.apps.apps.get_models() for one in model_list: columns = [] model_name = one._meta.model.__name__ model_ver_name = trans(one._meta.verbose_name_raw) # if(isinstance(model_ver_name,__proxy__)): if focus_model and model_name != focus_model: continue if one._meta.app_label in gen_labels: print("^^" * 20) print(one._meta.app_label) print("^^" * 20) img_field_list = [] date_row_list = [] model_add_item_list = [] model_many_to_many_list = [] model_import_item_list = [] model_service_item_list = [] date_field_list = [] fileds_num = len(one.objects.model._meta.fields) for filed in one.objects.model._meta.fields: name = filed.name ver_name = trans(filed.verbose_name) if not contain_zh(ver_name): ver_name = trans(filed.name) print(ver_name) if import_adapter_priority(one._meta.app_label,one._meta.model.__name__, name): model_import_item_list.append(FIELD_ADAPTER[one._meta.app_label][one._meta.model.__name__][name]["index_import"]) if effect_state_adapter_priority(one._meta.app_label,one._meta.model.__name__, name): model_add_item_list.append(FIELD_ADAPTER[one._meta.app_label][one._meta.model.__name__][name]["effect_state"]) if services_adapter_priority(one._meta.app_label, one._meta.model.__name__, name): model_service_item_list.append(FIELD_ADAPTER[one._meta.app_label][one._meta.model.__name__][name]["services"]) if field_adapter_priority(one._meta.app_label,one._meta.model.__name__, name): one_c = FIELD_ADAPTER[one._meta.app_label][one._meta.model.__name__][name]["field"] elif isinstance(filed, ForeignKey): rela_model = filed.related_model._meta.object_name if filed.blank: one_c = """{ title: '%s', dataIndex: '%s', backendType: 'foreignKey', rules: [ ], renderFormItem: (item, {value, onChange}) => { return dealForeignKeyField(item, value, onChange, %sForeignKeyList); },render: (text, record) => { return renderForeignKey(text, %sVerboseNameMap); }, },""" % (ver_name, name, name, name) else: one_c = """{ title: '%s', dataIndex: '%s', backendType: 'foreignKey', rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (item, {value, onChange}) => { return dealForeignKeyField(item, value, onChange, %sForeignKeyList); }, render: (text, record) => { return renderForeignKey(text, %sVerboseNameMap); }, },""" % (ver_name, name, ver_name, name, name) one_c = one_c.replace("$模型名字$", name) print(name) print(filed) if isinstance(filed.verbose_name, str): one_c = one_c.replace("$模型显示名字$", filed.verbose_name) else: one_c = one_c.replace("$模型显示名字$", name) model_add_item = """const [$模型名字$ForeignKeyList, set$模型名字首字母大写$ForeignKeyList] = useState([]); useEffect(() => { query$关联Model$({all: 1}).then(value => { set$模型名字首字母大写$ForeignKeyList(value); }); }, []); const [$模型名字$VerboseNameMap, set$模型名字首字母大写$VerboseNameMap] = useState([]); useEffect(() => { query$关联Model$VerboseName().then(value => { set$模型名字首字母大写$VerboseNameMap(value); }); }, []); """.replace("$模型名字$", name).replace("$模型名字首字母大写$", name[0].upper() + name[1:]).replace("$关联Model$", rela_model) model_add_item_list.append(model_add_item) model_import_item = """import {query$关联Model$, query$关联Model$VerboseName} from '@/pages/AutoGenPage/$关联Model$List/service';""" \ .replace("$关联Model$", rela_model) if model_import_item not in model_import_item_list and model_name != rela_model: model_import_item_list.append(model_import_item) elif isinstance(filed, CharField): if filed.default != NOT_PROVIDED: if filed.default is not None: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" else: default_replace = "" if filed.choices: filed_choices_list = [] for filed_one in filed.choices: one_line = f'"{filed_one[0]}":"{filed_one[1]}"' filed_choices_list.append(one_line) if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name, ver_name) one_c = one_c.replace("$valueEnum$", ",".join(filed_choices_list)) elif name == "password": one_c = """{ %s title: '%s', dataIndex: '%s', hideInTable: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) else: if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) elif name == "id": if filed.default != NOT_PROVIDED: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" one_c = """{ %s title: '%s', dataIndex: '%s', hideInForm: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) elif isinstance(filed, DateTimeField): print(filed.default) hideInform = None if filed.default != django.db.models.NOT_PROVIDED or filed.auto_now == True: hideInform = True one_c = """{ title: '%s', dataIndex: '%s', valueType: 'dateTime', $隐藏form$ rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return dealDateTimeDisplay(text); }, },""" % (ver_name, name, ver_name) if hideInform: one_c = one_c.replace("$隐藏form$", "hideInForm: true,") else: one_c = one_c.replace("$隐藏form$", "") date_field_list.append('"' + name + '"') date_row_list.append(f'record.{name} = moment(record.{name});') elif isinstance(filed, DateField): if filed.auto_now: pass one_c = """{ title: '%s', dataIndex: '%s', valueType: 'date', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) date_field_list.append('"' + name + '"') date_row_list.append(f'record.{name} = moment(record.{name});') elif isinstance(filed, BooleanField): if filed.default != NOT_PROVIDED: if filed.default: default_replace = f' initialValue: true,' else: default_replace = f' initialValue: false,' else: default_replace = "" if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], render: (text, record) => { return BooleanDisplay(text); }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const is_value = form.getFieldValue('%s'); if (type === "form" && !is_value) { form.setFieldsValue({'%s': false}); } return <Switch checked={is_value} onClick={(checked) => { form.setFieldsValue({'%s': checked}); }} />; }, },""" % (default_replace, ver_name, name, name, name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return BooleanDisplay(text); }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const is_value = form.getFieldValue('%s'); if (type === "form" && !is_value) { form.setFieldsValue({'%s': false}); } return <Switch checked={is_value} onClick={(checked) => { form.setFieldsValue({'%s': checked}); }} />; }, },""" % (default_replace, ver_name, name, ver_name, name, name, name) elif isinstance(filed, IntegerField) or isinstance(filed, FloatField): if filed.default != NOT_PROVIDED: if filed.default: default_replace = f' initialValue: {filed.default},' else: default_replace = "" else: default_replace = "" if filed.choices: filed_choices_list = [] for filed_one in filed.choices: one_line = f'{filed_one[0]}:"{filed_one[1]}"' filed_choices_list.append(one_line) if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name, ver_name) one_c = one_c.replace("$valueEnum$", ",".join(filed_choices_list)) else: if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', valueType: 'digit', rules: [ ], },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', valueType: 'digit', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) elif isinstance(filed, ImageField) or isinstance(filed, SImageField): img_field_list.append('"' + name + '"') help_text = filed.help_text if "头像" in filed.verbose_name or filed.name == "avatar" or help_text == MAIN_AVATAR: if filed.blank: one_c = """{ title: '%s', dataIndex: '%s', valueType: 'avatar', hideInSearch: true, rules: [ ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, name) else: one_c = """{ title: '%s', dataIndex: '%s', valueType: 'avatar', hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, ver_name, name) else: if filed.blank: one_c = """{ title: '%s', dataIndex: '%s', render: (text, record) => { return <img src={text} width="80px" alt=""/> }, hideInSearch: true, rules: [ ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, name) else: one_c = """{ title: '%s', dataIndex: '%s', render: (text, record) => { return <img src={text} width="80px" alt=""/> }, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, ver_name, name) elif isinstance(filed, FileField): img_field_list.append('"' + name + '"') if filed.blank: one_c = """{ title: '%s', dataIndex: '%s', hideInSearch: true, rules: [ ], render: (text, record) => { return <a download={text.split('/').slice(-1)} href={text}>{text.split('/').slice(-1)}</a>; }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const downloadUrl = form.getFieldValue('download'); return fileUpload(downloadUrl); }, },""" % (ver_name, name) else: one_c = """{ title: '%s', dataIndex: '%s', hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return <a download={text.split('/').slice(-1)} href={text}>{text.split('/').slice(-1)}</a>; }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const downloadUrl = form.getFieldValue('download'); return fileUpload(downloadUrl); }, },""" % (ver_name, name, ver_name) elif filed.__class__.__name__ == "TextField": if filed.default != NOT_PROVIDED: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', valueType: 'textarea', ellipsis: true, rules: [ ], },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', valueType: 'textarea', ellipsis: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) elif filed.__class__.__name__ == "UEditorField" or isinstance(filed, richTextField): if filed.default != NOT_PROVIDED: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', customCol:richCol, ellipsis: true, hideInSearch: true, rules: [ ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { return richForm(form, rest.id); }, },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', customCol:richCol, ellipsis: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { return richForm(form, rest.id); }, },""" % (default_replace, ver_name, name, ver_name) elif filed.__class__.__name__ == "TimeZoneField": if filed.default != NOT_PROVIDED: if filed.default is not None: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" else: default_replace = "" if filed.CHOICES: filed_choices_list = [] for filed_one in filed.CHOICES: one_line = f'"{filed_one[0]}":"{filed_one[1]}"' filed_choices_list.append(one_line) if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name) else: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], valueEnum: { $valueEnum$ }, },""" % (default_replace, ver_name, name, ver_name) one_c = one_c.replace("$valueEnum$", ",".join(filed_choices_list)) else: if filed.default != NOT_PROVIDED: default_replace = f' initialValue: "{filed.default}",' else: default_replace = "" if filed.blank: one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ ], },""" % (default_replace, ver_name, name) else: print(filed.__class__.__name__) one_c = """{ %s title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (default_replace, ver_name, name, ver_name) model_pic_dict[model_name] = img_field_list model_date_dict[model_name] = date_field_list columns.append(one_c) model_service_dict[model_name] = model_service_item_list for filed in one.objects.model._meta.many_to_many: black_many_to_many = [] ver_name = filed.verbose_name if filed.name in black_many_to_many: continue else: name = filed.name rela_model = filed.related_model._meta.object_name print("&&&" * 30) print(one._meta.app_label, name) print("&&&" * 30) if filed.blank: if filed.name == "permissions" and one._meta.app_label == "auth" and rela_model == "Group": width_help = " width: '70%'," else: width_help = "" one_c = """{ title: '%s', dataIndex: '%s', %s rules: [ ], renderFormItem: (item, {value, onChange, type, defaultRender}) => { return dealManyToManyField(item, value,onChange,type, %sManyToManyList) }, render: (text, record) => { return renderManyToMany(text) }, },""" % (ver_name, name, width_help, name,) else: one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (item, {value, onChange, type, defaultRender}) => { return dealManyToManyField(item, value,onChange,type, %sManyToManyList) }, render: (text, record) => { return renderManyToMany(text) }, },""" % (ver_name, name, ver_name, name) one_c = one_c.replace("$百分$", "%") model_many_to_many_item = """const [$模型名字$ManyToManyList, set$模型名字首字母大写$ManyToManyList] = useState([]); useEffect(() => { query$关联Model$({all:1}).then(value => { set$模型名字首字母大写$ManyToManyList(value); }); }, []);""".replace("$模型名字$", name).replace("$模型名字首字母大写$", name[0].upper() + name[1:]) \ .replace("$关联Model$", rela_model) model_many_to_many_list.append(model_many_to_many_item) model_import_item = """import {query$关联Model$} from '@/pages/AutoGenPage/$关联Model$List/service';""".replace("$关联Model$", rela_model) if model_import_item not in model_import_item_list and model_name != rela_model: model_import_item_list.append(model_import_item) columns.append(one_c) if one._meta.app_label == user._meta.app_label and model_name == user._meta.object_name: opera = """ { title: '操作', dataIndex: 'option', valueType: 'option', fixed: 'right', width: 100, render: (text, record) => ( <> <EditOutlined title="编辑" className="icon" onClick={async () => { $时间处理占位$ handleUpdateModalVisible(true); setUpdateFormValues(record); }} /> <Divider type="vertical" /> <KeyOutlined onClick={() => { handleUpdatePassWordModalVisible(true); setUpdateFormValues(record); }} /> <Divider type="vertical" /> <Popconfirm title="您确定要删除$模型名字$吗?" placement="topRight" onConfirm={() => { handleRemove([record]) actionRef.current.reloadAndRest(); }} okText="确定" cancelText="取消" > <DeleteOutlined title="删除" className="icon" /> </Popconfirm> </> ), },""".replace("$模型名字$", model_ver_name) else: opera = """ { title: '操作', dataIndex: 'option', valueType: 'option', fixed: 'right', width: 100, render: (text, record) => ( <> <EditOutlined title="编辑" className="icon" onClick={async () => { $时间处理占位$ handleUpdateModalVisible(true); setUpdateFormValues(record); }} /> <Divider type="vertical" /> <Popconfirm title="您确定要删除$模型名字$吗?" placement="topRight" onConfirm={() => { handleRemove([record]) actionRef.current.reloadAndRest(); }} okText="确定" cancelText="取消" > <DeleteOutlined title="删除" className="icon" /> </Popconfirm> </> ), },""".replace("$模型名字$", model_ver_name) opera = opera.replace("$时间处理占位$", "".join(date_row_list)) columns.append(opera) dest_path = f'{os.path.dirname(__file__)}/antd_page_templates/{template_type}' with open(f'{dest_path}/index.jsx', encoding='utf-8') as fr: content = fr.read() if fileds_num > 8: new_content = content.replace("$两列布局占位$", """ search={{ span: { lg: 12, md: 12, xxl: 12, xl: 12, sm: 12, xs: 24, }, }}""") else: new_content = content.replace("$两列布局占位$", "") new_content = new_content.replace("$占位列数据$", "".join(columns)) new_content = new_content.replace("$占位模型名$", model_name) new_content = new_content.replace("$占位模型显示名$", str(model_ver_name)) new_content = new_content.replace("$外键占位$", "".join(model_add_item_list)) new_content = new_content.replace("$多对多占位$", "".join(model_many_to_many_list)) new_content = new_content.replace("$import占位$", "".join(model_import_item_list)) new_content = new_content.replace("$时间占位$", ",".join(model_date_dict[model_name])) if one._meta.app_label == user._meta.app_label and model_name == user._meta.object_name: print("生成密码", one._meta.app_label, model_name) new_content = new_content.replace("$passwordform引入$", """import {updateUserPassword} from './service';\nimport UpdatePasswordForm from './components/UpdatePasswordForm';""") new_content = new_content.replace("$Password占位$", 'const [updatePassWordModalVisible, handleUpdatePassWordModalVisible] = useState(false);\nconst [updatePasswordForm] = Form.useForm();') new_content = new_content.replace("$更新密码方法占位$", """ const handlePassWordUpdate = () => { if (updatePasswordForm.getFieldValue('password') !== updatePasswordForm.getFieldValue('re_password')) { updatePasswordForm.setFields([{ name: 're_password', errors: ['两次密码不一致'], }]); } else { updatePasswordForm.validateFields().then( value => { updateUserPassword({ ...value, username: updateFormValues["username"], }).then( message.success('密码修改成功'), handleUpdatePassWordModalVisible(false), ); }, ); updatePasswordForm.submit; } };""") new_content = new_content.replace("$Password更新Form$", """ { <UpdatePasswordForm onCancel={() => { handleUpdatePassWordModalVisible(false); }} handleUpdate={handlePassWordUpdate} updateModalVisible={updatePassWordModalVisible} userName={updateFormValues["username"]} > <Form form={updatePasswordForm}> <FormItem labelCol={{ span: 5, }} wrapperCol={{ span: 15, }} label="密码" name="password" rules={[ { required: true, message: '请输入密码!', }, ]} > <Input.Password placeholder="请输入密码" type="password" /> </FormItem> <FormItem labelCol={{ span: 5, }} wrapperCol={{ span: 15, }} label="重复密码" name="re_password" rules={[ { required: true, message: '请输入重复密码', }, ]} > <Input.Password placeholder="请再次输入密码" type="password" /> </FormItem> </Form> </UpdatePasswordForm> }""") else: new_content = new_content.replace("$passwordform引入$", "") new_content = new_content.replace("$Password占位$", '') new_content = new_content.replace("$更新密码方法占位$", '') new_content = new_content.replace("$Password更新Form$", '') with open(f'{dest_path}/service.js', encoding='utf-8') as fr: content = fr.read() new_services = content.replace("$占位path$", get_lower_case_name(model_name)) new_services = new_services.replace("$占位模型名$", model_name) new_services = new_services.replace("$图片字段列表$", ",".join(model_pic_dict[model_name])) new_services = new_services.replace("$适配service占位$", "\n".join(model_service_dict[model_name])) if one._meta.app_label == user._meta.app_label: new_services = new_services.replace("$更新密码service占位$", """ export async function updateUserPassword(params) { return request('/api/xadmin/v1/list_change_password', { method: 'POST', data: { ...params}, }); }""") else: new_services = new_services.replace("$更新密码service占位$", "") with open(f'{dest_path}/components/CreateForm.jsx', encoding='utf-8') as fr: create_form = fr.read() create_form = create_form.replace("$占位模型显示名$", str(model_ver_name)) if fileds_num > 8: create_form = create_form.replace("$宽度占位$", 'width={1200}') else: create_form = create_form.replace("$宽度占位$", "width={800}") with open(f'{dest_path}/components/UpdateForm.jsx', encoding='utf-8') as fr: update_form = fr.read() update_form = update_form.replace("$占位模型显示名$", str(model_ver_name)) if fileds_num > 8: update_form = update_form.replace("$宽度占位$", 'width={1200}') else: update_form = update_form.replace("$宽度占位$", "width={800}") with open(f'{dest_path}/components/UpdatePasswordForm.jsx', encoding='utf-8') as fr: change_password_form = fr.read() target_path = f'{settings.BASE_DIR}/tyadmin/src/pages/AutoGenPage' cur_path = f'{target_path}/{model_name}List' if not os.path.exists(cur_path): os.makedirs(cur_path) cur_path_co = f'{target_path}/{model_name}List/components' if not os.path.exists(cur_path_co): os.mkdir(cur_path_co) with open(f'{target_path}/{model_name}List/index.jsx', 'w', encoding='utf-8') as fw: fw.write(new_content) with open(f'{target_path}/{model_name}List/service.js', 'w', encoding='utf-8') as fw: fw.write(new_services) with open(f'{target_path}/{model_name}List/components/CreateForm.jsx', 'w', encoding='utf-8') as fw: fw.write(create_form) with open(f'{target_path}/{model_name}List/components/UpdateForm.jsx', 'w', encoding='utf-8') as fw: fw.write(update_form) if one._meta.app_label == user._meta.app_label: with open(f'{target_path}/{model_name}List/components/UpdatePasswordForm.jsx', 'w', encoding='utf-8') as fw: fw.write(change_password_form)
def gen_route(project_name_settings, user_label_list): import django from django.conf import settings init_django_env(project_name_settings) if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] # before inner_before_list = ["\n".join([ "[", "{", " name: 'Home',", " path: '/xadmin/index',", " icon: 'dashboard',", " component: './TyAdminBuiltIn/DashBoard'", "}"]), "\n".join([ "{", " path: '/xadmin/',", " redirect: '/xadmin/index',", "}", ])] # route gen_labels = SYS_LABELS + user_label_list gen_labels = [one for one in gen_labels if one != "contenttypes"] menu_groups = OrderedDict() menu_display_dict = {} for model in django.apps.apps.get_models(): if model._meta.app_label not in gen_labels: continue # 中文 # group_name = model._meta.app_config.verbose_name # model_name = trans(model._meta.verbose_name) group_display = model._meta.app_config.verbose_name group_name = model._meta.app_label menu_display_dict[group_name] = group_display model_name = model._meta.verbose_name url = f'/xadmin/{group_name}/{get_lower_case_name(model._meta.model.__name__)}' menu = "\n".join([ "{", f" name: '{model_name}',", f" path: '{url}',", f" component: './AutoGenPage/{model._meta.model.__name__}List',", "}", ]) if group_name not in menu_groups: menu_groups[group_name] = [] menu_groups[group_name].append(menu) group_route_list = inner_before_list for group_name, route_list in menu_groups.items(): group_route = "\n".join([ "{", f" name: '{menu_display_dict[group_name]}',", " icon: 'BarsOutlined',", f" path: '/xadmin/{group_name}',", " routes:", " [", ',\n'.join(route_list), " ]"]) + "\n }" group_route_list.append(group_route) # after group_route_list.append("\n".join([ "{", " name: 'TyadminBuiltin',", " icon: 'VideoCamera',", " path: '/xadmin/sys',", " routes:", " [", " {", " name: 'TyAdminLog',", " icon: 'smile',", " path: '/xadmin/sys/ty_admin_sys_log',", " component: './TyAdminBuiltIn/TyAdminSysLogList'", " },", " {", " name: 'TyAdminVerify',", " icon: 'smile',", " path: '/xadmin/sys/ty_admin_email_verify_record',", " component: './TyAdminBuiltIn/TyAdminEmailVerifyRecordList'", " }", " ]", "}"])) password_routes = '\n'.join([ " {", " name: 'passwordModify',", " path: '/xadmin/account/change_password',", " hideInMenu: true,", " icon: 'dashboard',", " component: './TyAdminBuiltIn/ChangePassword',", " }", ]) not_found_route = '\n'.join([ " {", " component: './404',", " },", ]) menu_string = ',\n'.join(group_route_list) + '\n]' menu_string = format_json_string(menu_string) group_route_list.append(password_routes) group_route_list.append(not_found_route) route_string = ',\n'.join(group_route_list) + '\n]' route_string = format_json_string(route_string) # Used for menu items loading from server side path = f'{settings.BASE_DIR}/tyadmin_api/menu.json' print(f'gen: {path}') with open(path, 'w', encoding='utf-8') as fw: fw.write(menu_string) # Used for frontend url route in config.js path = f'{settings.BASE_DIR}/tyadmin/config/routes.js' print(f'gen: {path}') with open(path, 'w', encoding='utf-8') as fw: fw.write(route_string)
def gen_antd_pages(project_name_settings, focus_model=None, template_type="base"): init_django_env(project_name_settings) import django from django.conf import settings sys_label = [ 'admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django' ] # focus_model = "CourseResource" model_pic_dict = {} model_date_dict = {} user = get_user_model() for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name if focus_model and model_name != focus_model: continue if one._meta.app_label not in sys_label: img_field_list = [] date_row_list = [] model_add_item_list = [] model_many_to_many_list = [] model_import_item_list = [] date_field_list = [] fileds_num = len(one.objects.model._meta.fields) for filed in one.objects.model._meta.fields: name = filed.name ver_name = filed.verbose_name if isinstance(filed, ForeignKey): rela_model = filed.related_model._meta.object_name help_text = filed.help_text.replace( MAIN_DISPLAY + "__", "") one_c = """{ title: '%s', dataIndex: '%s', backendType: 'foreignKey', rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (item, {value, onChange}) => { const children = $模型名字$ForeignKeyList.map((item) => { return <Option key={item.id} value={item.id}>{item.$外键显示字段$}</Option>; }); return <Select placeholder="请选择$模型显示名字$" onChange={onChange} > {children} </Select>; }, },""" % (ver_name, name, ver_name) one_c = one_c.replace("$模型名字$", name) one_c = one_c.replace("$外键显示字段$", help_text) one_c = one_c.replace("$模型显示名字$", filed.verbose_name) model_add_item = """const [$模型名字$ForeignKeyList, set$模型名字首字母大写$ForeignKeyList] = useState([]); useEffect(() => { query$关联Model$().then(value => { set$模型名字首字母大写$ForeignKeyList(value.data); }); }, []);""".replace("$模型名字$", name).replace("$模型名字首字母大写$", name[0].upper() + name[1:]).replace( "$关联Model$", rela_model) model_add_item_list.append(model_add_item) model_import_item = """import {query$关联Model$} from '@/pages/AutoGenPage//$关联Model$List/service';""".replace( "$关联Model$", rela_model) model_import_item_list.append(model_import_item) elif isinstance(filed, CharField): if filed.choices: filed_choices_list = [] for filed_one in filed.choices: one_line = f'{filed_one[0]}:"{filed_one[1]}"' filed_choices_list.append(one_line) one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], valueEnum: { $valueEnum$ }, },""" % (ver_name, name, ver_name) one_c = one_c.replace("$valueEnum$", ",".join(filed_choices_list)) elif name == "password": one_c = """{ title: '%s', dataIndex: '%s', hideInTable: true, hideInForm: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) else: one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) elif name == "id": one_c = """{ title: '%s', dataIndex: '%s', hideInForm: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) elif isinstance(filed, DateTimeField): print(filed.default) hideInform = None if filed.default != django.db.models.NOT_PROVIDED or filed.auto_now == True: hideInform = True one_c = """{ title: '%s', dataIndex: '%s', valueType: 'dateTime', $隐藏form$ rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return dealDateTimeDisplay(text); }, },""" % (ver_name, name, ver_name) if hideInform: one_c = one_c.replace("$隐藏form$", "hideInForm: true,") else: one_c = one_c.replace("$隐藏form$", "") date_field_list.append('"' + name + '"') date_row_list.append( f'record.{name} = moment(record.{name});') elif isinstance(filed, DateField): if filed.auto_now == True: pass one_c = """{ title: '%s', dataIndex: '%s', valueType: 'date', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) date_field_list.append('"' + name + '"') date_row_list.append( f'record.{name} = moment(record.{name});') elif isinstance(filed, BooleanField): one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return BooleanDisplay(text); }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const is_value = form.getFieldValue('%s'); if (type === "form" && !is_value) { form.setFieldsValue({'%s': false}); } return <Switch checked={is_value} onClick={(checked) => { form.setFieldsValue({'%s': checked}); }} />; }, },""" % (ver_name, name, ver_name, name, name, name) elif isinstance(filed, IntegerField) or isinstance( filed, FloatField): if filed.choices: filed_choices_list = [] for filed_one in filed.choices: one_line = f'{filed_one[0]}:"{filed_one[1]}"' filed_choices_list.append(one_line) one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], valueEnum: { $valueEnum$ }, },""" % (ver_name, name, ver_name) one_c = one_c.replace("$valueEnum$", ",".join(filed_choices_list)) else: one_c = """{ title: '%s', dataIndex: '%s', valueType: 'digit', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) elif isinstance(filed, ImageField) or isinstance( filed, SImageField): img_field_list.append('"' + name + '"') help_text = filed.help_text if help_text == MAIN_AVATAR: one_c = """{ title: '%s', dataIndex: '%s', valueType: 'avatar', hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, ver_name, name) elif help_text == MAIN_PIC: one_c = """{ title: '%s', dataIndex: '%s', render: (text, record) => { return <img src={text} width="80px" alt=""/> }, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const imageUrl = form.getFieldValue('%s'); return <UploadAvatar img={imageUrl}/> }, },""" % (ver_name, name, ver_name, name) elif isinstance(filed, FileField): img_field_list.append('"' + name + '"') one_c = """{ title: '%s', dataIndex: '%s', hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], render: (text, record) => { return <a download={text.split('/').slice(-1)} href={text}>{text.split('/').slice(-1)}</a>; }, renderFormItem: (_, {type, defaultRender, ...rest}, form) => { const downloadUrl = form.getFieldValue('download'); return fileUpload(downloadUrl); }, },""" % ( ver_name, name, ver_name) elif filed.__class__.__name__ == "TextField": one_c = """{ title: '%s', dataIndex: '%s', valueType: 'textarea', ellipsis: true, rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) elif filed.__class__.__name__ == "UEditorField" or isinstance( filed, richTextField): one_c = """{ title: '%s', dataIndex: '%s', customCol:richCol, ellipsis: true, hideInSearch: true, rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (_, {type, defaultRender, ...rest}, form) => { return richForm(form, rest.id); }, },""" % (ver_name, name, ver_name) else: print(filed.__class__.__name__) one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], },""" % (ver_name, name, ver_name) model_pic_dict[model_name] = img_field_list model_date_dict[model_name] = date_field_list columns.append(one_c) for filed in one.objects.model._meta.many_to_many: black_many_to_many = [ "groups", "permissions", "user_permissions" ] if one._meta.model == user and filed.name in black_many_to_many: continue else: name = filed.name ver_name = filed.verbose_name rela_model = filed.related_model._meta.object_name help_text = filed.help_text.replace( MAIN_DISPLAY + "__", "") one_c = """{ title: '%s', dataIndex: '%s', rules: [ { required: true, message: '%s为必填项', }, ], renderFormItem: (item, {value, onChange}) => { const children = %sManyToManyList.map(item => { return ( <Option key={item.id} value={item.id}> {item.%s} </Option> ); }); return ( <Select mode="multiple" placeholder="请选择%s" onChange={onChange}> {children} </Select> ); }, render: (text, record) => { const color_arr = [ 'green', 'cyan', 'blue', 'geekblue', 'purple', 'magenta', 'red', 'volcano', 'orange', 'gold', 'lime', ]; const child = []; text.forEach((value, index, arr) => { child.push(<Tag color={color_arr[value $百分$ 10]}>{%sManyToManyMap[value]}</Tag>); }); return <Space>{child}</Space>; }, },""" % (ver_name, name, ver_name, name, help_text, ver_name, name) one_c = one_c.replace("$百分$", "%") model_many_to_many_item = """const [$模型名字$ManyToManyList, set$模型名字首字母大写$ManyToManyList] = useState([]); const [$模型名字$ManyToManyMap, set$模型名字首字母大写$ManyToManyMap] = useState([]); useEffect(() => { query$关联Model$().then(value => { set$模型名字首字母大写$ManyToManyList(value.data); let get$模型名字首字母大写$ManyToManyMap = {}; for (let index in value.data) { let item = value.data[index]; get$模型名字首字母大写$ManyToManyMap[item.id.toString()] = item.$关联字段$; } set$模型名字首字母大写$ManyToManyMap(get$模型名字首字母大写$ManyToManyMap); }); }, []);""".replace("$模型名字$", name).replace("$模型名字首字母大写$", name[0].upper() + name[1:]) \ .replace("$关联Model$", rela_model).replace("$关联字段$", help_text) model_many_to_many_list.append(model_many_to_many_item) model_import_item = """import {query$关联Model$} from '@/pages/AutoGenPage//$关联Model$List/service';""".replace( "$关联Model$", rela_model) model_import_item_list.append(model_import_item) columns.append(one_c) opera = """ { title: '操作', dataIndex: 'option', valueType: 'option', fixed: 'right', width: 100, render: (text, record) => ( <> <EditOutlined title="编辑" className="icon" onClick={async () => { $时间处理占位$ handleUpdateModalVisible(true); setUpdateFormValues(record); }} /> <Divider type="vertical" /> <Popconfirm title="您确定要删除$模型名字$吗?" placement="topRight" onConfirm={() => { handleRemove([record]) actionRef.current.reloadAndRest(); }} okText="确定" cancelText="取消" > <DeleteOutlined title="删除" className="icon" /> </Popconfirm> </> ), },""".replace("$模型名字$", model_ver_name) opera = opera.replace("$时间处理占位$", "".join(date_row_list)) columns.append(opera) dest_path = f'{os.path.dirname(__file__)}/antd_page_templates/{template_type}' with open(f'{dest_path}/index.jsx', encoding='utf-8') as fr: content = fr.read() if fileds_num > 8: new_content = content.replace( "$两列布局占位$", """ search={{ span: { lg: 12, md: 12, xxl: 12, xl: 12, sm: 12, xs: 24, }, }}""") else: new_content = content.replace("$两列布局占位$", "") new_content = new_content.replace("$占位列数据$", "".join(columns)) new_content = new_content.replace("$占位模型名$", model_name) new_content = new_content.replace("$占位模型显示名$", str(model_ver_name)) new_content = new_content.replace("$外键占位$", "".join(model_add_item_list)) new_content = new_content.replace( "$多对多占位$", "".join(model_many_to_many_list)) new_content = new_content.replace( "$import占位$", "".join(model_import_item_list)) new_content = new_content.replace( "$时间占位$", ",".join(model_date_dict[model_name])) if len(model_pic_dict[model_name]) > 0: with open(f'{dest_path}/service_img.js', encoding='utf-8') as fr: content = fr.read() new_services = content.replace( "$占位path$", get_lower_case_name(model_name)) new_services = new_services.replace("$占位模型名$", model_name) new_services = new_services.replace( "$图片字段列表$", ",".join(model_pic_dict[model_name])) else: with open(f'{dest_path}/service.js', encoding='utf-8') as fr: content = fr.read() new_services = content.replace( "$占位path$", get_lower_case_name(model_name)) new_services = new_services.replace("$占位模型名$", model_name) with open(f'{dest_path}/components/CreateForm.jsx', encoding='utf-8') as fr: create_form = fr.read() create_form = create_form.replace("$占位模型显示名$", str(model_ver_name)) if fileds_num > 8: create_form = create_form.replace("$宽度占位$", 'width={1200}') else: create_form = create_form.replace("$宽度占位$", "width={600}") with open(f'{dest_path}/components/UpdateForm.jsx', encoding='utf-8') as fr: update_form = fr.read() update_form = update_form.replace("$占位模型显示名$", str(model_ver_name)) if fileds_num > 8: update_form = update_form.replace("$宽度占位$", 'width={1200}') else: update_form = update_form.replace("$宽度占位$", "width={600}") target_path = f'{settings.BASE_DIR}/tyadmin/src/pages/AutoGenPage' cur_path = f'{target_path}/{model_name}List' if not os.path.exists(cur_path): os.mkdir(cur_path) cur_path_co = f'{target_path}/{model_name}List/components' if not os.path.exists(cur_path_co): os.mkdir(cur_path_co) with open(f'{target_path}/{model_name}List/index.jsx', 'w', encoding='utf-8') as fw: fw.write(new_content) with open(f'{target_path}/{model_name}List/service.js', 'w', encoding='utf-8') as fw: fw.write(new_services) with open( f'{target_path}/{model_name}List/components/CreateForm.jsx', 'w', encoding='utf-8') as fw: fw.write(create_form) with open( f'{target_path}/{model_name}List/components/UpdateForm.jsx', 'w', encoding='utf-8') as fw: fw.write(update_form)
def gen_filter(project_name_settings, user_label_list): init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] model_list = [] model_pic_dict = {} model_fk_dict = {} model_date_dict = {} app_model_import_dict = {} gen_labels = SYS_LABELS + user_label_list for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label in gen_labels: try: app_model_import_dict[app_label].append(model_name) except KeyError: app_model_import_dict[app_label] = [model_name] img_field_list = [] fk_field_list = [] date_field_list = [] for filed in one.objects.model._meta.fields: name = filed.name ver_name = filed.verbose_name if isinstance(filed, ImageField): img_field_list.append('"' + name + '"') if isinstance(filed, FileField): img_field_list.append('"' + name + '"') if isinstance(filed, ForeignKey): help_text = filed.help_text.replace( MAIN_DISPLAY + "__", "") fk_field_list.append(name + "$分割$" + help_text) if isinstance(filed, DateTimeField): date_field_list.append(name) if filed.__class__.__name__ == "TimeZoneField": img_field_list.append('"' + name + '"') model_pic_dict[model_name] = img_field_list model_fk_dict[model_name] = fk_field_list model_date_dict[model_name] = date_field_list model_list.append(model_name) filters_txt = f"""from django_filters import rest_framework as filters from tyadmin_api.custom import DateFromToRangeFilter $model_import占位$""" model_import_rows = [] for app, m_list in app_model_import_dict.items(): if app in ["auth", "contenttypes"]: txt = f'from django.contrib.{app}.models import {", ".join(m_list)}\n' else: txt = f'from {app}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) model_import_rows = model_import_rows[:-1] + [ model_import_rows[-1].replace("\n", "") ] filters_txt = filters_txt.replace("$model_import占位$", "".join(model_import_rows)) for (model, img_field_l), (model_2, fk_field_l), (model_3, date_field_l) in zip( model_pic_dict.items(), model_fk_dict.items(), model_date_dict.items()): fk_display_p = [] for one_fk in fk_field_l: fk_name, fk_text = one_fk.split("$分割$") fk_one_line = f' {fk_name}_text = filters.CharFilter(field_name="{fk_name}")\n' fk_display_p.append(fk_one_line) date_range_p = [] for one_date in date_field_l: date_one_line = f' {one_date} = DateFromToRangeFilter(field_name="{one_date}")\n' date_range_p.append(date_one_line) filters_txt += f""" class {model}Filter(filters.FilterSet): {"".join(fk_display_p)}{"".join(date_range_p)} class Meta: model = {model} exclude = [{",".join(img_field_l)}]""" # if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_filters.py'): # print("已存在filters.py跳过") # else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_filters.py', 'w', encoding='utf-8') as fw: fw.write(filters_txt)
def gen_serializer(project_name_settings): init_django_env(project_name_settings) import django from django.conf import settings model_list = [] model_fk_dict = {} app_model_import_dict = {} sys_label = [ 'admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django' ] for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label not in sys_label: fk_field_list = [] try: app_model_import_dict[app_label].append(model_name) except KeyError: app_model_import_dict[app_label] = [model_name] for filed in one.objects.model._meta.fields: name = filed.name ver_name = filed.verbose_name if isinstance(filed, ForeignKey): help_text = filed.help_text.replace( MAIN_DISPLAY + "__", "") fk_field_list.append(name + "$分割$" + help_text) model_fk_dict[model_name] = fk_field_list model_list.append(model_name) # status_text = serializers.CharField(source="status.text", read_only=True) print(model_fk_dict) app_name = "tyadmin_api" serializers_txt = f""" from rest_framework import serializers $model_import占位$ """ model_import_rows = [] for app, m_list in app_model_import_dict.items(): txt = f'from {app}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) serializers_txt = serializers_txt.replace("$model_import占位$", "".join(model_import_rows)) print(model_fk_dict) for model, fk_field_l in model_fk_dict.items(): fk_display_p = [] for one_fk in fk_field_l: fk_name, fk_text = one_fk.split("$分割$") fk_one_line = f'{fk_name}_text = serializers.CharField(source="{fk_name}.{fk_text}", read_only=True)\n' fk_display_p.append(fk_one_line) serializers_txt += f""" class {model}Serializer(serializers.ModelSerializer): {" ".join(fk_display_p)} class Meta: model = {model} fields = "__all__" """ # if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_serializers.py'): print("已存在serializers跳过") else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_serializers.py', 'w', encoding='utf-8') as fw: fw.write(serializers_txt)
def gen_filter(project_name_settings): init_django_env(project_name_settings) import django from django.conf import settings model_list = [] model_pic_dict = {} model_fk_dict = {} model_date_dict = {} app_model_import_dict = {} sys_label = ['admin', 'auth', 'contenttypes', 'sessions', 'captcha', 'xadmin', 'tyadmin_api', 'authtoken', 'social_django'] for one in django.apps.apps.get_models(): columns = [] model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label if app_label not in sys_label: try: app_model_import_dict[app_label].append(model_name) except KeyError: app_model_import_dict[app_label] = [model_name] img_field_list = [] fk_field_list = [] date_field_list = [] for filed in one.objects.model._meta.fields: name = filed.name ver_name = filed.verbose_name if isinstance(filed, ImageField): img_field_list.append('"' + name + '"') if isinstance(filed, FileField): img_field_list.append('"' + name + '"') if isinstance(filed, ForeignKey): help_text = filed.help_text.replace(MAIN_DISPLAY + "__", "") fk_field_list.append(name + "$分割$" + help_text) if isinstance(filed, DateTimeField): date_field_list.append(name) model_pic_dict[model_name] = img_field_list model_fk_dict[model_name] = fk_field_list model_date_dict[model_name] = date_field_list model_list.append(model_name) app_name = "tyadmin_api" filters_txt = f""" from django_filters import rest_framework as filters from tyadmin_api.custom import DateFromToRangeFilter $model_import占位$ """ model_import_rows = [] for app, m_list in app_model_import_dict.items(): txt = f'from {app}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) filters_txt = filters_txt.replace("$model_import占位$", "".join(model_import_rows)) for (model, img_field_l), (model_2, fk_field_l), (model_3, date_field_l) in zip(model_pic_dict.items(), model_fk_dict.items(), model_date_dict.items()): fk_display_p = [] for one_fk in fk_field_l: fk_name, fk_text = one_fk.split("$分割$") fk_one_line = f' {fk_name}_text = filters.CharFilter(field_name="{fk_name}")\n' fk_display_p.append(fk_one_line) date_range_p = [] for one_date in date_field_l: date_one_line = f' {one_date} = DateFromToRangeFilter(field_name="{one_date}")\n' date_range_p.append(date_one_line) filters_txt += f""" class {model}Filter(filters.FilterSet): {"".join(fk_display_p)}{"".join(date_range_p)} class Meta: model = {model} exclude = [{",".join(img_field_l)}] """ if os.path.exists(f'{settings.BASE_DIR}/tyadmin_api/auto_filters.py'): print("已存在filters.py跳过") else: with open(f'{settings.BASE_DIR}/tyadmin_api/auto_filters.py', 'w') as fw: fw.write(filters_txt)
def gen_antd_pages(project_name_settings, user_label_list, focus_model=None, template_type="base"): init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] try: force_cover = settings.TY_ADMIN_CONFIG['FORCED_COVER'] except KeyError: force_cover = False gen_labels = SYS_LABELS + user_label_list model_pic_dict = {} model_date_dict = {} model_service_dict = {} user = get_user_model() model_list = django.apps.apps.get_models() for one in model_list: columns = [] model_name = one._meta.model.__name__ model_ver_name = trans(one._meta.verbose_name_raw) app_name = one._meta.app_label model_meta = one.objects.model._meta if focus_model and model_name != focus_model: continue if app_name in gen_labels: img_field_list = [] date_row_list = [] model_add_item_list = [] model_many_to_many_list = [] model_import_item_list = [] model_service_item_list = [] date_field_list = [] fields_count = len(model_meta.fields) # 处理字段类型 for field in model_meta.fields: field_name = field.name # 进行第三方Field重写,优先级高 try: cur_adapter = FIELD_ADAPTER[app_name][model_name][ field_name] except KeyError: cur_adapter = None if cur_adapter and adapter_priority( app_name, model_name, field_name, "index_import"): model_import_item_list.append(cur_adapter["index_import"]) if cur_adapter and adapter_priority( app_name, model_name, field_name, "effect_state"): model_add_item_list.append(cur_adapter["effect_state"]) if cur_adapter and adapter_priority(app_name, model_name, field_name, "services"): model_service_item_list.append(cur_adapter["services"]) if cur_adapter and adapter_priority(app_name, model_name, field_name, "field"): current_field = cur_adapter["field"] elif isinstance(field, ForeignKey): associated_model = field.related_model._meta.object_name current_field = Field_Template_Factory(field) # print(current_field) field_first_up = field_name[0].upper() + field_name[1:] model_add_item = f""" const [{field_name}ForeignKeyList, set{field_first_up}ForeignKeyList] = useState([]); useEffect(() => {{ query{associated_model}({{all: 1}}).then(value => {{ set{field_first_up}ForeignKeyList(value); }}); }}, []); const [{field_name}VerboseNameMap, set{field_first_up}VerboseNameMap] = useState([]); useEffect(() => {{ query{associated_model}VerboseName().then(value => {{ set{field_first_up}VerboseNameMap(value); }}); }}, []);""" model_add_item_list.append(model_add_item) model_import_item = f"""import {{query{associated_model}, query{associated_model}VerboseName}} from '@/pages/AutoGenPage/{associated_model}List/service';""" if model_import_item not in model_import_item_list and model_name != associated_model: # 外键self 处理 model_import_item_list.append(model_import_item) elif isinstance(field, CharField): current_field = Field_Template_Factory(field) elif isinstance(field, DateTimeField): current_field = Field_Template_Factory(field) date_field_list.append('"' + field_name + '"') date_row_list.append( f'record.{field_name} = record.{field_name} === null ? record.{field_name} : moment(record.{field_name});' ) elif isinstance(field, DateField): current_field = Field_Template_Factory(field) date_field_list.append('"' + field_name + '"') date_row_list.append( f'record.{field_name} = record.{field_name} === null ? record.{field_name} : moment(record.{field_name});' ) elif isinstance(field, BooleanField): current_field = Field_Template_Factory(field) elif isinstance(field, IntegerField): current_field = Field_Template_Factory(field) elif isinstance(field, FloatField): current_field = Field_Template_Factory(field) elif isinstance(field, ImageField) or isinstance( field, SImageField): img_field_list.append('"' + field_name + '"') current_field = Field_Template_Factory(field) elif isinstance(field, FileField): img_field_list.append('"' + field_name + '"') current_field = Field_Template_Factory(field) elif isinstance(field, TextField): current_field = Field_Template_Factory(field) elif field.__class__.__name__ == "UEditorField" or isinstance( field, richTextField): current_field = Field_Template_Factory(field) elif field.__class__.__name__ == "TimeZoneField": current_field = Field_Template_Factory(field) else: current_field = Field_Template_Factory(field) # print(current_field) model_pic_dict[model_name] = img_field_list model_date_dict[model_name] = date_field_list columns.append(current_field) model_service_dict[model_name] = model_service_item_list # 处理多对多关系 for field in model_meta.many_to_many: associated_model = field.related_model._meta.object_name if style_adapter_priority(app_name, model_name, field.name, "many_to_many"): try: many_style = settings.TY_ADMIN_CONFIG["REWRITE"][ app_name][model_name][field.name]["many_to_many"] except KeyError: many_style = ty_admin_settings.TY_ADMIN_CONFIG[ "REWRITE"][app_name][model_name][ field.name]["many_to_many"] else: many_style = None current_field = Field_Template_Factory(field, many=True, manyStyle=many_style) field_name = field.name field_first_up = field_name[0].upper() + field_name[1:] model_many_to_many_item = f"""const [{field.name}ManyToManyList, set{field_first_up}ManyToManyList] = useState([]); useEffect(() => {{ query{associated_model}({{all:1}}).then(value => {{ set{field_first_up}ManyToManyList(value); }}); }}, []);""" model_many_to_many_list.append(model_many_to_many_item) model_import_item = f"""import {{query{associated_model}}} from '@/pages/AutoGenPage/{associated_model}List/service';""" if model_import_item not in model_import_item_list and model_name != associated_model: model_import_item_list.append(model_import_item) columns.append(current_field) if app_name == user._meta.app_label and model_name == user._meta.object_name: opera = UserOptionColumn.replace(">>MODEL_NAME<<", model_ver_name) else: opera = GeneralOptionColumn.replace(">>MODEL_NAME<<", model_ver_name) opera = opera.replace(">>TIME_DEAL_PLACEHOLDER<<", "".join(date_row_list)) columns.append(opera) dest_path = f'{os.path.dirname(__file__)}/antd_page_templates/{template_type}' with open(f'{dest_path}/index.jsx', encoding='utf-8') as fr: content = fr.read() if fields_count > 8: new_content = content.replace(">>TWO_COLUMNS_COL<<", "twoColumns") else: new_content = content.replace(">>TWO_COLUMNS_COL<<", "{}") new_content = new_content.replace(">>COLUMNS_LIST<<", "".join(columns)) new_content = new_content.replace(">>MODEL_NAME<<", model_name) new_content = new_content.replace(">>MODEL_VERBOSE_NAME<<", str(model_ver_name)) new_content = new_content.replace(">>FOREIGNKEY_PLACE<<", "".join(model_add_item_list)) new_content = new_content.replace( ">>MANY_TO_MANY_PLACE<<", "".join(model_many_to_many_list)) new_content = new_content.replace( ">>IMPORT_PLACE<<", "".join(model_import_item_list)) new_content = new_content.replace( ">>TIME_PLACE<<", ",".join(model_date_dict[model_name])) if app_name == user._meta.app_label and model_name == user._meta.object_name: # 更新自己的密码 new_content = new_content.replace(">>PASSWORD_FORM<<", PASSWORD_FORM) new_content = new_content.replace(">>PASSWORD_PLACE<<", PASSWORD_PLACE) new_content = new_content.replace( ">>UPDATE_PASSWORD_METHOD<<", UPDATE_PASSWORD_METHOD) new_content = new_content.replace( ">>PASSWORD_UPDATE_FORM<<", PASSWORD_UPDATE_FORM) else: new_content = new_content.replace(">>PASSWORD_FORM<<", "") new_content = new_content.replace(">>PASSWORD_PLACE<<", '') new_content = new_content.replace( ">>UPDATE_PASSWORD_METHOD<<", '') new_content = new_content.replace( ">>PASSWORD_UPDATE_FORM<<", '') with open(f'{dest_path}/service.js', encoding='utf-8') as fr: content = fr.read() new_services = content.replace(">>MODEL_NAME_LOWER_CASE<<", get_lower_case_name(model_name)) new_services = new_services.replace(">>MODEL_NAME<<", model_name) new_services = new_services.replace( ">>IMAGE_FIELD_LIST<<", ",".join(model_pic_dict[model_name])) new_services = new_services.replace( ">>ADAPTER_SERVICE<<", "\n".join(model_service_dict[model_name])) if app_name == user._meta.app_label: new_services = new_services.replace( ">>UPDATE_PASSWORD_SERVICE<<", """ export async function updateUserPassword(params) { return request('/api/xadmin/v1/list_change_password', { method: 'POST', data: { ...params}, }); }""") else: new_services = new_services.replace( ">>UPDATE_PASSWORD_SERVICE<<", "") with open(f'{dest_path}/components/CreateForm.jsx', encoding='utf-8') as fr: create_form = fr.read() create_form = create_form.replace(">>MODEL_VERBOSE_NAME<<", str(model_ver_name)) if fields_count > 8: create_form = create_form.replace(">>WIDTH_PLACEHOLDER<<", 'width={1200}') else: create_form = create_form.replace(">>WIDTH_PLACEHOLDER<<", "width={800}") with open(f'{dest_path}/components/UpdateForm.jsx', encoding='utf-8') as fr: update_form = fr.read() update_form = update_form.replace(">>MODEL_VERBOSE_NAME<<", str(model_ver_name)) if fields_count > 8: update_form = update_form.replace(">>WIDTH_PLACEHOLDER<<", 'width={1200}') else: update_form = update_form.replace(">>WIDTH_PLACEHOLDER<<", "width={800}") with open(f'{dest_path}/components/UpdatePasswordForm.jsx', encoding='utf-8') as fr: change_password_form = fr.read() target_path = f'{settings.BASE_DIR}/tyadmin/src/pages/AutoGenPage' cur_path = f'{target_path}/{model_name}List' if not os.path.exists(cur_path): os.makedirs(cur_path) cur_path_co = f'{target_path}/{model_name}List/components' if not os.path.exists(cur_path_co): os.makedirs(cur_path_co) index_jsx_path = f'{target_path}/{model_name}List/index.jsx' if not force_cover and os.path.exists(index_jsx_path): pass else: with open(index_jsx_path, 'w', encoding='utf-8') as fw: fw.write(new_content) service_jsx_path = f'{target_path}/{model_name}List/service.js' if not force_cover and os.path.exists(service_jsx_path): pass else: with open(service_jsx_path, 'w', encoding='utf-8') as fw: fw.write(new_services) create_form_path = f'{target_path}/{model_name}List/components/CreateForm.jsx' if not force_cover and os.path.exists(create_form_path): pass else: with open(create_form_path, 'w', encoding='utf-8') as fw: fw.write(create_form) update_form_path = f'{target_path}/{model_name}List/components/UpdateForm.jsx' if not force_cover and os.path.exists(update_form_path): pass else: with open(update_form_path, 'w', encoding='utf-8') as fw: fw.write(update_form) if app_name == user._meta.app_label: update_password_form_path = f'{target_path}/{model_name}List/components/UpdatePasswordForm.jsx' if not force_cover and os.path.exists( update_password_form_path): pass else: with open(update_password_form_path, 'w', encoding='utf-8') as fw: fw.write(change_password_form)
from tyadmin_api_cli.utils import init_django_env init_django_env("skyoms.settings") import django model_list = django.apps.apps.get_models() for one in model_list: print(one.objects.model._meta.object_name)
def gen_view(project_name_settings, user_label_list): init_django_env(project_name_settings) import django from django.conf import settings if not user_label_list: user_label_list = settings.TY_ADMIN_CONFIG["GEN_APPS"] model_list = [] app_name = "tyadmin_api" model_search_dict = {} app_model_import_dict = {} gen_labels = SYS_LABELS + user_label_list for one in django.apps.apps.get_models(): model_name = one._meta.model.__name__ model_ver_name = one._meta.verbose_name app_label = one._meta.app_label import_path = get_model_import_path(one) if app_label in gen_labels: try: app_model_import_dict[import_path].append(model_name) except KeyError: app_model_import_dict[import_path] = [model_name] search_list = [] model_list.append(model_name) for field in one.objects.model._meta.fields: name = field.name ver_name = field.verbose_name if isinstance(field, CharField): search_list.append('"' + name + '"') elif isinstance(field, CharField): search_list.append('"' + name + '"') model_search_dict[model_name] = search_list serializers_list = [one + "ListSerializer" for one in model_list] serializers_update_list = [ one + "CreateUpdateSerializer" for one in model_list ] filters_list = [one + "Filter" for one in model_list] viewset_txt = f""" from rest_framework import viewsets from tyadmin_api.custom import XadminViewSet $model_import占位$ from {app_name}.auto_serializers import {", ".join(serializers_list)} from {app_name}.auto_serializers import {", ".join(serializers_update_list)} from {app_name}.auto_filters import {", ".join(filters_list)} """ model_import_rows = [] for import_path, m_list in app_model_import_dict.items(): print(m_list) txt = f'from {import_path}.models import {", ".join(m_list)}\n' model_import_rows.append(txt) viewset_txt = viewset_txt.replace("$model_import占位$", "".join(model_import_rows)) for model_name in model_list: viewset_txt += f""" class {model_name}ViewSet(XadminViewSet): serializer_class = {model_name}ListSerializer queryset = {model_name}.objects.all().order_by('-pk') filter_class = {model_name}Filter search_fields = [{",".join(model_search_dict[model_name])}] def get_serializer_class(self): if self.action == "list": return {model_name}ListSerializer else: return {model_name}CreateUpdateSerializer """ with open(f'{settings.BASE_DIR}/tyadmin_api/auto_views.py', 'w', encoding='utf-8') as fw: fw.write(viewset_txt)