Package: django-rest-witchcraft
Django REST WitchcraftDjango REST Framework integration with SQLAlchemydjango-rest-witchcraft is an extension for Django REST Framework that adds support for SQLAlchemy. It aims to provide
a similar development experience to building REST api’s with Django REST Framework with Django ORM, except with
SQLAlchemy.Installationpip install django-rest-witchcraftQuick StartFirst up, lets define some simple models:importsqlalchemyassaimportsqlalchemy.orm# noqafromsqlalchemy.ext.declarativeimportdeclarative_baseengine=sa.create_engine('sqlite:///:memory:',echo=True)session=sa.orm.scoped_session(sa.orm.sessionmaker(bind=engine))Base=declarative_base()Base.query=session.query_property()classGroup(Base):__tablename__='groups'id=sa.Column(sa.Integer(),primary_key=True,autoincrement=True)name=sa.Column(sa.String())classUser(Base):__tablename__='users'id=sa.Column(sa.Integer(),primary_key=True,autoincrement=True)name=sa.Column(sa.String())fullname=sa.Column(sa.String())password=sa.Column(sa.String())_group_id=sa.Column('group_id',sa.Integer(),sa.ForeignKey('groups.id'))group=sa.orm.relationship(Group,backref='users')classAddress(Base):__tablename__='addresses'id=sa.Column(sa.Integer(),primary_key=True,autoincrement=True)email_address=sa.Column(sa.String(),nullable=False)_user_id=sa.Column(sa.Integer(),sa.ForeignKey('users.id'))user=sa.orm.relationship(User,backref='addresses')Base.metadata.create_all(engine)Nothing fancy here, we have aUserclass that can belongs to aGroupinstance and has manyAddressinstancesThis serializer can handle nested create, update or partial update operations.Lets define a serializer forUserwith all the fields:classUserSerializer(serializers.ModelSerializer):classMeta:model=Usersession=sessionfields='__all__'This will create the following serializer for us:>>> serializer = UserSerializer()

>>> serializer
UserSerializer():
    id = IntegerField(allow_null=False, help_text=None, label='Id', required=True)
    name = CharField(allow_null=True, help_text=None, label='Name', max_length=None, required=False)
    fullname = CharField(allow_null=True, help_text=None, label='Fullname', max_length=None, required=False)
    password = CharField(allow_null=True, help_text=None, label='Password', max_length=None, required=False)
    group = GroupSerializer(allow_null=True, is_nested=True, required=False):
        id = IntegerField(allow_null=False, help_text=None, label='Id', required=False)
        name = CharField(allow_null=True, help_text=None, label='Name', max_length=None, required=False)
    addresses = AddressSerializer(allow_null=True, many=True, required=False):
        id = IntegerField(allow_null=False, help_text=None, label='Id', required=False)
        email_address = CharField(allow_null=False, help_text=None, label='Email_address', max_length=None, required=True)
    url = UriField(read_only=True)Lets try to create aUserinstance with our brand new serializer:serializer=UserSerializer(data={'name':'shosca','password':'swordfish',})serializer.is_valid()serializer.save()user=serializer.instanceThis will create the following user for us:>>> user
User(_group_id=None, id=1, name='shosca', fullname=None, password='swordfish')Lets try to update our userUserinstance and change its password:serializer=UserSerializer(user,data={'name':'shosca','password':'password',})serializer.is_valid()serializer.save()user=serializer.instanceOur user now looks like:>>> user
User(_group_id=None, id=1, name='shosca', fullname=None, password='password')Lets try to update ourUserinstance again, but this time lets change its password only:serializer=UserSerializer(user,data={'password':'swordfish',},partial=True)serializer.is_valid()serializer.save()user=serializer.instanceThis will update the following user for us:>>> user
User(_group_id=None, id=1, name='shosca', fullname=None, password='swordfish')Our user does not belong to aGroup, lets fix that:group=Group(name='Admin')session.add(group)session.flush()serializer=UserSerializer(user,data={'group':{'id':group.id}})serializer.is_valid()serializer.save()user=serializer.instanceNow, our user looks like:>>> user
User(_group_id=1, id=1, name='shosca', fullname=None, password='swordfish')

>>> user.group
Group(id=1, name='Admin')We can also change the name of our user’s group through the user using nested updates:classUserSerializer(serializers.ModelSerializer):classMeta:model=Usersession=sessionfields='__all__'extra_kwargs={'group':{'allow_nested_updates':True}}serializer=UserSerializer(user,data={'group':{'name':'Super User'}},partial=True)serializer.is_valid()user=serializer.save()Now, our user looks like:>>> user
User(_group_id=1, id=1, name='shosca', fullname=None, password='swordfish')

>>> user.group
Group(id=1, name='Super User')We can use this serializer in a viewset like:fromrest_witchcraftimportviewsetsclassUserViewSet(viewsets.ModelViewSet):queryset=User.queryserializer_class=UserSerializerAnd we can register this viewset in oururls.pylike:fromrest_witchcraftimportroutersrouter=routers.DefaultRouter()router.register(r'users',UserViewSet)urlpatterns=[...url(r'^',include(router.urls)),...]