├── django_rest_framework_generator ├── __init__.py └── management │ ├── __init__.py │ └── commands │ ├── __init__.py │ └── generate_serializers_views.py ├── README.md ├── .gitignore ├── LICENSE └── setup.py /django_rest_framework_generator/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_rest_framework_generator/management/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_rest_framework_generator/management/commands/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Generate initial & very basic serializers and viewsets 2 | 3 | Installation 4 | ------------ 5 | 6 | `pip install git+git://github.com/rapilabs/django-rest-framework-generator.git` 7 | 8 | or in your requirements.txt: 9 | 10 | `-e git+git://github.com/rapilabs/django-rest-framework-generator.git#egg=django-rest-framework-generator` 11 | 12 | and in your settings.py add: 13 | 14 | ```python 15 | INSTALLED_APPS = [ 16 | # ... 17 | 'django_rest_framework_generator', 18 | ] 19 | ``` 20 | 21 | Usage 22 | ----- 23 | 24 | To generate serializers: 25 | 26 | `python manage.py generate_serializers_views > /serializers.py` 27 | 28 | To generate viewsets: 29 | 30 | `python manage.py generate_serializers_views --viewsets > /views.py` 31 | 32 | To generate urls: 33 | 34 | `python manage.py generate_serializers_views --urls > /urls.py` 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 David Sanders 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup, find_packages 3 | 4 | with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme: 5 | README = readme.read() 6 | 7 | # allow setup.py to be run from any path 8 | os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) 9 | 10 | setup( 11 | name='django-rest-framework-generator', 12 | version='0.1.0', 13 | packages=find_packages(), 14 | include_package_data=True, 15 | license='MIT License', 16 | description='Generate initial serializers and viewsets', 17 | long_description=README, 18 | url='https://github.com/rapilabs/django-rest-framework-generator', 19 | author='David Sanders', 20 | author_email='dsanders@rapilabs.com', 21 | classifiers=[ 22 | 'Environment :: Web Environment', 23 | 'Framework :: Django', 24 | 'Intended Audience :: Developers', 25 | 'License :: OSI Approved :: MIT License', 26 | 'Operating System :: OS Independent', 27 | 'Programming Language :: Python', 28 | 'Programming Language :: Python :: 2.7', 29 | 'Programming Language :: Python :: 3.4', 30 | 'Topic :: Internet :: WWW/HTTP', 31 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 32 | ], 33 | keywords='generator generates', 34 | ) 35 | -------------------------------------------------------------------------------- /django_rest_framework_generator/management/commands/generate_serializers_views.py: -------------------------------------------------------------------------------- 1 | from optparse import make_option 2 | from django.core.management.base import BaseCommand, CommandError 3 | try: 4 | from django.apps import apps 5 | get_app = apps.get_app_config 6 | from django.apps.registry import AppConfig 7 | get_models = AppConfig.get_models 8 | except ImportError: 9 | from django.db.models.loading import get_app, get_models 10 | 11 | serializers = """\ 12 | from rest_framework import serializers 13 | %(model_imports)s 14 | %(classes)s 15 | """ 16 | 17 | serializer_class_def = """\ 18 | 19 | 20 | class %(model)sSerializer(serializers.ModelSerializer): 21 | class Meta: 22 | model = %(model)s 23 | """ 24 | 25 | viewsets = """\ 26 | from rest_framework import viewsets 27 | %(model_imports)s 28 | %(serializer_imports)s 29 | %(classes)s 30 | """ 31 | 32 | viewset_class_def = """\ 33 | 34 | 35 | class %(model)sViewSet(viewsets.ModelViewSet): 36 | queryset = %(model)s.objects.all() 37 | serializer_class = %(model)sSerializer 38 | """ 39 | 40 | urls = """\ 41 | from django.conf.urls import url, include 42 | from rest_framework import routers 43 | from . import views 44 | 45 | router = routers.DefaultRouter() 46 | %(router_defs)s 47 | 48 | urlpatterns = [ 49 | url(r'^', include(router.urls)), 50 | ] 51 | """ 52 | 53 | router_def = "router.register(r'%(model_api_name)s', views.%(model)sViewSet)\n" 54 | 55 | class Command(BaseCommand): 56 | args = '' 57 | help = 'Generates serializers and viewsets (with --viewsets) for DRF' 58 | option_list = BaseCommand.option_list + ( 59 | make_option('--viewsets', 60 | action='store_true', 61 | dest='viewsets', 62 | default=False, 63 | help='Generate viewsets'), 64 | make_option('--urls', 65 | action='store_true', 66 | dest='urls', 67 | default=False, 68 | help='Generate urls'), 69 | ) 70 | 71 | def handle(self, *args, **options): 72 | if len(args) != 1: 73 | raise CommandError('Please supply an app name') 74 | 75 | app_name = args[0] 76 | app = get_app(app_name) 77 | model_names = [model.__name__ for model in get_models(app)] 78 | 79 | if options['viewsets']: 80 | serializer_names = [model_name + 'Serializer' for model_name in model_names] 81 | class_defs = [ 82 | viewset_class_def % { 83 | 'model': name, 84 | } 85 | for name in model_names 86 | ] 87 | 88 | print(viewsets % { 89 | 'model_imports': 'from ' + app_name + '.models import ' + (', '.join(model_names)), 90 | 'serializer_imports': 'from ' + app_name + '.serializers import ' + (', '.join(serializer_names)), 91 | 'classes': ''.join(class_defs), 92 | }) 93 | 94 | elif options['urls']: 95 | view_names = [model_name + 'ViewSet' for model_name in model_names] 96 | router_defs = [ 97 | router_def % { 98 | 'model_api_name': model_name.lower() + 's', 99 | 'model': model_name, 100 | } 101 | for model_name in model_names 102 | ] 103 | 104 | print(urls % { 105 | 'view_imports': 'from ' + app_name + '.views import ' + (', '.join(view_names)), 106 | 'router_defs': ''.join(router_defs), 107 | }) 108 | 109 | else: 110 | class_defs = [ 111 | serializer_class_def % { 112 | 'model': name, 113 | } 114 | for name in model_names 115 | ] 116 | 117 | print(serializers % { 118 | 'model_imports': 'from ' + app_name + '.models import ' + (', '.join(model_names)), 119 | 'classes': ''.join(class_defs), 120 | }) 121 | --------------------------------------------------------------------------------