├── .gitignore ├── .gitlab-ci.yml ├── README.md ├── django2go ├── __init__.py ├── admin.py ├── apps.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── model2go.py ├── migrations │ └── __init__.py ├── models.py ├── templates │ └── model.go ├── tests.py └── views.py ├── setup.py └── test_project ├── db.sqlite3 ├── manage.py ├── test_project ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py ├── testapp.go └── testapp ├── __init__.py ├── admin.py ├── apps.py ├── migrations ├── 0001_initial.py └── __init__.py ├── models.py ├── tests.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cd] 2 | *.vscode/ 3 | */.env/ 4 | build/ 5 | dist/ 6 | *.egg-info/ -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - test 3 | 4 | test: 5 | stage: test 6 | script: 7 | - cd test_project/ 8 | - python manage.py model2go testapp 9 | - cat testapp.go 10 | only: 11 | - master 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django Model 2 Go Struct 2 | 3 | for gorm or other ORM operation. 4 | 5 | Depends in go code: 6 | 7 | https://github.com/jinzhu/gorm 8 | 9 | https://github.com/guregu/null 10 | 11 | ## Install 12 | 13 | ```bash 14 | git clone /django2go.git 15 | cd django2go 16 | python setup.py install . 17 | ``` 18 | 19 | ## Usage: 20 | 21 | settings.py 22 | 23 | ```python 24 | INSTALLED_APPS = [ 25 | ... 26 | 'django2go', 27 | ... 28 | ] 29 | 30 | ``` 31 | 32 | run CMD: 33 | 34 | `python manage.py model2go app_name` 35 | 36 | Example generated go code: [testapp.go](./test_project/testapp.go) 37 | 38 | `python manage.py model2go app_name --use_column_name` To use database column name. 39 | 40 | Django model: 41 | 42 | ```python 43 | 44 | class Model1(models.Model): 45 | field1 = models.CharField(max_length=200) 46 | field_with_under_score = models.IntegerField() 47 | fieldWithUpperCase = models.IntegerField() 48 | fieldWith_Case = models.IntegerField() 49 | 50 | ``` 51 | 52 | Generated go struct: 53 | 54 | ```go 55 | 56 | type Model2 struct { 57 | Id int64 `json:"id" gorm:"primary_key"` 58 | Field1 string `json:"field1"` 59 | FieldWithUnderScore int64 `json:"field_with_under_score"` 60 | Fieldwithuppercase int64 `json:"fieldWithUpperCase"` 61 | FieldwithCase int64 `json:"fieldWith_Case"` 62 | } 63 | 64 | // TableName 使用指定的数据库表名 65 | func (Model2) TableName() string { 66 | 67 | return TABLE_PREFIX + "model2" 68 | 69 | } 70 | 71 | ``` -------------------------------------------------------------------------------- /django2go/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/django2go/__init__.py -------------------------------------------------------------------------------- /django2go/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.contrib import admin 5 | 6 | # Register your models here. 7 | -------------------------------------------------------------------------------- /django2go/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.apps import AppConfig 5 | 6 | 7 | class DjangoGoConfig(AppConfig): 8 | name = 'django2go' 9 | -------------------------------------------------------------------------------- /django2go/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/django2go/management/__init__.py -------------------------------------------------------------------------------- /django2go/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/django2go/management/commands/__init__.py -------------------------------------------------------------------------------- /django2go/management/commands/model2go.py: -------------------------------------------------------------------------------- 1 | from django.core.management.base import BaseCommand, CommandError 2 | from django2go.views import model2go 3 | 4 | import six 5 | class Command(BaseCommand): 6 | help = 'Generate structs from models.py from given app.' 7 | 8 | def add_arguments(self, parser): 9 | parser.add_argument('app_name', nargs='+', type=str) 10 | parser.add_argument('-c', '--use_column_name', help='Use DB column name or model field name(default).', action='store_true') 11 | 12 | def handle(self, *args, **options): 13 | for app_name in options['app_name']: 14 | code = model2go(app_name, use_column_name=options['use_column_name']) 15 | if six.PY2: 16 | open("%s.go"%app_name, 'w').write(code.encode('utf-8')) 17 | else: 18 | open("%s.go"%app_name, 'w', encoding='utf-8').write(code) 19 | 20 | self.stdout.write(self.style.SUCCESS('Successfully generated model "%s"' % app_name)) -------------------------------------------------------------------------------- /django2go/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/django2go/migrations/__init__.py -------------------------------------------------------------------------------- /django2go/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | 6 | # Create your models here. 7 | 8 | IntegerField = "int64" 9 | BooleanField = "bool" 10 | CharField = "string" 11 | DateField = "string" 12 | DateTimeField = "string" 13 | EmailField = "string" 14 | DecimalField = "float" 15 | ModelField = "unknown" 16 | FileField = "string" 17 | ImageField = "string" 18 | FloatField = "float64" 19 | NullBooleanField = "int" 20 | URLField = "string" 21 | TimeField = "string" 22 | IPAddressField = "string" 23 | FilePathField = "string" 24 | JSONField = "string" 25 | 26 | # null_map = { 27 | # "string":"sql.NullString", 28 | # "unknown":"unknown", 29 | # "int":"sql.NullInt64", 30 | # "int64":"sql.NullInt64", 31 | # "bool":"sql.NullBool", 32 | # "float64":"sql.NullFloat64" 33 | # } 34 | 35 | null_map = { 36 | "string":"null.String", 37 | "unknown":"unknown", 38 | "int":"null.Int", 39 | "int64":"null.Int", 40 | "bool":"null.Bool", 41 | "float64":"null.Float" 42 | } 43 | 44 | serializer_field_mapping = { 45 | 'AutoField': IntegerField, 46 | 'ForeignKey': IntegerField, 47 | 'OneToOneField': IntegerField, 48 | 'ManyToManyField': IntegerField, 49 | 'BigIntegerField': IntegerField, 50 | 'BooleanField': BooleanField, 51 | 'CharField': CharField, 52 | 'CommaSeparatedIntegerField': CharField, 53 | 'DateField': DateField, 54 | 'DateTimeField': DateTimeField, 55 | 'DecimalField': DecimalField, 56 | 'EmailField': EmailField, 57 | 'Field': ModelField, 58 | 'FileField': FileField, 59 | 'FloatField': FloatField, 60 | 'ImageField': ImageField, 61 | 'IntegerField': IntegerField, 62 | 'NullBooleanField': NullBooleanField, 63 | 'PositiveIntegerField': IntegerField, 64 | 'PositiveSmallIntegerField': IntegerField, 65 | 'SmallIntegerField': IntegerField, 66 | 'TextField': CharField, 67 | 'TimeField': TimeField, 68 | 'URLField': URLField, 69 | 'GenericIPAddressField': IPAddressField, 70 | 'FilePathField': FilePathField, 71 | 'JSONField': JSONField, 72 | } 73 | 74 | extras = { 75 | 'BinaryField': CharField, 76 | } 77 | 78 | serializer_field_mapping.update(extras) 79 | -------------------------------------------------------------------------------- /django2go/templates/model.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strings" 7 | 8 | {%if null%} 9 | "github.com/guregu/null"{%endif%} 10 | 11 | "github.com/jinzhu/gorm" 12 | _ "github.com/jinzhu/gorm/dialects/mysql" 13 | _ "github.com/mattn/go-sqlite3" 14 | ) 15 | 16 | const TABLE_PREFIX = "{{app_name}}_" 17 | 18 | {% for model_name, table_name, use_prefix, fields in structs %} 19 | 20 | type {{model_name}} struct {{% for field, field_type, tag in fields %} 21 | {{field | ljust:15}} {{field_type| ljust:10}} {%if tag%}`{{tag|safe }}`{%endif%}{%endfor%} 22 | } 23 | 24 | // TableName 使用指定的数据库表名 25 | func ({{model_name}}) TableName() string { 26 | {% if use_prefix %} 27 | return TABLE_PREFIX + "{{table_name}}" 28 | {% else %} 29 | return "{{table_name}}" 30 | {% endif %} 31 | } 32 | 33 | {% endfor %} 34 | 35 | // MigrateTabels 迁移数据库表 36 | func MigrateTabels(db *gorm.DB) { 37 | {% for model_name, _, _, _ in structs %} 38 | db.AutoMigrate(&{{model_name}}{}){% endfor %} 39 | 40 | } 41 | 42 | func Unmarshal(name string, data []byte) (interface{}, error) { 43 | name = strings.ToLower(name) 44 | switch name {{% for model_name, _, _, _ in structs %} 45 | case "{{model_name|lower}}": 46 | var source {{model_name}} 47 | err := json.Unmarshal(data, &source) 48 | return &source, err 49 | {% endfor %} 50 | } 51 | return nil, fmt.Errorf("Not a validated source type.") 52 | 53 | } 54 | 55 | func main() { 56 | db, err := gorm.Open("sqlite3", "{{app_name}}.db") 57 | // db, err := gorm.Open("mysql", "root:root@/db?charset=utf8") 58 | if err != nil { 59 | panic(err.Error()) 60 | } 61 | defer db.Close() 62 | 63 | // Migrate the schema 64 | MigrateTabels(db) 65 | 66 | fmt.Println("Done.") 67 | } 68 | -------------------------------------------------------------------------------- /django2go/tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.test import TestCase 5 | 6 | # Create your tests here. 7 | -------------------------------------------------------------------------------- /django2go/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.template.loader import render_to_string 5 | from django2go.models import serializer_field_mapping, null_map 6 | from django.apps import apps 7 | # Create your views here. 8 | 9 | 10 | def trans_name(name): 11 | return name.replace('_', " ").title().replace(' ', '') 12 | 13 | 14 | 15 | def map_field(field, null=True, use_column_name=False): 16 | # field, field_type, tag in fields 17 | name, _type, tag = trans_name(field.column), "", [] 18 | _type = serializer_field_mapping.get(field.get_internal_type(), "unknown") 19 | if _type == "unknown": 20 | print("Field %s unknown"%field.get_internal_type()) 21 | 22 | if null and field.null: 23 | _type = null_map[_type] 24 | 25 | tag += ['json:"%s"'%(field.column if use_column_name else field.name)] 26 | if field.primary_key: 27 | tag += ['gorm:"primary_key"'] 28 | 29 | 30 | return name, _type, ' '.join(tag) 31 | 32 | def get_app_structs(app_name, models=[], null=True, use_column_name=False): 33 | _models = apps.all_models[app_name] 34 | structs = [] 35 | # model_name, table_name, use_prefix, fields in structs 36 | for mname, model in _models.items(): 37 | if models: 38 | if mname not in models: 39 | continue 40 | go_fields = [map_field(f, null, use_column_name) for f in model._meta.fields] 41 | n = model.__name__ 42 | tablename = model._meta.db_table 43 | use_prefix = tablename.startswith(app_name+"_") 44 | if use_prefix: 45 | tablename = tablename[len(app_name)+1:] 46 | 47 | structs.append([ 48 | n, 49 | tablename, 50 | use_prefix, 51 | go_fields 52 | ]) 53 | 54 | return structs 55 | 56 | 57 | def model2go(app_name, models=[], null=True, use_column_name=False): 58 | env = dict( 59 | null=null, 60 | app_name=app_name, 61 | structs=get_app_structs(app_name, models, null, use_column_name), 62 | ) 63 | return render_to_string("model.go", env) 64 | 65 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os 3 | import six 4 | from setuptools import find_packages, setup 5 | 6 | if six.PY2: 7 | with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme: 8 | README = readme.read() 9 | else: 10 | with open(os.path.join(os.path.dirname(__file__), 'README.md'), encoding='utf8') as readme: 11 | README = readme.read() 12 | 13 | # allow setup.py to be run from any path 14 | os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) 15 | 16 | setup( 17 | name='django2go', 18 | version='0.1.3', 19 | packages=find_packages(), 20 | include_package_data=True, 21 | description='Translate django model to go struct.', 22 | long_description=README, 23 | author='treeoph', 24 | author_email="treeoph@gmail.com", 25 | long_description_content_type='text/markdown', 26 | data_files=[ 27 | ('django2go/templates', [])], 28 | classifiers=[ 29 | 'Environment :: Web Environment', 30 | 'Framework :: Django', 31 | 'Framework :: Django :: 1.10', # replace "X.Y" as appropriate 32 | 'Framework :: Django :: 3.2', # replace "X.Y" as appropriate 33 | 'Intended Audience :: Developers', 34 | 'Operating System :: OS Independent', 35 | 'Programming Language :: Python', 36 | # Replace these appropriately if you are stuck on Python 2. 37 | 'Programming Language :: Python :: 2.7', 38 | 'Programming Language :: Python :: 3', 39 | 'Programming Language :: Python :: 3.6', 40 | 'Programming Language :: Python :: 3.9', 41 | 'Topic :: Internet :: WWW/HTTP', 42 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 43 | ], 44 | ) 45 | -------------------------------------------------------------------------------- /test_project/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/test_project/db.sqlite3 -------------------------------------------------------------------------------- /test_project/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | sys.path.insert(0, '..') 5 | 6 | if __name__ == "__main__": 7 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") 8 | try: 9 | from django.core.management import execute_from_command_line 10 | except ImportError: 11 | # The above import may fail for some other reason. Ensure that the 12 | # issue is really that Django is missing to avoid masking other 13 | # exceptions on Python 2. 14 | try: 15 | import django 16 | except ImportError: 17 | raise ImportError( 18 | "Couldn't import Django. Are you sure it's installed and " 19 | "available on your PYTHONPATH environment variable? Did you " 20 | "forget to activate a virtual environment?" 21 | ) 22 | raise 23 | execute_from_command_line(sys.argv) 24 | -------------------------------------------------------------------------------- /test_project/test_project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/test_project/test_project/__init__.py -------------------------------------------------------------------------------- /test_project/test_project/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for test_project project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.11.4. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.11/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | # Quick-start development settings - unsuitable for production 19 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ 20 | 21 | # SECURITY WARNING: keep the secret key used in production secret! 22 | SECRET_KEY = 'hp%+g=uhhnxp40^qgy(^pe8z=gm@1t1n3j7ywil#tz%vc(m&p_' 23 | 24 | # SECURITY WARNING: don't run with debug turned on in production! 25 | DEBUG = True 26 | 27 | ALLOWED_HOSTS = [] 28 | 29 | 30 | # Application definition 31 | 32 | INSTALLED_APPS = [ 33 | 'django.contrib.admin', 34 | 'django.contrib.auth', 35 | 'django.contrib.contenttypes', 36 | 'django.contrib.sessions', 37 | 'django.contrib.messages', 38 | 'django.contrib.staticfiles', 39 | 'django2go', 40 | 'testapp', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'test_project.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'test_project.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/1.11/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | -------------------------------------------------------------------------------- /test_project/test_project/urls.py: -------------------------------------------------------------------------------- 1 | """test_project URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.11/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | 19 | urlpatterns = [ 20 | url(r'^admin/', admin.site.urls), 21 | ] 22 | -------------------------------------------------------------------------------- /test_project/test_project/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for test_project project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /test_project/testapp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strings" 7 | 8 | 9 | "github.com/guregu/null" 10 | 11 | "github.com/jinzhu/gorm" 12 | _ "github.com/jinzhu/gorm/dialects/mysql" 13 | _ "github.com/mattn/go-sqlite3" 14 | ) 15 | 16 | const TABLE_PREFIX = "testapp_" 17 | 18 | 19 | 20 | type Model1 struct { 21 | Id int64 `json:"id" gorm:"primary_key"` 22 | Field1 string `json:"field1"` 23 | FieldWithUnderScore int64 `json:"field_with_under_score"` 24 | Fieldwithuppercase int64 `json:"fieldWithUpperCase"` 25 | FieldwithCase int64 `json:"fieldWith_Case"` 26 | } 27 | 28 | // TableName 使用指定的数据库表名 29 | func (Model1) TableName() string { 30 | 31 | return TABLE_PREFIX + "model1" 32 | 33 | } 34 | 35 | 36 | 37 | type Model2 struct { 38 | Id int64 `json:"id" gorm:"primary_key"` 39 | Field1 string `json:"field1"` 40 | FieldWithUnderScore int64 `json:"field_with_under_score"` 41 | Fieldwithuppercase int64 `json:"fieldWithUpperCase"` 42 | FieldwithCase int64 `json:"fieldWith_Case"` 43 | } 44 | 45 | // TableName 使用指定的数据库表名 46 | func (Model2) TableName() string { 47 | 48 | return TABLE_PREFIX + "model2" 49 | 50 | } 51 | 52 | 53 | 54 | type Model3 struct { 55 | Id int64 `json:"id" gorm:"primary_key"` 56 | Field1 string `json:"field1"` 57 | } 58 | 59 | // TableName 使用指定的数据库表名 60 | func (Model3) TableName() string { 61 | 62 | return TABLE_PREFIX + "model3" 63 | 64 | } 65 | 66 | 67 | 68 | type ModelCase2_field11 struct { 69 | Id int64 `json:"id" gorm:"primary_key"` 70 | Modelcase2Id int64 `json:"modelcase2_id"` 71 | Model3Id int64 `json:"model3_id"` 72 | } 73 | 74 | // TableName 使用指定的数据库表名 75 | func (ModelCase2_field11) TableName() string { 76 | 77 | return TABLE_PREFIX + "modelcase2_field11" 78 | 79 | } 80 | 81 | 82 | 83 | type ModelCase2 struct { 84 | Id int64 `json:"id" gorm:"primary_key"` 85 | Field1 string `json:"field1"` 86 | Field2 int64 `json:"field2"` 87 | Field3 int64 `json:"field3"` 88 | Field4 string `json:"field4"` 89 | Field5 float64 `json:"field5"` 90 | Field6 string `json:"field6"` 91 | Field7 string `json:"field7"` 92 | Field8 string `json:"field8"` 93 | Field9Id int64 `json:"field9_id"` 94 | Field10Id int64 `json:"field10_id"` 95 | } 96 | 97 | // TableName 使用指定的数据库表名 98 | func (ModelCase2) TableName() string { 99 | 100 | return TABLE_PREFIX + "modelcase2" 101 | 102 | } 103 | 104 | 105 | 106 | type ModelCase3_field11 struct { 107 | Id int64 `json:"id" gorm:"primary_key"` 108 | Modelcase3Id int64 `json:"modelcase3_id"` 109 | Model3Id int64 `json:"model3_id"` 110 | } 111 | 112 | // TableName 使用指定的数据库表名 113 | func (ModelCase3_field11) TableName() string { 114 | 115 | return TABLE_PREFIX + "modelcase3_field11" 116 | 117 | } 118 | 119 | 120 | 121 | type ModelCase3 struct { 122 | Id int64 `json:"id" gorm:"primary_key"` 123 | Field1 null.String `json:"field1"` 124 | Field2 null.Int `json:"field2"` 125 | Field3 null.Int `json:"field3"` 126 | Field4 null.String `json:"field4"` 127 | Field5 null.Float `json:"field5"` 128 | Field6 null.String `json:"field6"` 129 | Field7 null.String `json:"field7"` 130 | Field8 null.String `json:"field8"` 131 | Field9Id null.Int `json:"field9_id"` 132 | Field10Id null.Int `json:"field10_id"` 133 | } 134 | 135 | // TableName 使用指定的数据库表名 136 | func (ModelCase3) TableName() string { 137 | 138 | return TABLE_PREFIX + "modelcase3" 139 | 140 | } 141 | 142 | 143 | 144 | // MigrateTabels 迁移数据库表 145 | func MigrateTabels(db *gorm.DB) { 146 | 147 | db.AutoMigrate(&Model1{}) 148 | db.AutoMigrate(&Model2{}) 149 | db.AutoMigrate(&Model3{}) 150 | db.AutoMigrate(&ModelCase2_field11{}) 151 | db.AutoMigrate(&ModelCase2{}) 152 | db.AutoMigrate(&ModelCase3_field11{}) 153 | db.AutoMigrate(&ModelCase3{}) 154 | 155 | } 156 | 157 | func Unmarshal(name string, data []byte) (interface{}, error) { 158 | name = strings.ToLower(name) 159 | switch name { 160 | case "model1": 161 | var source Model1 162 | err := json.Unmarshal(data, &source) 163 | return &source, err 164 | 165 | case "model2": 166 | var source Model2 167 | err := json.Unmarshal(data, &source) 168 | return &source, err 169 | 170 | case "model3": 171 | var source Model3 172 | err := json.Unmarshal(data, &source) 173 | return &source, err 174 | 175 | case "modelcase2_field11": 176 | var source ModelCase2_field11 177 | err := json.Unmarshal(data, &source) 178 | return &source, err 179 | 180 | case "modelcase2": 181 | var source ModelCase2 182 | err := json.Unmarshal(data, &source) 183 | return &source, err 184 | 185 | case "modelcase3_field11": 186 | var source ModelCase3_field11 187 | err := json.Unmarshal(data, &source) 188 | return &source, err 189 | 190 | case "modelcase3": 191 | var source ModelCase3 192 | err := json.Unmarshal(data, &source) 193 | return &source, err 194 | 195 | } 196 | return nil, fmt.Errorf("Not a validated source type.") 197 | 198 | } 199 | 200 | func main() { 201 | db, err := gorm.Open("sqlite3", "testapp.db") 202 | // db, err := gorm.Open("mysql", "root:root@/db?charset=utf8") 203 | if err != nil { 204 | panic(err.Error()) 205 | } 206 | defer db.Close() 207 | 208 | // Migrate the schema 209 | MigrateTabels(db) 210 | 211 | fmt.Println("Done.") 212 | } 213 | -------------------------------------------------------------------------------- /test_project/testapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/test_project/testapp/__init__.py -------------------------------------------------------------------------------- /test_project/testapp/admin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.contrib import admin 5 | 6 | # Register your models here. 7 | -------------------------------------------------------------------------------- /test_project/testapp/apps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.apps import AppConfig 5 | 6 | 7 | class TestappConfig(AppConfig): 8 | name = 'testapp' 9 | -------------------------------------------------------------------------------- /test_project/testapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.3 on 2023-03-02 01:37 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | initial = True 10 | 11 | dependencies = [ 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Model1', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('field1', models.CharField(max_length=200)), 20 | ('field_with_under_score', models.IntegerField()), 21 | ('fieldWithUpperCase', models.IntegerField()), 22 | ('fieldWith_Case', models.IntegerField()), 23 | ], 24 | ), 25 | migrations.CreateModel( 26 | name='Model2', 27 | fields=[ 28 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 29 | ('field1', models.CharField(max_length=200)), 30 | ('field_with_under_score', models.IntegerField()), 31 | ('fieldWithUpperCase', models.IntegerField()), 32 | ('fieldWith_Case', models.IntegerField()), 33 | ], 34 | ), 35 | migrations.CreateModel( 36 | name='Model3', 37 | fields=[ 38 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 39 | ('field1', models.CharField(max_length=200)), 40 | ], 41 | ), 42 | migrations.CreateModel( 43 | name='ModelCase3', 44 | fields=[ 45 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 46 | ('field1', models.CharField(max_length=200, null=True)), 47 | ('field2', models.IntegerField(null=True)), 48 | ('field3', models.BigIntegerField(null=True)), 49 | ('field4', models.BinaryField(null=True)), 50 | ('field5', models.FloatField(null=True)), 51 | ('field6', models.TextField(null=True)), 52 | ('field7', models.TimeField(null=True)), 53 | ('field8', models.DateTimeField(null=True)), 54 | ('field10', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='testapp.model2')), 55 | ('field11', models.ManyToManyField(to='testapp.Model3')), 56 | ('field9', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='testapp.model1')), 57 | ], 58 | ), 59 | migrations.CreateModel( 60 | name='ModelCase2', 61 | fields=[ 62 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 63 | ('field1', models.CharField(max_length=200)), 64 | ('field2', models.IntegerField()), 65 | ('field3', models.BigIntegerField()), 66 | ('field4', models.BinaryField()), 67 | ('field5', models.FloatField()), 68 | ('field6', models.TextField()), 69 | ('field7', models.TimeField()), 70 | ('field8', models.DateTimeField()), 71 | ('field10', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='testapp.model2')), 72 | ('field11', models.ManyToManyField(to='testapp.Model3')), 73 | ('field9', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='testapp.model1')), 74 | ], 75 | ), 76 | ] 77 | -------------------------------------------------------------------------------- /test_project/testapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadnoodles/django2go/d0d32d913aba262763e6053b0d9b1096f11420cf/test_project/testapp/migrations/__init__.py -------------------------------------------------------------------------------- /test_project/testapp/models.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | 6 | class Model1(models.Model): 7 | field1 = models.CharField(max_length=200) 8 | field_with_under_score = models.IntegerField() 9 | fieldWithUpperCase = models.IntegerField() 10 | fieldWith_Case = models.IntegerField() 11 | 12 | 13 | class Model2(models.Model): 14 | field1 = models.CharField(max_length=200) 15 | field_with_under_score = models.IntegerField() 16 | fieldWithUpperCase = models.IntegerField() 17 | fieldWith_Case = models.IntegerField() 18 | 19 | 20 | class Model3(models.Model): 21 | field1 = models.CharField(max_length=200) 22 | 23 | class ModelCase2(models.Model): 24 | field1 = models.CharField(max_length=200) 25 | field2 = models.IntegerField() 26 | field3 = models.BigIntegerField() 27 | field4 = models.BinaryField() 28 | field5 = models.FloatField() 29 | field6 = models.TextField() 30 | field7 = models.TimeField() 31 | field8 = models.DateTimeField() 32 | field9 = models.ForeignKey(Model1, on_delete=models.CASCADE) 33 | field10 = models.OneToOneField(Model2, on_delete=models.CASCADE) 34 | field11 = models.ManyToManyField(Model3) 35 | 36 | 37 | class ModelCase3(models.Model): 38 | field1 = models.CharField(null=True,max_length=200) 39 | field2 = models.IntegerField(null=True) 40 | field3 = models.BigIntegerField(null=True) 41 | field4 = models.BinaryField(null=True) 42 | field5 = models.FloatField(null=True) 43 | field6 = models.TextField(null=True) 44 | field7 = models.TimeField(null=True) 45 | field8 = models.DateTimeField(null=True) 46 | field9 = models.ForeignKey(Model1,null=True, on_delete=models.SET_NULL) 47 | field10 = models.OneToOneField(Model2,null=True, on_delete=models.SET_NULL) 48 | field11 = models.ManyToManyField(Model3) 49 | -------------------------------------------------------------------------------- /test_project/testapp/tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | import datetime 4 | from django.test import TestCase 5 | from testapp.models import * 6 | # Create your tests here. 7 | -------------------------------------------------------------------------------- /test_project/testapp/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.shortcuts import render 5 | 6 | # Create your views here. 7 | --------------------------------------------------------------------------------