Modern architecture for a CRUD-Application in Django without an SPA-Frontend

Django is an opinionated framework. It recommends a structure for how to build the application and as a developer you should follow. However, from a frontend perspective it is very traditional with the strict differentiation of views, templates and styles – in contrast to SPA-technologies like Angular2+, React or Vue which uses a component-approach.

If you have a more or less pure CRUD-application, it can make sense to rely on Django completely instead of programming an SPA-Frontend. Django provides a lot of features out of the box in a good structured manner. BUT the strict separation most often lead to complex views and templates after some time with a lot of violations of the Single Responsibility Principle, although at the beginning everything seems fine.

In this article, I will show an alternative Django-structure on how to implement a component-approach.

Components and Pages as Architecture Foundation

The structure for components in Django could look as follows:

Component structure in Django

In every module – in this case “sme_profile” two new folders are added: components and pages. Pages are the traditional views with their template. But, in a component-approach, these pages would contain a lot of components. For these, the components are introduced: Django templates (with associated styles) which will be included into the page template by {% include %}.

  • Pages are components, but with a Django-view associated
  • Components only consist of templates – styles

For styling, BEM (Block – Element – Modifier) should be used, so that we also follow the component-approach in this aspect.

Implementation

Templates

One of the most important things for a component-approach is the fact, that all files are together in a folder for a component, making the component self-contained and closed. This is quite easy in Django, with a minimal change in the settings: For each module, enter

TEMPLATES = [
    {
        'DIRS': [
            os.path.join(BASE_DIR, '##module##', 'pages'),
            os.path.join(BASE_DIR, '##module##', 'components'),

In this way, the templates will be found by django. It is definitely a flaw, that for each module, the templates must be registered, but you could also extends Django functionality here.

Routing

The routing itself – via urls.py – will not change, but you have to use more imports than before, since the views are not longer in a single python-module-file. For example:

from sme_profile.pages.sme_list.sme_list import SubjectMatterExpertListView
from sme_profile.pages.sme_profile.sme_profile import SubjectMatterExpertDetailUserView, SubjectMatterExpertDetailView
from sme_profile.pages.sme_form.sme_form import SubjectMatterExpertCreateView, SubjectMatterExpertUpdateView