代码之家  ›  专栏  ›  技术社区  ›  agentofuser

如何编写单个文件的django应用程序?

  •  12
  • agentofuser  · 技术社区  · 16 年前

    我想在一个文件中编写一个非常小的django应用程序,需要所有适当的模块和东西,然后能够以普通的python脚本运行它,如下所示:

    $ python myapp.py
    

    你可以假设我不会呈现HTML,所以我不需要模板(我会返回 JSON 或者其他自动生成的字符串)。

    10 回复  |  直到 7 年前
        1
  •  12
  •   Rid Zeal ars    11 年前

    你可以考虑一下西蒙·威利森的图书馆:

    readme :

    djng是一个依赖于宏框架(django)的微框架。

    我对微观框架的定义:让你创建一个完整的 单个模块中的python web应用程序:

    import djng
    
    def index(request):
        return djng.Response('Hello, world')
    
    if __name__ == '__main__':
        djng.serve(index, '0.0.0.0', 8888)
    

    […]

        2
  •  12
  •   vicatcu    16 年前

    开始使用Django也很容易。以下是一个10行的单文件django webapp:

    import os
    from django.conf.urls.defaults import patterns
    from django.http import HttpResponse
    filepath, extension = os.path.splitext(__file__)
    ROOT_URLCONF = os.path.basename(filepath)
    
    def yoohoo(request):
        return HttpResponse('Yoohoo!')
    
    urlpatterns = patterns('', (r'^hello/$', yoohoo))
    

    查看我的日志 Minimal Django 详情。

        3
  •  8
  •   John Millikin    16 年前

    这是在Django中作为单个文件实现的简单CMS。它是由 Paul Bissex . 其中一些已经“打高尔夫球”了,可以做一些扩展,但它仍然相对容易阅读。

    源头已经从他的巴斯德箱子里消失了,但我保存了它:

    #!/usr/bin/env python
    """
    jngo -- The unhealthily compressed Django application.
    
    Usage: ./jngo.py
    
    Assuming a working install of Django (http://djangoproject.com/) and SQLite
    (http://sqlite.org), this script can be executed directly without any other 
    preparations -- you don't have to do `setup.py install`, it doesn't 
    need to be on your Python path, you don't need to set DJANGO_SETTINGS_MODULE,
    you don't need a webserver. You don't even need content -- the first time it's 
    run, it will create a SQLite database in the same directory as the script 
    and populate it with sample pages.
    
    Features:
    
    * Editable content on all pages
    * Dynamically generated navigation buttons
    * Optional private-access pages
    * Optional per-page comments
    * RSS feed of latest comments, with autodiscovery
    
    Author: Paul Bissex <pb@e-scribe.com>
    URL: http://news.e-scribe.com/
    License: MIT
    
    FAQS: 
    
    Q: Should I use this as an example of excellent Django coding practices?
    A: Um, no. This is pretty much the opposite of excellent Django coding practices.
    
    Q: Why did you do such a terrible thing?
    A: At first, it was just a perverse experiment. It ended up being a
    good way to refresh my memory on some Django internals, by trying all
    kinds of things that broke in weird ways.
    """
    
    #--- Settings ---
    NAME = ROOT_URLCONF = "jngo"
    DEBUG = TEMPLATE_DEBUG = True
    SITE_ID = 3000
    HOSTNAME_AND_PORT = "127.0.0.1:8000"
    DATABASE_ENGINE = "sqlite3"
    DATABASE_NAME = NAME + ".db"
    INSTALLED_APPS = ["django.contrib.%s" % app for app in "auth admin contenttypes sessions sites flatpages comments".split()]
    TEMPLATE_LOADERS = ('django.template.loaders.app_directories.load_template_source', NAME + '.template_loader')
    MIDDLEWARE_CLASSES = ('django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware')
    TEMPLATE_CONTEXT_PROCESSORS = (NAME + '.context_processor', "django.core.context_processors.auth", "django.core.context_processors.request")
    
    #--- Template loader and templates ---
    def template_loader(t, _):
        from django.template import TemplateDoesNotExist
        try:
            return {
                'base.html': """<html><head><title>{{ flatpage.title }}</title><link rel='alternate' type='application/rss+xml' href='/feed/'><style type="text/css">body { margin: 15px 50px; background: #eee; color: #343; font-family: sans-serif; } ul { padding: 0; } li { display: inline; background: #383; padding: 4px 8px; margin: 3px; } li:hover { background: #252; } dd { border-bottom: 1px dotted #666; } a { color: #383; text-decoration: none; } li a { color: #fff; } .anav { background: #141; } .rnav a { color: #ff4; } .error { color: #e22; } #footer { border-top: 1px dotted #555; font-size: 80%; color: #555; margin-top: 15px } #comments { background: #ddd; margin-top: 20px; padding: 10px; } dt { font-weight: bold; margin-top: 1em; }</style></head><body><ul>{% for nav in navs %}<li class="{% ifequal nav.url flatpage.url %}anav {% endifequal %}{% if nav.registration_required %}rnav {% endif %}"><a href="{{ nav.url }}">{{ nav.title }}</a></li>{% endfor %}</ul>{% block content %}{% endblock %}<div id="footer">{% if request.user.is_staff %}<a href="javascript:(function(){if(typeof%20ActiveXObject!='undefined'){var%20x=new%20ActiveXObject('Microsoft.XMLHTTP')}else%20if(typeof%20XMLHttpRequest!='undefined'){var%20x=new%20XMLHttpRequest()}else{return;}x.open('GET',location.href,false);x.send(null);try{var%20type=x.getResponseHeader('x-object-type');var%20id=x.getResponseHeader('x-object-id');}catch(e){return;}document.location='/admin/'+type.split('.').join('/')+'/'+id+'/';})()">Edit this page</a> (as staff user <a href="/admin/">{{ request.user }}</a>)<br>{% endif %}Powered by <a href="http://djangoproject.com/">Django</a> {{ version }}<br></div></body></html>""",
                'flatpages/default.html': """{% extends "base.html" %}{% load comments %}{% block content %}<h1>{{ flatpage.title }}</h1>{{ flatpage.content }}{% if flatpage.enable_comments %}<div id="comments">{% get_free_comment_list for flatpages.flatpage flatpage.id as comments %}<h3>Comments!</h3><dl>{% for comment in comments %}{% include "comment.html" %}{% endfor %}</dl>{% free_comment_form for flatpages.flatpage flatpage.id %}</div>{% endif %}{% endblock %}""",
                'comments/free_preview.html': """{% extends "base.html" %}{% block content %}<h1>Comment preview</h1><dl>{% include "comment.html" %}</dl><form action='.' method='post'><input type='hidden' name='gonzo' value='{{ hash }}'><input type='hidden' name='options' value='{{ options }}'><input type='hidden' name='comment' value='{{ comment.comment }}'><input type='hidden' name='person_name' value='{{ comment.person_name }}'><input type='hidden' name='target' value='{{ target }}'><input type='submit' name='post' value='Post comment'></form>{% endblock %}""", 
                'comments/posted.html': """{% extends "base.html" %}{% block content %}<h1>Comment posted</h1><p>Thanks for posting!</p> <p><a href='{{ object.get_absolute_url }}'>Continue</a></p>{% endblock %}""",
                'comment.html': """<dt>{{ comment.person_name }} said:</dt> <dd>{{ comment.comment }}</dd>""",
                'registration/login.html': """{% extends "base.html" %}{% block content %}{% if form.has_errors %}<h2 class="error">Wrong!</h2>{% endif %}<p>This page is top secret, so you need to log in.</p><form method="post" action=".">Username: {{ form.username }}<br>Password: {{ form.password }}<br><input type="submit" value="login"><input type="hidden" name="next" value="{{ next }}"></form>{% endblock %}"""
                }[t], ''
        except KeyError:
            raise TemplateDoesNotExist
    template_loader.is_usable = True
    
    #--- Context processor ---
    def context_processor(request):
        from django.contrib.flatpages.models import FlatPage
        navs = FlatPage.objects.all().values("url", "title", "registration_required")
        from django import get_version
        return { 'navs': navs, 'version': get_version() }
    
    #--- RSS Feed (hacky wrapper function needed because of jngo's one-file setup) ---
    def feed(*args, **kwargs):
        from django.contrib.comments.feeds import LatestFreeCommentsFeed
        return LatestFreeCommentsFeed(*args, **kwargs)
    
    #--- URLconf ---
    from django.conf.urls.defaults import *
    urlpatterns = patterns("", 
        (r"^admin/", include("django.contrib.admin.urls")), 
        (r"^comments/", include("django.contrib.comments.urls.comments")), 
        (r"^accounts/login/$", "django.contrib.auth.views.login"),
        (r"^(feed)/$", "django.contrib.syndication.views.feed", {'feed_dict': {'feed': feed}}),
        )
    
    #--- Execution ---
    if __name__ == "__main__":
        import os, sys
        from django.core.management import call_command
        here = os.path.dirname(__file__)
        sys.path.append(here)
        os.environ["DJANGO_SETTINGS_MODULE"] = NAME
        if not os.path.isfile(os.path.join(here, DATABASE_NAME)):
            from django.contrib.auth.create_superuser import createsuperuser
            from django.contrib.flatpages.models import FlatPage
            from django.contrib.sites.models import Site
            call_command("syncdb")
            createsuperuser()
            site_obj = Site.objects.create(id=SITE_ID, domain=HOSTNAME_AND_PORT)
            FlatPage.objects.create(url="/", title="Home", content="Welcome to %s!" % NAME).sites.add(site_obj)
            FlatPage.objects.create(url="/stuff/", enable_comments=True, title="Stuff", content="This is a page about stuff.").sites.add(site_obj)
            FlatPage.objects.create(url="/topsecret/", title="Top Secret", content="Now you know.", registration_required=True).sites.add(site_obj)
        call_command("runserver", HOSTNAME_AND_PORT)
    
        4
  •  4
  •   un1t    11 年前

    用Django 1.7测试

    #!/usr/bin/env python
    import os
    import sys
    from django.conf import settings
    from django.conf.urls import patterns, include, url
    from django.http import HttpResponse
    
    filename = os.path.splitext(os.path.basename(__file__))[0]
    
    urlpatterns = patterns('',
        url(r'^$', '%s.home' % filename, name='home'),
    )
    
    def home(request):
        return HttpResponse('hello')
    
    if __name__ == "__main__":
        settings.configure(
            DEBUG=True,
            MIDDLEWARE_CLASSES = [],
            ROOT_URLCONF = filename
        )
    
        from django.core.management import execute_from_command_line
        execute_from_command_line([sys.argv[0], 'runserver'])
    
        5
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    16 年前

    那么你需要的不是姜戈。 你需要的就是 micropy 做。

        6
  •  2
  •   k4ml    14 年前

    在Web上发现的大多数单文件django示例缺少对模型的支持,因为django以某种方式要求在每个模型的models.py文件中声明模型。 INSTALLED_APP .最后,我找到了一个例子,其中包括对模型的支持:

    http://fahhem.com/blog/2011/10/django-models-without-apps-or-everything-django-truly-in-a-single-file/

    链接到django wiki上的模型创建也值得一读。以及完整的代码,包括管理:

    https://gist.github.com/2219751

        7
  •  1
  •   Bite code    16 年前

    最简单的方法是在一个文件中模拟Django项目arbo。因此,在一个模块中,确保:

    Root_module :
        Root_module.settings
        Root_module.urls
        Root_module.app_in_the_module
        Root_module.app_in_the_module.models
        Root_module.app_in_the_module.views
    

    那么代码就是一个普通的Django项目。你必须知道的是,姜戈不需要任何东西在一个特定的地方。标准名称和路径处于节拍、约定状态,最坏情况下,是阻止定义设置的快捷方式。

    如果你对Django非常了解,你甚至不需要模仿ARBO,只需编写Django应用程序,让来自上述模块的所有数据以它们应该的方式互连。

        8
  •  1
  •   Community Mohan Dere    9 年前

    John's answer 引用 jngo app 保罗·比塞克斯的作品令人印象深刻,但在姜戈1.7的作品中却被打破了。

    我挖了很多洞 created 𝜇Django 演示如何在单个python文件中使用sqlite数据库运行模型类。我计划用它来发布关于django模型类的问题。如果你想要JNGO的其他部分,你可以把它们移植到这个上面。法尔辛·赫马蒂发布了 an example 这看起来很相似,包括完整的django:Web服务器、模型、管理命令。我还没试过。

    # Tested with Django 1.9.2
    import sys
    
    import django
    from django.apps import apps
    from django.apps.config import AppConfig
    from django.conf import settings
    from django.db import connections, models, DEFAULT_DB_ALIAS
    from django.db.models.base import ModelBase
    
    NAME = 'udjango'
    
    
    def main():
        setup()
    
        class Person(models.Model):
            first_name = models.CharField(max_length=30)
            last_name = models.CharField(max_length=30)
    
        syncdb(Person)
    
        p1 = Person(first_name='Jimmy', last_name='Jones')
        p1.save()
        p2 = Person(first_name='Bob', last_name='Brown')
        p2.save()
    
        print ', '.join([p.first_name for p in Person.objects.all()])
    
    
    def setup():
        DB_FILE = NAME + '.db'
        with open(DB_FILE, 'w'):
            pass  # wipe the database
        settings.configure(
            DEBUG=True,
            DATABASES={
                DEFAULT_DB_ALIAS: {
                    'ENGINE': 'django.db.backends.sqlite3',
                    'NAME': DB_FILE}},
            LOGGING={'version': 1,
                     'disable_existing_loggers': False,
                     'formatters': {
                        'debug': {
                            'format': '%(asctime)s[%(levelname)s]'
                                      '%(name)s.%(funcName)s(): %(message)s',
                            'datefmt': '%Y-%m-%d %H:%M:%S'}},
                     'handlers': {
                        'console': {
                            'level': 'DEBUG',
                            'class': 'logging.StreamHandler',
                            'formatter': 'debug'}},
                     'root': {
                        'handlers': ['console'],
                        'level': 'WARN'},
                     'loggers': {
                        "django.db": {"level": "WARN"}}})
        app_config = AppConfig(NAME, sys.modules['__main__'])
        apps.populate([app_config])
        django.setup()
        original_new_func = ModelBase.__new__
    
        @staticmethod
        def patched_new(cls, name, bases, attrs):
            if 'Meta' not in attrs:
                class Meta:
                    app_label = NAME
                attrs['Meta'] = Meta
            return original_new_func(cls, name, bases, attrs)
        ModelBase.__new__ = patched_new
    
    
    def syncdb(model):
        """ Standard syncdb expects models to be in reliable locations.
    
        Based on https://github.com/django/django/blob/1.9.3
        /django/core/management/commands/migrate.py#L285
        """
        connection = connections[DEFAULT_DB_ALIAS]
        with connection.schema_editor() as editor:
            editor.create_model(model)
    
    main()
    
        9
  •  0
  •   monkut    16 年前

    你也可以看看 web.py . ( Tutorial )

    这是另一个紧凑但功能强大的Web框架。

    主页上的示例:

    import web
    
    urls = ('/(.*)', 'hello')
    app = web.application(urls, globals())
    
    class hello:        
        def GET(self, name):
            if not name: 
                name = 'world'
            return 'Hello, ' + name + '!'
    
    if __name__ == "__main__":
        app.run()
    
        10
  •  0
  •   djvg Carl Meyer    7 年前

    下面的代码表示一个文件django应用程序。它是 无耻地抄袭 this interesting book chapter ,并且可以使用运行 python singlefile.py runserver (如果文件被调用 singlefile.py )至少在Django 1.9和2.0中工作。

    import sys
    from django.conf import settings
    
    settings.configure(
        DEBUG=True,
        SECRET_KEY='thisisthesecretkey',
        ROOT_URLCONF=__name__,
        MIDDLEWARE_CLASSES=('django.middleware.common.CommonMiddleware',
                            'django.middleware.csrf.CsrfViewMiddleware',
                            'django.middleware.clickjacking.XFrameOptionsMiddleware')
    )
    
    from django.conf.urls import url
    from django.http import HttpResponse
    
    
    def index(request): return HttpResponse('Hello World')
    
    urlpatterns = (url(r'^$', index), )
    
    if __name__ == "__main__":
        from django.core.management import execute_from_command_line
        execute_from_command_line(sys.argv)
    

    …它看起来很像UN1T的答案,除了一些 details .