Coder Social home page Coder Social logo

django-micro's Introduction

Django Micro

image

image

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:

django-micro's People

Contributors

babykick avatar barseghyanartur avatar johnfraney avatar kosc avatar maxpoletaev avatar yarlson avatar zodman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-micro's Issues

Add admin panel

I think it would be great to add lightweight integration of admin panel.

This works serverless with zappa

We're running a django-micro app serverless on AWS Lambda using Zappa 👍

Only things needed was to use "app.application" as app_function WSGI function and to not specify a django_settings module in zappa_config.json; and then apply the sys.path import fix from django_zappa.py.

It also runs fine without database by disabling all database related apps and functionality.

This is a pretty neat way to run lightweight services while keeping commonality with our existing full fat Django apps and dependencies!

FYI 😉

New idea for admin panel

What if we will right:

configure(locals(), admin_on='admin')

instead of:

configure(locals(), django_admin=True)

So, in that case we will make it even more easy to enable admin and add route.

Missing TEMPLATE_DIRS in README example

Just did a copy/paste of the README, and go this:

% python app.py runserver
Traceback (most recent call last):
  File "app.py", line 5, in <module>
    configure(locals())
  File "/Users/jbbarth/.virtualenvs/elastictac/lib/python2.7/site-packages/django_micro.py", line 81, in configure
    'DIRS': config_dict.pop('TEMPLATE_DIRS'),
KeyError: 'TEMPLATE_DIRS'

Having a TEMPLATE_DIRS = [] above the configure(locals()) call seems to fix it. I'm running django-micro-1.4.1 with django-1.10.7 at the moment.

Thanks for your work anyway, I'm giving it a try today and I already like it :-)

`migration --run-syncdb` doesn't create models

https://github.com/django/django/blob/a77f21880dfb0631ea0adb22d47909915cbfc3a9/django/core/management/commands/migrate.py#L268-L276

        # Build the manifest of apps and models that are to be synchronized.
        all_models = [
            (
                app_config.label,
                router.get_migratable_models(app_config, connection.alias, include_auto_created=False),
            )
            for app_config in apps.get_app_configs()
            if app_config.models_module is not None and app_config.label in app_labels
        ]

It seems that app_config.models_module is None for django-micro apps

Reproduction:

Problem Repro
only works with app_name and migrate https://pyfiddle.io/fiddle/f5a6361a-49df-4c79-8d3c-f94cadb94b6a
makemigrations needs app_name https://pyfiddle.io/fiddle/ca85bac0-b44b-4810-9a4f-4afd9f6440a4
migrate sync_db=True doesn't work https://pyfiddle.io/fiddle/2512299d-6fdb-4e36-9612-96844d4122f9

Add tests

The project doesn't seem to have tests and test automation.

Would you be interested to have that and packaging automation added via a PR?

No module named "example", when I try to run application from example

(.venv) ~/sources/wisdomchest/django-micro/example$ python app.py migrate
Traceback (most recent call last):
File "app.py", line 19, in
configure(locals(), django_admin=True)
File "/home/roman/sources/wisdomchest/.venv/lib/python3.6/site-packages/django_micro.py", line 83, in configure
_create_app(inspect.stack()) # load application from parent module
File "/home/roman/sources/wisdomchest/.venv/lib/python3.6/site-packages/django_micro.py", line 34, in _create_app
import_module(app_module)
File "/home/roman/sources/wisdomchest/.venv/lib/python3.6/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 994, in _gcd_import
File "", line 971, in _find_and_load
File "", line 953, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'example'

If I try to import this module from +1 level of file system then importing work correctly either running with uwsgi.
Uwsgi backtrace from example folder shows the same error.

I found that U cannot import module when U stay in imported module folder. It looks like a reason.

Django 2.0.8, python 3.6

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.