Django Clean Arch
Django Clean Arch
in Django
What’s the problem?
• Where do we put business logic?
• Have caller (eg view) inject adapters into use case layer
Source: “The Clean Architecture” blog post by Bob Martin
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
What is clean architecture?
1. Independent of Frameworks. The architecture does not depend
on the existence of some library of feature laden software. This
allows you to use such frameworks as tools, rather than having to
cram your system into their limited constraints.
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
A simple use case
notes/use_cases.py:
class UseCases():
def __init__(self, storage):
self.storage = storage Use cases class exists for the sole purpose
of injecting adapters
def create_note(self, title, body):
Use cases use entities, and don’t know about
note = Note(title, body)
return self.storage.save_note(note) Django models
notes/entities.py:
adapters/django_storage.py:
class DjangoStorage():
The storage layer takes entities & returns
def save_note(self, note):
entities, hides storage details
django_note = Note.from_entity(note)
django_note.save()
return django_note.to_entity()
…and the view
from django.http import JsonResponse
storage = DjangoStorage()
use_cases = UseCases(storage)
def create_board(request):
req_data = json.loads(request.body)
board = use_cases.create_board(
title=req_data['title'],
body=req_data['body']
)
return JsonResponse(
{'board': board.to_dict()},
status=200
)
Use case abstractions
class NoteActions():
def __init__(self, storage, logging):
self.use_cases = NoteUseCases(storage)
self.logging = logging
@log('board.create')
def create_board(self, *args, **kwargs):
return self.use_cases.create_board(*args, **kwargs)
@log('board.delete')
@permission('delete')
def delete_board(self, *args, **kwargs):
return self.use_cases.delete_board(*args, **kwargs)
Use case abstractions
from rentomatic.shared import response_object as res
class UseCase(object):
class StorageRoomListUseCase(uc.UseCase):
• https://8thlight.com/blog/uncle-bob/2012/08/13/the-
clean-architecture.html
• http://blog.thedigitalcatonline.com/blog/2016/11/14/
clean-architectures-in-python-a-step-by-step-example/
• https://www.youtube.com/watch?v=DJtef410XaM