• Stars
    star
    273
  • Rank 150,780 (Top 3 %)
  • Language
    Python
  • License
    BSD 2-Clause "Sim...
  • Created about 9 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Django as a microframework

Django Micro

Django Micro is lightweight wrapper around Django that turns it to the microframework for writing small applications in a single file.

tl;dr: See the example_ of full-featured application.

What works

Installation

$ pip install django-micro

Quick start

Create app.py file with following content.

from django_micro import configure, route, run
from django.http import HttpResponse

DEBUG = True
configure(locals())


@route('', name='homepage')
def homepage(request):
    name = request.GET.get('name', 'World')
    return HttpResponse('Hello, {}!'.format(name))


application = run()

Run the application.

$ python app.py runserver

Note: Parent directory of the app.py file must have a valid python module name. Under the hood, Micro adds that directory to INSTALLED_APPS and uses it as a regular Django application.

Compatibility

The latest relase of django-micro supports only the latest stable release of Django. This is the only way to keep codebase of django-micro clean, without hacks for different versions of Django.

  • Django version: >=2.1
  • Python version: >=3.4

Run and deployment

On the localhost the application runs with the built-in runserver command and deploys as a standard WSGI application.

$ python app.py runserver
$ gunicorn example.app --bind localhost:8000
$ uwsgi --module example.app --http localhost:8000

This behaviour is provided by the single string: application = run() which actually just a shortcut for the following code.

if __name__ == '__main__':
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)
else:
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

Configuration

The call of the configure function must be placed at the top of your application above the definition of views, models, and imports of other modules. It may violate PEP8, but this is the only way to make it works. You canโ€™t define models or import models from another application until Django is configured.

I recommend to define all the configuration in the global namespace and call configure with locals() argument. Donโ€™t worry, configure takes only UPPERCASE variables.

from django_micro import configure

DEBUG = True

configure(locals())

Views and routes

Routing is wrapped in a single function route. You can use it as a decorator.

from django_micro import route

@route('blog/<int:year>/', name='year_archive')
def year_archive(request, year):
    return HttpResponse('hello')

Or as a regular function.

def year_archive(request):
    return HttpResponse('hello')

route('blog/<int:year>/', year_archive, name='year_archive')

Also route may be used with class-based views.

@route('blog/<int:year>/', name='year_archive')
class YearArchiveView(View):
    def get(request, year):
        return HttpResponse('hello')

# or directly
route('blog/<int:year>/', YearArchiveView.as_view(), name='year_archive')

Micro uses the new simplified routing syntax which was introduced in Django 2.0. But if youโ€™d like to use the regex-based routing syntax, just add regex=True to the decorator.

@route(r'^articles/(?P<year>[0-9]{4})/$', regex=True)
def year_archive(request, year):
    return HttpResponse('hello')

You always can access the urlpatterns for the use low-level API.

from django.urls import path
import django_micro as micro

micro.urlpatterns += [
    path('', homepage, name='homepage'),
]

Note: You can include third-party apps into Microโ€™s urlpatterns, but currently canโ€™t use Micro as a third-party app. Micro is a singleton, and you canโ€™t create more that one instance of it.

Models and migrations

Micro works well with models and migrations. Just define model in your app.py file. If you need migrations, create migrations directory next to the app.py and call python app.py makemigrations.

blog
โ”œโ”€โ”€ __init__.py
โ”œโ”€โ”€ app.py
โ””โ”€โ”€ migrations
    โ”œโ”€โ”€ __init__.py
    โ””โ”€โ”€ 0001_initial.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=255)

    class Meta:
        app_label = 'blog'

Note: You always need to set app_label attribute in Meta of your models. For example, if application placed in blog/app.py, app_label should be blog.

For getting app_label you can use get_app_label shortcut.

from django_micro import get_app_label

class Meta:
    app_label = get_app_label()

You also can place models separately in models.py file. In this case app_label is not required, but this is not a micro-way ;)

Management commands

Now you can create any management command without creating a file in yourapp/management/commands. Just defne command class in your app.py and wrap it to @command decorator.

from django.core.management.base import BaseCommand
from django_micro import command

@command('print_hello')
class PrintHelloCommand(BaseCommand):
    def handle(self, *args, **options):
        self.stdout.write('Hello, Django!')

You also can create function-based commands.

from django_micro import command

@command
def print_hello(cmd, **options):
    cmd.stdout.write('Hello, Django!')

Unfortunately, the command decorator uses a few dirty hacks for command registration. But everything works fine if you donโ€™t think about it ;)

Custom template tags

Use template for register template tags. It works same as a register object in tag library file.

from django_micro import template

@template.simple_tag
def print_hello(name):
    return 'Hello, {}!'

@template.filter
def remove_spaces(value):
    return value.replace(' ', '')

You donโ€™t need to use the load tag. All template tags are global.

Testing

No magick. Use built-in test cases.

from django.test import TestCase

class TestIndexView(TestCase):
    def test_success(self):
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)

To run tests which defined in app.py use the following command:

$ python app.py test __main__

Admin interface

Django-admin requires lots of dependencies in apps and middlewares. Weโ€™ve realized that itโ€™s not a simple way to add a huge list of apps to your config just to use the admin interface. So we added a shortcut django_admin=True to the configure function that automatically includes all the needed dependencies.

from django.contrib import admin
from django_micro import configure

configure(locals(), django_admin=True)


class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField(blank=True)
    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        app_label = get_app_label()
        ordering = ('-create_date',)


@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    pass


route('admin/', admin.site.urls)

Credits

Django Micro is based on ideas from the following projects:

More Repositories

1

golang-book

An Introduction to programming in Go
HTML
447
star
2

dendy

NES/Famicom emulator with network multiplayer
Go
314
star
3

opencart-exchange1c

[deprecated] Data exchange with 1C for OpenCart
PHP
104
star
4

opencart-webapi

[deprecated] Remotely work with the OpenCart 1.5.3+ via the REST API
PHP
79
star
5

jquery-bem

[Deprecaetd] Plugin for comfortable work with BEM DOM from jQuery
JavaScript
64
star
6

node-beml

HTML preprocessor for BEM
JavaScript
64
star
7

kivi

Dynamo-inspired distributed leader-less key-value database that has no unique features and no apparent reason to exist
Go
38
star
8

php-commerceml

Library for easy parsing CommerceML files
PHP
20
star
9

gulp-django-utils

Gulp helpers for Django
JavaScript
8
star
10

django-roxyfileman

Integrate Django with Roxy Fileman
JavaScript
7
star
11

gulp-beml

Gulp plugin for BEML processing
JavaScript
7
star
12

python-xmltag

Tool for easy creating XML and HTML documents
Python
6
star
13

gossip

Reliable decentralized broadcast protocol implemetation
Go
6
star
14

django-frontserver

Run grunt/gulp watcher and django server with a single command
Python
5
star
15

react-svgdom-loader

Import SVG as ReactDOM element
JavaScript
4
star
16

storagl

Simple storage for screenshots and other shared files with short direct links.
Python
4
star
17

van

In-app command/event bus with dependency-injection
Go
3
star
18

pdfserver

The easiest way to generate PDF from HTML
Python
3
star
19

grunt-beml

Grunt plugin for processing BEML templates
JavaScript
2
star
20

django-goodforms

Custom renderer for django.forms
Python
2
star
21

opencart-priceparser

Module for import price lists in OpenCart
PHP
2
star
22

yotaman

Console client for my.yota.ru (unofficial)
Go
2
star
23

bitbucket-stats

Team statistic from Bitbucket
Python
2
star
24

pg_migrate.sh

Schema migration tool for PostgreSQL
Shell
1
star
25

pypograph

Simple typographic tool for Python/Django
Python
1
star
26

python-langpack

Key-based translation framework for gettext haters
Python
1
star
27

6502

MOS 6502 CPU emulator
Rust
1
star
28

opencart-rossko

Module for integration OpenCart with Rossko
PHP
1
star
29

python-passbook

Generate and sign .pkpass files
Python
1
star
30

brickboy

Gameboy emulator in good old C
C
1
star
31

tdlib-docker

Docker image with precompiled tdlib
Dockerfile
1
star