Skip to content

Instantly share code, notes, and snippets.

@jamesmcnamara
Last active March 8, 2016 05:03
Show Gist options
  • Save jamesmcnamara/da30e29d0c57372b1c68 to your computer and use it in GitHub Desktop.
Save jamesmcnamara/da30e29d0c57372b1c68 to your computer and use it in GitHub Desktop.
Rest Skeleton
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)))
@jamesmcnamara
Copy link
Author

Rest Skeleton Generator

Django Rest Framework command to add default Serializers and ViewSet 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

python manage.py rest_skeleton <your_app_name>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment