Monday, April 30, 2012

Django as a micro framework, including models

The following can be used as a base when you want to avoid the normal structure Django imposes on your project, and you just want everything in a single file.

It is based on similar attempts by Ivan Sagalaev and Fahrzin Hemmati (especially this gist), and a post on stack overflow.

A thing that I consider an improvement over Fahrzin Hemmati's version is that models don't need the explicit app_label and __module__.

  1. #  
  2. # Django as a microframework skeleton, by Allan Boll, 1 May 2012  
  3. # Based on http://softwaremaniacs.org/blog/2011/01/07/django-micro-framework/en/  
  4. # and https://gist.github.com/2219751  
  5. #  
  6.   
  7. #  
  8. # Settings  
  9. #  
  10. appname = 'app'  
  11. from django.conf import settings  
  12. if not settings.configured:  
  13.     settings.configure(  
  14.         SITE_ID=1,  
  15.         TEMPLATE_DIRS=['.'],  
  16.         DATABASES = {  
  17.             'default':{  
  18.                 'ENGINE':'django.db.backends.sqlite3',  
  19.                 'NAME''db',  
  20.             }  
  21.         },  
  22.         DEBUG=True,  
  23.         TEMPLATE_DEBUG=True,  
  24.         ROOT_URLCONF = __name__,  
  25.         STATIC_URL='/static/',  
  26.         STATICFILES_DIRS=['./static/'],  
  27.         INSTALLED_APPS=(  
  28.             'django.contrib.auth',  
  29.             'django.contrib.contenttypes',  
  30.             'django.contrib.sessions',  
  31.             'django.contrib.messages',  
  32.             'django.contrib.staticfiles',  
  33.             'django.contrib.admin',   
  34.         )  
  35.     )  
  36.   
  37. #  
  38. # Models  
  39. #  
  40. from django.db import models  
  41.   
  42. # Workaround to allow models in current file  
  43. import sys  
  44. sys.modules[appname+'.'] = sys.modules[__name__]  
  45. old_module_name = sys.modules[__name__].__name__  
  46. sys.modules[__name__].__name__ = appname+'.'  
  47.   
  48. class SomeModel(models.Model):  
  49.     field_name = models.CharField(max_length=10)  
  50.   
  51. # Continuation of workaround to allow models in current file  
  52. sys.modules[__name__].__name__ = old_module_name  
  53.   
  54.   
  55. #  
  56. # Views  
  57. #  
  58. from django.shortcuts import render  
  59.   
  60. def index(request):  
  61.     out = []  
  62.     for obj in SomeModel.objects.all():  
  63.         out.append(obj.field_name)  
  64.     return render(request, 'index.html', {'s'', '.join(out)})  
  65.   
  66.   
  67. #  
  68. # URL configuration  
  69. #  
  70. from django.conf.urls.defaults import patterns, url, include  
  71.   
  72. urlpatterns = patterns('',  
  73.     (r'^$', index),  
  74. )  
  75.   
  76.   
  77. #  
  78. # Admin site  
  79. #  
  80. from django.contrib import admin  
  81. from django.contrib.auth.admin import UserAdmin, GroupAdmin  
  82. from django.contrib.auth.models import User, Group  
  83.   
  84. admin.site = admin.AdminSite()  
  85. admin.site.register(User, UserAdmin)  
  86. admin.site.register(Group, GroupAdmin)  
  87. admin.site.register(SomeModel)  
  88.   
  89. urlpatterns = patterns('',  
  90.     url(r'^admin/', include(admin.site.urls))  
  91. ) + urlpatterns  
  92.   
  93.   
  94. #  
  95. # Running  
  96. #  
  97. if __name__=='__main__':  
  98.     # Monkey patch get_app to allow models in current file  
  99.     get_app_orig = models.get_app  
  100.     def get_app(app_label,*a, **kw):  
  101.         if app_label==appname:  
  102.             return sys.modules[__name__]  
  103.         return get_app_orig(app_label, *a, **kw)  
  104.     models.get_app = get_app  
  105.   
  106.     # Add models in current file to global list of apps  
  107.     models.loading.cache.app_store[type(appname+'.models',(),{'__file__':__file__})] = appname  
  108.   
  109.     from django.core import management  
  110.     management.execute_from_command_line()