Last active
March 8, 2016 05:03
-
-
Save jamesmcnamara/da30e29d0c57372b1c68 to your computer and use it in GitHub Desktop.
Rest Skeleton
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from operator import attrgetter | |
import os | |
from django.db.models import Model | |
from django.core.management.base import BaseCommand | |
from rest_framework.serializers import ModelSerializer | |
from rest_framework.viewsets import ModelViewSet | |
from my_app import serializers, models, views | |
def subclasses_in_module(module, superclass): | |
return set(filter(lambda obj: obj.__module__ == module, superclass.__subclasses__())) | |
def fields(model): | |
return tuple(map(attrgetter("name"), model._meta.get_fields(include_parents=False))) | |
def find_related_models(module, name, ParentClass, model_getter): | |
module = "{module}.{name}".format(module=module, name=name) | |
subclasses = subclasses_in_module(module, ParentClass) | |
return {model_getter(obj) for obj in subclasses} | |
class Command(BaseCommand): | |
TEMPLATES = {"serializers": """ | |
class {name}Serializer(serializers.ModelSerializer): | |
class Meta: | |
model = models.{name} | |
fields = {fields} | |
""", | |
"views": """ | |
class {name}ViewSet(viewsets.ModelViewSet): | |
queryset = models.{name}.objects.all() | |
serializer_class = serializers.{name}Serializer | |
"""} | |
# Each tuple contains | |
# 1. Name of module to search for objects | |
# 2. Parent class to cross reference each object with, and | |
# 3. function that given an idiomatic subclass of 2, will extract the related model | |
SKELETON_META = (("serializers", ModelSerializer, attrgetter("Meta.model")), | |
("views", ModelViewSet, attrgetter("serializer_class.Meta.model"))) | |
def add_arguments(self, parser): | |
parser.add_argument("module") | |
def handle(self, *args, **options): | |
module = options["module"] | |
model_module = "%s.models" % module | |
models = subclasses_in_module(model_module, Model) | |
for name, ParentClass, model_getter in self.SKELETON_META: | |
related_models = find_related_models(module, name, ParentClass, model_getter) | |
self.write_skeleton(models - related_models, module, name) | |
def write_skeleton(self, models, module, template_name): | |
cur_dir = os.path.join(os.getcwd(), module) | |
with open(os.path.join(cur_dir, "{}.py".format(template_name)), "a") as f: | |
for model in models: | |
model_name = model._meta.object_name | |
self.stdout.write("Creating %s for %s" % (template_name[:-1], model_name)) | |
f.write(self.TEMPLATES[template_name].format(name=model_name, fields=fields(model))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rest Skeleton Generator
Django Rest Framework command to add default
Serializer
s andViewSet
implementations for all models in an app that don't already have implementations.Install it in
<your_app_dir>/management/commands/rest_skeleton.py
and invoke it with