├── django_autocode_tools ├── __init__.py ├── wrapper │ ├── __init__.py │ └── http_wrapper.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── auto_code.py ├── templates │ ├── ser │ ├── orm │ └── view ├── app_settings.py └── auto_code.py ├── tests ├── __init__.py ├── lx_pro │ ├── __init__.py │ ├── auto_code │ │ ├── __init__.py │ │ ├── orms │ │ │ └── __init__.py │ │ ├── sers │ │ │ └── __init__.py │ │ └── views │ │ │ └── __init__.py │ └── auto_template │ │ └── __init__.py └── README.MD ├── MANIFEST.in ├── setup.py └── README.md /django_autocode_tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /tests/lx_pro/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include django_autocode_tools/templates/* 2 | -------------------------------------------------------------------------------- /django_autocode_tools/wrapper/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- -------------------------------------------------------------------------------- /tests/README.MD: -------------------------------------------------------------------------------- 1 | 运行 python manage.py auto_code add Books 试一下吧 -------------------------------------------------------------------------------- /tests/lx_pro/auto_code/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /tests/lx_pro/auto_code/orms/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /tests/lx_pro/auto_code/sers/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /tests/lx_pro/auto_code/views/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /tests/lx_pro/auto_template/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /django_autocode_tools/management/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /django_autocode_tools/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | -------------------------------------------------------------------------------- /django_autocode_tools/templates/ser: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | from rest_framework import serializers 4 | 5 | from {{app}}.models import {{view_name}} 6 | 7 | 8 | class Ser{{view_name}}(serializers.ModelSerializer): 9 | 10 | class Meta: 11 | model = {{view_name}} 12 | fields = ('id',{{fields}}) 13 | 14 | def update(self, instance, validated_data): 15 | {{update}} 16 | instance.save() 17 | return instance 18 | 19 | -------------------------------------------------------------------------------- /django_autocode_tools/templates/orm: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from {{app}}.models import {{view_name}} 3 | 4 | def select_{{file_name}}_all(): 5 | return {{view_name}}.objects.all() 6 | 7 | 8 | def select_{{file_name}}_id(id): 9 | if isinstance(id,list): 10 | return {{view_name}}.objects.get(id__in=id) 11 | else: 12 | return {{view_name}}.objects.filter(id=id) 13 | 14 | def delete_{{file_name}}_id(id): 15 | {{view_name}}.objects.get(id=id).delete() -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from setuptools import setup, find_packages 3 | 4 | setup( 5 | name='django_autocode_tools', 6 | version='0.0.4', 7 | description=('Automatic Generation Interface and Database Operation tool based on django'), 8 | author='yunshao', 9 | author_email='yunshao1992@gmail.com', 10 | url='https://github.com/Mr-yun/django_autocode_tools', 11 | packages =['django_autocode_tools', 12 | 'django_autocode_tools.management', 13 | 'django_autocode_tools.management.commands', 14 | 'django_autocode_tools.wrapper'], 15 | install_requires=['Django>=1.8','jinja2','djangorestframework'], 16 | include_package_data = True 17 | ) 18 | -------------------------------------------------------------------------------- /django_autocode_tools/app_settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from __future__ import print_function 3 | 4 | from os import path, getcwd 5 | 6 | 7 | class Settings(): 8 | def __init__(self, settings): 9 | self.AUTO_CODE_ROOT_APP = getattr(settings, 'AUTO_CODE_ROOT_APP', None) 10 | self.AUTO_CODE_TEMPLATES_VIEW = getattr(settings, 'AUTO_CODE_TEMPLATES_VIEW', 11 | path.join(path.abspath(path.dirname(__file__)), 'templates')) 12 | self.AUTO_CODE_VIEW_SAVE_PATH = getattr(settings, 'AUTO_CODE_VIEW_SAVE_PATH', 13 | path.join(getcwd(), 'auto_code/views')) 14 | self.AUTO_CODE_ORM_SAVE_PATH = getattr(settings, 'AUTO_CODE_ORM_SAVE_PATH', 15 | path.join(getcwd(), 'auto_code/orms')) 16 | self.AUTO_CODE_SER_SAVE_PATH = getattr(settings, 'AUTO_CODE_SER_SAVE_PATH', 17 | path.join(getcwd(), 'auto_code/sers')) 18 | -------------------------------------------------------------------------------- /django_autocode_tools/management/commands/auto_code.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | from django.core.management.base import BaseCommand 4 | from django_autocode_tools.auto_code import AutoCode 5 | from django_crontab.crontab import Crontab 6 | 7 | 8 | class Command(BaseCommand): 9 | help = ''' 10 | add: automatically add restful api and basic orm operation. 11 | remove: remove automatic add script. 12 | refresh: refreshes serialized file''' 13 | 14 | def add_arguments(self, parser): 15 | parser.add_argument('subcommand', choices=['add', 'remove', 'refresh', 'zdy'], 16 | help=self.help) 17 | parser.add_argument('jobhash', nargs='?') 18 | 19 | def handle(self, *args, **options): 20 | auto = AutoCode(**options) 21 | if options['subcommand'] == 'add': 22 | auto.add() 23 | elif options['subcommand'] == 'remove': 24 | auto.remove() 25 | elif options['subcommand'] == 'refresh': 26 | auto.refresh() 27 | elif options['subcommand'] == 'zdy': 28 | auto.zdy() 29 | else: 30 | print(self.help) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django_autocode_tools 2 | django_autocode_tools是一款根据表名自动生成视图、表的基本orm操作、以及序列化操作代码文件, 3 | 同时该工具拥有自定义功能,只要稍微修改,你就打造一款适合你的自动化工具 4 | tests提供了可以试用样例,可以试用一下。 5 | 6 | ## 安装方法 7 | 1. pip install django_autocode_tools 8 | 9 | ## 使用说明 10 | ### 基本用法 11 | 1. 将'django_autocode_tools'加到settings.py中的INSTALL_APPS中 12 | *例 INSTALLED_APPS = ( 13 | '''' 14 | 'django.contrib.staticfiles', 15 | 'django_autocode_tools', 16 | '''', 17 | ) 18 | 2. python manage.py auto_code add 操作表名 19 | 3. 在manage.py同级目录下会生成auto_code文件夹 20 | *例 ├── auto_code 21 | │   ├── orms 22 | │   │   └── orm_books.py 23 | │   ├── sers 24 | │   │   └── ser_books.py 25 | │   └── views 26 | │   └── view_books.py 27 | ### 自定义用法 28 | 1. 在django项目中创建一个包,并添加一个zdy.py文件(除zdy.py外,其他文件为非必须) 29 | *例 :├── auto_template 30 | ├── oper 31 | ├── orm 32 | ├── ser 33 | ├── view 34 | └── zdy.py 35 | 2. zdy.py 采用一下模板(默认) 36 | class Zdy(object): 37 | def __init__(self, auto_code): 38 | self.auto_code = auto_code 39 | self.run() 40 | 41 | def run(self): 42 | 此处填写自定义方法 43 | 3. 将刚才创建的包路径添加到 setting.py中添加AUTO_CODE_TEMPLATES_VIEW配置 44 | AUTO_CODE_TEMPLATES_VIEW = 'auto_template' 45 | 4. python manage.py auto_code zdy 操作表名 46 | ### 命令 47 | add: 添加视图,表orm,表序列化代码 48 | refresh: 更新表序列化代码 49 | remove: 移除视图,表orm,表序列化代码 50 | zdy: 自定义操作 51 | ### 配置 52 | AUTO_CODE_VIEW_SAVE_PATH = 'mes/dj_views' # 视图.py存放位置 53 | AUTO_CODE_ORM_SAVE_PATH = 'mes/orms/' # 表orm.py存放位置 54 | AUTO_CODE_SER_SAVE_PATH = 'mes/orms/serializer' # 表序列化.py存放位置 55 | AUTO_CODE_TEMPLATES_VIEW = 'auto_template' # 模板以及zdy.py存放位置 56 | -------------------------------------------------------------------------------- /django_autocode_tools/templates/view: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from rest_framework.views import APIView 3 | 4 | from django_autocode_tools.wrapper.http_wrapper import JsonRsp 5 | 6 | 7 | 8 | class View{{view_name}}(APIView): 9 | # url(r'/{{file_name}}',View{{view_name}}.as_view()) 10 | 11 | 12 | def post(self, request, *args, **kwargs): 13 | obj_{{file_name}} = create_{{file_name}}(request.body.decode('utf-8')) 14 | jsp = JsonRsp({'result': 'success','id':obj_{{file_name}}.id}) 15 | return jsp 16 | 17 | def get(self, request, *args, **kwargs): 18 | if request.GET.get('type') == 'index': 19 | list_{{file_name}} = select_{{file_name}}_all() 20 | jsp = JsonRsp({'result': 'success', 21 | 'list_{{file_name}}': Ser{{view_name}}(list_{{file_name}},many=True).data}) 22 | 23 | elif request.GET.get('type') == 'dtl': 24 | obj_{{file_name}} = select_{{file_name}}_id(request.GET.get('id')) 25 | jsp = JsonRsp({'result': 'success','{{file_name}}':Ser{{view_name}}(obj_{{file_name}}).data}) 26 | else: 27 | jsp = JsonRsp({'result': 'failure','msg':'url error'}) 28 | return jsp 29 | 30 | 31 | def put(self, request, *args, **kwargs): 32 | obj_{{file_name}} = select_{{file_name}}_id(request.GET.get('id')) 33 | Ser{{view_name}}().update(obj_{{file_name}},request.body.decode('utf-8')) 34 | jsp = JsonRsp({'result': 'failure','msg':'url error'}) 35 | return jsp 36 | 37 | 38 | def delete(self, request, *args, **kwargs): 39 | delete_{{file_name}}_id(request.GET.get('id')) 40 | jsp = JsonRsp({'result': 'success'}) 41 | return jsp 42 | -------------------------------------------------------------------------------- /django_autocode_tools/wrapper/http_wrapper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | from django.http import HttpResponse, JsonResponse 5 | 6 | # from requests import post as requests_post, adapters as requests_adapters 7 | 8 | http_server_version = 'Apache/2.4.12' 9 | 10 | 11 | # requests_adapters.DEFAULT_RETRIES = 3 12 | 13 | 14 | # =============================================================== 15 | 16 | # def post_http_request(url, data_dict): 17 | # headers = {'Content-Type': 'application/json;charset=utf-8'} 18 | # rsp = requests_post(url, data=json_dumps(data_dict), headers=headers, verify=False) 19 | # return rsp 20 | 21 | 22 | # =============================================================== 23 | 24 | class HttpRsp(HttpResponse): 25 | def __init__(self, *args, **kwargs): 26 | super(HttpRsp, self).__init__(*args, **kwargs) 27 | self['Server'] = http_server_version 28 | self['Cache-Control'] = 'no-store' 29 | 30 | 31 | class JsonRsp(JsonResponse): 32 | def __init__(self, data={}, status=200, *args, **kwargs): 33 | super(JsonRsp, self).__init__(data, **kwargs) 34 | self.status_code = status 35 | if 200 != status: 36 | self.reason_phrase = 'ERR' 37 | self['Server'] = http_server_version 38 | self['Cache-Control'] = 'no-store' 39 | 40 | # 允许跨域 41 | self["Access-Control-Allow-Origin"] = 'http://localhost:8081' 42 | 43 | self["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS, PUT, DELETE" 44 | self["Access-Control-Allow-Credentials"] = "true" 45 | self[ 46 | "Access-Control-Allow-Headers"] = "Content-Type,Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-CSRF-Token,x-csrftoken" 47 | -------------------------------------------------------------------------------- /django_autocode_tools/auto_code.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from imp import load_source 3 | from os import path, getcwd, makedirs, remove as file_remove 4 | 5 | from django.conf import settings 6 | from django_autocode_tools.app_settings import Settings 7 | from jinja2 import FileSystemLoader, Environment 8 | 9 | 10 | class AutoCode(object): 11 | def __find_oper_table(self): 12 | '''根据APP列表(倒叙),自动查找操作的表''' 13 | attribute = [] 14 | for z in settings.INSTALLED_APPS[::-1]: 15 | self.app = z 16 | attribute = self.get_attribute() 17 | 18 | if len(attribute) > 0: 19 | break 20 | return attribute 21 | 22 | def __check_folder(self): 23 | 24 | for dir_path in [self.settings.AUTO_CODE_VIEW_SAVE_PATH, 25 | self.settings.AUTO_CODE_ORM_SAVE_PATH, 26 | self.settings.AUTO_CODE_SER_SAVE_PATH]: 27 | if not path.exists(dir_path): 28 | makedirs(dir_path) 29 | 30 | def __init__(self, **options): 31 | self.view_name = options.get('jobhash') 32 | self.file_name = self.view_name.lower() 33 | 34 | self.old_template_path = path.join(path.abspath(path.dirname(__file__)), 'templates') 35 | self.settings = Settings(settings) 36 | self.base_dir = getcwd() 37 | 38 | if self.settings.AUTO_CODE_ROOT_APP is None: 39 | self.attribute = self.__find_oper_table() 40 | else: 41 | self.app = self.settings.AUTO_CODE_ROOT_APP 42 | self.attribute = self.get_attribute() 43 | 44 | def get_attribute(self): 45 | begin_bit = False 46 | attribute = [] 47 | app_path = path.join(self.base_dir, self.app) 48 | models_path = path.join(app_path, 'models.py') 49 | if path.exists(models_path): 50 | module_models = __import__(self.app + '.models', self.app) 51 | cls_table = getattr(module_models.models, self.view_name, None) 52 | if cls_table is not None: 53 | with open(models_path, 'r') as f: 54 | for line in f: 55 | if line.strip().startswith('#'): 56 | continue 57 | else: 58 | if line.startswith("class {0}(models.Model)".format(self.view_name)): 59 | begin_bit = True 60 | continue 61 | if 'class' in line: 62 | begin_bit = False 63 | if begin_bit and not line.startswith('#'): 64 | if '=' in line: 65 | attribute.append({ 66 | 'value': line.split('=')[0].strip(), 67 | 'ForeignKey': False, 68 | 'null': False 69 | }) 70 | if 'ForeignKey' in line: 71 | attribute[-1]['ForeignKey'] = True 72 | 73 | if 'null' in line: 74 | attribute[-1]['null'] = True 75 | if getattr(cls_table, '_meta', None): 76 | self.file_name = getattr(getattr(cls_table, '_meta', None), 'db_table', None) 77 | else: 78 | pass 79 | else: 80 | pass 81 | 82 | return attribute 83 | 84 | def __get_templates(self, filename): 85 | if path.exists(path.join(self.settings.AUTO_CODE_TEMPLATES_VIEW, filename)): 86 | templateLoader = FileSystemLoader(self.settings.AUTO_CODE_TEMPLATES_VIEW) 87 | env = Environment(loader=templateLoader) 88 | else: 89 | templateLoader = FileSystemLoader(self.old_template_path) 90 | env = Environment(loader=templateLoader) 91 | 92 | return env.get_template(filename) 93 | 94 | def add(self): 95 | self.__check_folder() 96 | 97 | self.__create_view() 98 | self.__ceare_orm() 99 | self.__create_ser() 100 | 101 | def refresh(self): 102 | self.__create_ser() 103 | 104 | def remove(self): 105 | for files in [ 106 | path.join(self.settings.AUTO_CODE_VIEW_SAVE_PATH, 'view_{}.py'.format(self.file_name)), 107 | path.join(self.settings.AUTO_CODE_ORM_SAVE_PATH, 'orm_{}.py'.format(self.file_name)), 108 | path.join(self.settings.AUTO_CODE_SER_SAVE_PATH, 'ser_{}.py'.format(self.file_name)), 109 | 110 | ]: 111 | 112 | if path.exists(files): 113 | file_remove(files) 114 | 115 | def __create_view(self): 116 | template = self.__get_templates('view') 117 | 118 | with open(path.join(self.settings.AUTO_CODE_VIEW_SAVE_PATH, 119 | 'view_{}.py'.format(self.file_name)), 120 | 'w') as f: 121 | f.write(template.render(view_name=self.view_name, file_name=self.file_name)) 122 | 123 | def __ceare_orm(self): 124 | template = self.__get_templates('orm') 125 | str_template = template.render(app=self.app, view_name=self.view_name, file_name=self.file_name) 126 | str_create = ''' 127 | def create_{1}(req): 128 | return {0}.objects.create({2}) 129 | ''' 130 | 131 | str_select = ''' 132 | def select_{1}_{2}(obj_{2}): 133 | return {0}.objects.filter({2}=obj_{2}) 134 | ''' 135 | template_create = '' 136 | 137 | for i in self.attribute: 138 | if not i['null']: 139 | template_create += "{0}=req['{0}'],".format(i['value']) 140 | if i['ForeignKey']: 141 | str_template += '\n\n' + str_select.format(self.view_name, self.file_name, i['value']) 142 | str_template += '\n\n' + str_create.format(self.view_name, self.file_name, template_create) 143 | 144 | with open(path.join(self.settings.AUTO_CODE_ORM_SAVE_PATH, 'orm_{}.py'.format(self.file_name)), 'w') as f: 145 | f.write(str_template) 146 | 147 | def __create_ser(self): 148 | template = self.__get_templates('ser') 149 | fields = "" 150 | for z in filter(lambda x: x['ForeignKey'] == False, self.attribute): 151 | fields += "'{}',".format(z['value']) 152 | 153 | update = '' 154 | for i in self.attribute: 155 | update += "instance.{0} = validated_data.get('{0}', instance.{0})\n ".format(i['value']) 156 | str_template = template.render(app=self.app, view_name=self.view_name, file_name=self.file_name, 157 | fields=fields[:-1], update=update) 158 | with open(path.join(self.settings.AUTO_CODE_SER_SAVE_PATH, 'ser_{}.py'.format(self.file_name)), 'w') as f: 159 | f.write(str_template) 160 | 161 | def zdy(self): 162 | py_file = path.join(self.settings.AUTO_CODE_TEMPLATES_VIEW, 'zdy.py') 163 | if path.exists(py_file): 164 | obj_zdy = load_source('auto_zdy', py_file).Zdy(self) 165 | obj_zdy.run() 166 | else: 167 | print('unfind zdy.py files') 168 | --------------------------------------------------------------------------------