Skip to main content

Django only html and views.py

Djangoは設定とか面倒なので、簡単にする方法を考えました。 app1,2,3,4...と量産するアプリを例に、コードをかきます。

まず、myprojectというprojectを作ります

  • django-admin startproject myproject
  • cd myproject
  • python manage.py startapp app1 : app2,3,4も同様に...
  • INSTALLED_APPS += ['app%s'%s for s in [1,2,3,4]] myproject/settings.py 最後に追加

次に、下の様にディレクトリを作る (各appはviews.py以外消す)

C:.
├─app1
│ └─views.py
├─app2
│ └─views.py
│ (...同様に3,4と作る)
├─templates
│ ├─app1
│ └─app2
│ (...同様に3,4と作る)
myproject
├─settings.py
└─urls.py

myproject/urls.pyの最後に追加します。

for i, app in enumerate(['app%s'%s for s in [1,2,3,4]]):
views_name = app + ".views"
views_lib = importlib.import_module(views_name)
for name, cls in views_lib.__dict__.items():
if name.lower() == "fromdirview":
url = "%s/%s"%( i, cls.url() )
urlpatterns += [path(url, cls.as_view()]

各appのviews.pyに次のViewを追加します。

class FromDirView(TemplateView):
def __init__(self):
self.name = osp.basename(osp.dirname(osp.abspath(__file__)))
self.path = osp.join(settings.TEMPLATES[0]['DIRS'][0], self.name)
self.pages = self.make_grouped_pages()
self.page = osp.join(self.path, 'test.html')

def url():
return ''

def get(self, request, *args, **kwargs):
page = request.GET['p'] if 'p' in request.GET else ''
self.template_name = self.pages[page] if page in self.pages else self.page
return super().get(request, *args, **kwargs)

def get_context_data(self):
context = super().get_context_data()
context['pages'] = self.pages.keys()
return context

def make_grouped_pages(self):
paths = {}
for fname in sorted(os.walk(self.path)):
page = osp.basename(fname[0])
if any([ f==page+'.html' for f in fname[2] ]):
paths[page] = osp.join(fname[0], page+'.html')
return paths

FromDirView で用いた make_grouped_pagesは、 urlの?p=で指定した名前と同じディレクトリがtemplatesディレクトリ内にあり、 かつその内に同じ名前+.htmlファイルがある場合、そのhtmlファイルをtemplateに指定します。 (ospはimport os.path as ospで略して利用しています。) settings.pyの変数は from django.conf import settings で取得できます。

app1/test.htmlは次の様に追加しておきます。

{% for p in pages%}
<a href="?p={{p}}">{{p}} </a>
{% endfor %}