Commits

Sylvain Hellegouarch committed 9c35b4b

support for django 1.4. cherrypy now serves static files from django's contrib rather than locally. added websocket support for extra fun

  • Participants
  • Parent commits c899e1b

Comments (0)

Files changed (88)

frameworks/django_/__init__.py

 In order to configure the application, we use the `settings.configure(...)`
 function provided by Django.
 
-Finally, since the CherryPy WSGI server doesn't offer a log
+Since the CherryPy WSGI server doesn't offer a log
 facility, we add a straightforward WSGI middleware to do so, based
 on the CherryPy built-in logger. Obviously any other log middleware
 can be used instead.
 
+For some extra fun we demonstrate how to add WebSocket support
+to your Django application. This requires ws4py:
+
+https://github.com/Lawouach/WebSocket-for-Python
+
 Note this application admin site uses the following credentials:
 admin/admin
 
     from djangoplugin import DjangoAppPlugin
     DjangoAppPlugin(cherrypy.engine, settings_module='myapp.settings').subscribe()
 
+    from ws4py.server.cherrypyserver import WebSocketPlugin
+    WebSocketPlugin(cherrypy.engine).subscribe()
+
     cherrypy.quickstart()

frameworks/django_/djangoplugin.py

 # -*- coding: utf-8 -*-
 import imp
 import os, os.path
+import urlparse
 
 import cherrypy
 from cherrypy.process import plugins
 
+import django
 from django.conf import settings
 from django.core.handlers.wsgi import WSGIHandler
 
         cherrypy.log("Loading and serving the Django application")
         cherrypy.tree.graft(self.wsgi_http_logger(WSGIHandler()))
         settings = self.load_settings()
+
+        # App specific static handler
         static_handler = cherrypy.tools.staticdir.handler(
             section="/",
             dir=os.path.split(settings.STATIC_ROOT)[1],
         )
         cherrypy.tree.mount(static_handler, settings.STATIC_URL)
 
+        # Admin static handler. From django's internal (django.core.servers.basehttp)
+        admin_static_dir = os.path.join(django.__path__[0], 'contrib', 'admin', 'static')
+        admin_static_handler = cherrypy.tools.staticdir.handler(
+            section='/',
+            dir='admin',
+            root=admin_static_dir
+        )
+        cherrypy.tree.mount(admin_static_handler, urlparse.urljoin(settings.STATIC_URL, 'admin'))
+
     def load_settings(self):
         """ Loads the Django application's settings. You can
         override this method to provide your own loading

frameworks/django_/myapp/middleware.py

+# -*- coding: utf-8 -*-
+import cherrypy
+from django.http import HttpResponse
+from ws4py.server.cherrypyserver import WebSocketTool
+from ws4py.websocket import WebSocket
+
+__all__ = ['WebSocketMiddleware']
+
+class WebSocketBroadcaster(WebSocket):
+    def received_message(self, m):
+        cherrypy.engine.publish('websocket-broadcast', m)
+
+    def closed(self, code, reason="A client left the room without a proper explanation."):
+        cherrypy.engine.publish('websocket-broadcast', reason)
+
+class WebSocketMiddleware(object):
+    """
+    Middleware that initiates the websocket handshake
+    by extracting data from the Django request and
+    feeding the CherryPy request used by the ws4py component.
+    """
+    def process_request(self, request):
+        if request.path == '/ws':
+            try:
+                meta = request.META
+                req = cherrypy.serving.request
+
+                headers = req.headers
+                headers['Upgrade'] = meta['HTTP_UPGRADE']
+                headers['Connection'] = meta['HTTP_CONNECTION']
+                headers['Sec-WebSocket-Version'] = meta['HTTP_SEC_WEBSOCKET_VERSION']
+                headers['Sec-WebSocket-Key'] = meta['HTTP_SEC_WEBSOCKET_KEY']
+                headers['Sec-WebSocket-Extensions'] = meta['HTTP_SEC_WEBSOCKET_EXTENSIONS']
+
+                req.wsgi_environ = meta
+                req.rfile = meta['wsgi.input']
+
+                # Performs the whole websocket handshake process
+                wstool = WebSocketTool()
+                wstool.upgrade(handler_cls=WebSocketBroadcaster)
+                wstool.complete()
+                wstool.cleanup_headers()
+                wstool.start_handler()
+
+                
+                resp = cherrypy.serving.response
+                response = HttpResponse(status=resp.status)
+                for header in resp.headers:
+                    response[header] = resp.headers[header]
+
+                return response
+            except:
+                cherrypy.log(traceback=True)

frameworks/django_/myapp/myapp.db

Binary file modified.

frameworks/django_/myapp/settings.py

     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
+    'myapp.middleware.WebSocketMiddleware'
 )
 ROOT_URLCONF = 'myapp.urls'
 TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)

frameworks/django_/myapp/static/admin/css/base.css

-/*
-    DJANGO Admin styles
-*/
-
-body {
-    margin: 0;
-    padding: 0;
-    font-size: 12px;
-    font-family: "Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif;
-    color: #333;
-    background: #fff;
-}
-
-/* LINKS */
-
-a:link, a:visited {
-    color: #5b80b2;
-    text-decoration: none;
-}
-
-a:hover {
-    color: #036;
-}
-
-a img {
-    border: none;
-}
-
-a.section:link, a.section:visited {
-    color: white;
-    text-decoration: none;
-}
-
-/* GLOBAL DEFAULTS */
-
-p, ol, ul, dl {
-    margin: .2em 0 .8em 0;
-}
-
-p {
-    padding: 0;
-    line-height: 140%;
-}
-
-h1,h2,h3,h4,h5 {
-    font-weight: bold;
-}
-
-h1 {
-    font-size: 18px;
-    color: #666;
-    padding: 0 6px 0 0;
-    margin: 0 0 .2em 0;
-}
-
-h2 {
-    font-size: 16px;
-    margin: 1em 0 .5em 0;
-}
-
-h2.subhead {
-    font-weight: normal;
-    margin-top: 0;
-}
-
-h3 {
-    font-size: 14px;
-    margin: .8em 0 .3em 0;
-    color: #666;
-    font-weight: bold;
-}
-
-h4 {
-    font-size: 12px;
-    margin: 1em 0 .8em 0;
-    padding-bottom: 3px;
-}
-
-h5 {
-    font-size: 10px;
-    margin: 1.5em 0 .5em 0;
-    color: #666;
-    text-transform: uppercase;
-    letter-spacing: 1px;
-}
-
-ul li {
-    list-style-type: square;
-    padding: 1px 0;
-}
-
-ul.plainlist {
-    margin-left: 0 !important;
-}
-
-ul.plainlist li {
-    list-style-type: none;
-}
-
-li ul {
-    margin-bottom: 0;
-}
-
-li, dt, dd {
-    font-size: 11px;
-    line-height: 14px;
-}
-
-dt {
-    font-weight: bold;
-    margin-top: 4px;
-}
-
-dd {
-    margin-left: 0;
-}
-
-form {
-    margin: 0;
-    padding: 0;
-}
-
-fieldset {
-    margin: 0;
-    padding: 0;
-}
-
-blockquote {
-    font-size: 11px;
-    color: #777;
-    margin-left: 2px;
-    padding-left: 10px;
-    border-left: 5px solid #ddd;
-}
-
-code, pre {
-    font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
-    background: inherit;
-    color: #666;
-    font-size: 11px;
-}
-
-pre.literal-block {
-    margin: 10px;
-    background: #eee;
-    padding: 6px 8px;
-}
-
-code strong {
-    color: #930;
-}
-
-hr {
-    clear: both;
-    color: #eee;
-    background-color: #eee;
-    height: 1px;
-    border: none;
-    margin: 0;
-    padding: 0;
-    font-size: 1px;
-    line-height: 1px;
-}
-
-/* TEXT STYLES & MODIFIERS */
-
-.small {
-    font-size: 11px;
-}
-
-.tiny {
-    font-size: 10px;
-}
-
-p.tiny {
-    margin-top: -2px;
-}
-
-.mini {
-    font-size: 9px;
-}
-
-p.mini {
-    margin-top: -3px;
-}
-
-.help, p.help {
-    font-size: 10px !important;
-    color: #999;
-}
-
-p img, h1 img, h2 img, h3 img, h4 img, td img {
-    vertical-align: middle;
-}
-
-.quiet, a.quiet:link, a.quiet:visited {
-    color: #999 !important;
-    font-weight: normal !important;
-}
-
-.quiet strong {
-    font-weight: bold !important;
-}
-
-.float-right {
-    float: right;
-}
-
-.float-left {
-    float: left;
-}
-
-.clear {
-    clear: both;
-}
-
-.align-left {
-    text-align: left;
-}
-
-.align-right {
-    text-align: right;
-}
-
-.example {
-    margin: 10px 0;
-    padding: 5px 10px;
-    background: #efefef;
-}
-
-.nowrap {
-    white-space: nowrap;
-}
-
-/* TABLES */
-
-table {
-    border-collapse: collapse;
-    border-color: #ccc;
-}
-
-td, th {
-    font-size: 11px;
-    line-height: 13px;
-    border-bottom: 1px solid #eee;
-    vertical-align: top;
-    padding: 5px;
-    font-family: "Lucida Grande", Verdana, Arial, sans-serif;
-}
-
-th {
-    text-align: left;
-    font-size: 12px;
-    font-weight: bold;
-}
-
-thead th,
-tfoot td {
-    color: #666;
-    padding: 2px 5px;
-    font-size: 11px;
-    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
-    border-left: 1px solid #ddd;
-    border-bottom: 1px solid #ddd;
-}
-
-tfoot td {
-    border-bottom: none;
-    border-top: 1px solid #ddd;
-}
-
-thead th:first-child,
-tfoot td:first-child {
-    border-left: none !important;
-}
-
-thead th.optional {
-    font-weight: normal !important;
-}
-
-fieldset table {
-    border-right: 1px solid #eee;
-}
-
-tr.row-label td {
-    font-size: 9px;
-    padding-top: 2px;
-    padding-bottom: 0;
-    border-bottom: none;
-    color: #666;
-    margin-top: -1px;
-}
-
-tr.alt {
-    background: #f6f6f6;
-}
-
-.row1 {
-    background: #EDF3FE;
-}
-
-.row2 {
-    background: white;
-}
-
-/* SORTABLE TABLES */
-
-thead th a:link, thead th a:visited {
-    color: #666;
-    display: block;
-}
-
-table thead th.sorted {
-    background-position: bottom left !important;
-}
-
-table thead th.sorted a {
-    padding-right: 13px;
-}
-
-table thead th.ascending a {
-    background: url(../img/admin/arrow-up.gif) right .4em no-repeat;
-}
-
-table thead th.descending a {
-    background: url(../img/admin/arrow-down.gif) right .4em no-repeat;
-}
-
-/* ORDERABLE TABLES */
-
-table.orderable tbody tr td:hover {
-    cursor: move;
-}
-
-table.orderable tbody tr td:first-child {
-    padding-left: 14px;
-    background-image: url(../img/admin/nav-bg-grabber.gif);
-    background-repeat: repeat-y;
-}
-
-table.orderable-initalized .order-cell, body>tr>td.order-cell {
-    display: none;
-}
-
-/* FORM DEFAULTS */
-
-input, textarea, select, .form-row p {
-    margin: 2px 0;
-    padding: 2px 3px;
-    vertical-align: middle;
-    font-family: "Lucida Grande", Verdana, Arial, sans-serif;
-    font-weight: normal;
-    font-size: 11px;
-}
-
-textarea {
-    vertical-align: top !important;
-}
-
-input[type=text], input[type=password], textarea, select, .vTextField {
-    border: 1px solid #ccc;
-}
-
-/* FORM BUTTONS */
-
-.button, input[type=submit], input[type=button], .submit-row input {
-    background: white url(../img/admin/nav-bg.gif) bottom repeat-x;
-    padding: 3px 5px;
-    color: black;
-    border: 1px solid #bbb;
-    border-color: #ddd #aaa #aaa #ddd;
-}
-
-.button:active, input[type=submit]:active, input[type=button]:active {
-    background-image: url(../img/admin/nav-bg-reverse.gif);
-    background-position: top;
-}
-
-.button[disabled], input[type=submit][disabled], input[type=button][disabled] {
-	background-image: url(../img/admin/nav-bg.gif);
-	background-position: bottom;
-	opacity: 0.4;
-}
-
-.button.default, input[type=submit].default, .submit-row input.default {
-    border: 2px solid #5b80b2;
-    background: #7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x;
-    font-weight: bold;
-    color: white;
-    float: right;
-}
-
-.button.default:active, input[type=submit].default:active {
-    background-image: url(../img/admin/default-bg-reverse.gif);
-    background-position: top;
-}
-
-.button[disabled].default, input[type=submit][disabled].default, input[type=button][disabled].default {
-	background-image: url(../img/admin/default-bg.gif);
-	background-position: bottom;
-	opacity: 0.4;
-}
-
-
-/* MODULES */
-
-.module {
-    border: 1px solid #ccc;
-    margin-bottom: 5px;
-    background: white;
-}
-
-.module p, .module ul, .module h3, .module h4, .module dl, .module pre {
-    padding-left: 10px;
-    padding-right: 10px;
-}
-
-.module blockquote {
-    margin-left: 12px;
-}
-
-.module ul, .module ol {
-    margin-left: 1.5em;
-}
-
-.module h3 {
-    margin-top: .6em;
-}
-
-.module h2, .module caption, .inline-group h2 {
-    margin: 0;
-    padding: 2px 5px 3px 5px;
-    font-size: 11px;
-    text-align: left;
-    font-weight: bold;
-    background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x;
-    color: white;
-}
-
-.module table {
-    border-collapse: collapse;
-}
-
-/* MESSAGES & ERRORS */
-
-ul.messagelist {
-    padding: 0 0 5px 0;
-    margin: 0;
-}
-
-ul.messagelist li {
-    font-size: 12px;
-    display: block;
-    padding: 4px 5px 4px 25px;
-    margin: 0 0 3px 0;
-    border-bottom: 1px solid #ddd;
-    color: #666;
-    background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat;
-}
-
-ul.messagelist li.warning{
-    background-image: url(../img/admin/icon_alert.gif);
-}
-
-ul.messagelist li.error{
-    background-image: url(../img/admin/icon_error.gif);
-}
-
-.errornote {
-    font-size: 12px !important;
-    display: block;
-    padding: 4px 5px 4px 25px;
-    margin: 0 0 3px 0;
-    border: 1px solid red;
-    color: red;
-    background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
-}
-
-ul.errorlist {
-    margin: 0 !important;
-    padding: 0 !important;
-}
-
-.errorlist li {
-    font-size: 12px !important;
-    display: block;
-    padding: 4px 5px 4px 25px;
-    margin: 0 0 3px 0;
-    border: 1px solid red;
-    color: white;
-    background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat;
-}
-
-.errorlist li a {
- 	color: white;
-    text-decoration: underline;
-}
-
-td ul.errorlist {
-    margin: 0 !important;
-    padding: 0 !important;
-}
-
-td ul.errorlist li {
-    margin: 0 !important;
-}
-
-.errors {
-    background: #ffc;
-}
-
-.errors input, .errors select, .errors textarea {
-    border: 1px solid red;
-}
-
-div.system-message {
-    background: #ffc;
-    margin: 10px;
-    padding: 6px 8px;
-    font-size: .8em;
-}
-
-div.system-message p.system-message-title {
-    padding: 4px 5px 4px 25px;
-    margin: 0;
-    color: red;
-    background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat;
-}
-
-.description {
-    font-size: 12px;
-    padding: 5px 0 0 12px;
-}
-
-/* BREADCRUMBS */
-
-div.breadcrumbs {
-    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
-    padding: 2px 8px 3px 8px;
-    font-size: 11px;
-    color: #999;
-    border-top: 1px solid white;
-    border-bottom: 1px solid #ccc;
-    text-align: left;
-}
-
-/* ACTION ICONS */
-
-.addlink {
-    padding-left: 12px;
-    background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat;
-}
-
-.changelink {
-    padding-left: 12px;
-    background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat;
-}
-
-.deletelink {
-    padding-left: 12px;
-    background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat;
-}
-
-a.deletelink:link, a.deletelink:visited {
-    color: #CC3434;
-}
-
-a.deletelink:hover {
-    color: #993333;
-}
-
-/* OBJECT TOOLS */
-
-.object-tools {
-    font-size: 10px;
-    font-weight: bold;
-    font-family: Arial,Helvetica,sans-serif;
-    padding-left: 0;
-    float: right;
-    position: relative;
-    margin-top: -2.4em;
-    margin-bottom: -2em;
-}
-
-.form-row .object-tools {
-    margin-top: 5px;
-    margin-bottom: 5px;
-    float: none;
-    height: 2em;
-    padding-left: 3.5em;
-}
-
-.object-tools li {
-    display: block;
-    float: left;
-    background: url(../img/admin/tool-left.gif) 0 0 no-repeat;
-    padding: 0 0 0 8px;
-    margin-left: 2px;
-    height: 16px;
-}
-
-.object-tools li:hover {
-    background: url(../img/admin/tool-left_over.gif) 0 0 no-repeat;
-}
-
-.object-tools a:link, .object-tools a:visited {
-    display: block;
-    float: left;
-    color: white;
-    padding: .1em 14px .1em 8px;
-    height: 14px;
-    background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat;
-}
-
-.object-tools a:hover, .object-tools li:hover a {
-    background: #5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat;
-}
-
-.object-tools a.viewsitelink, .object-tools a.golink {
-    background: #999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat;
-    padding-right: 28px;
-}
-
-.object-tools a.viewsitelink:hover, .object-tools a.golink:hover {
-    background: #5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat;
-}
-
-.object-tools a.addlink {
-    background: #999 url(../img/admin/tooltag-add.gif) top right no-repeat;
-    padding-right: 28px;
-}
-
-.object-tools a.addlink:hover {
-    background: #5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat;
-}
-
-/* OBJECT HISTORY */
-
-table#change-history {
-    width: 100%;
-}
-
-table#change-history tbody th {
-    width: 16em;
-}
-
-/* PAGE STRUCTURE */
-
-#container {
-    position: relative;
-    width: 100%;
-    min-width: 760px;
-    padding: 0;
-}
-
-#content {
-    margin: 10px 15px;
-}
-
-#header {
-    width: 100%;
-}
-
-#content-main {
-    float: left;
-    width: 100%;
-}
-
-#content-related {
-    float: right;
-    width: 18em;
-    position: relative;
-    margin-right: -19em;
-}
-
-#footer {
-    clear: both;
-    padding: 10px;
-}
-
-/* COLUMN TYPES */
-
-.colMS {
-    margin-right: 20em !important;
-}
-
-.colSM {
-    margin-left: 20em !important;
-}
-
-.colSM #content-related {
-    float: left;
-    margin-right: 0;
-    margin-left: -19em;
-}
-
-.colSM #content-main {
-    float: right;
-}
-
-.popup .colM {
-    width: 95%;
-}
-
-.subcol {
-    float: left;
-    width: 46%;
-    margin-right: 15px;
-}
-
-.dashboard #content {
-    width: 500px;
-}
-
-/* HEADER */
-
-#header {
-    background: #417690;
-    color: #ffc;
-    overflow: hidden;
-}
-
-#header a:link, #header a:visited {
-    color: white;
-}
-
-#header a:hover {
-    text-decoration: underline;
-}
-
-#branding h1 {
-    padding: 0 10px;
-    font-size: 18px;
-    margin: 8px 0;
-    font-weight: normal;
-    color: #f4f379;
-}
-
-#branding h2 {
-    padding: 0 10px;
-    font-size: 14px;
-    margin: -8px 0 8px 0;
-    font-weight: normal;
-    color: #ffc;
-}
-
-#user-tools {
-    position: absolute;
-    top: 0;
-    right: 0;
-    padding: 1.2em 10px;
-    font-size: 11px;
-    text-align: right;
-}
-
-/* SIDEBAR */
-
-#content-related h3 {
-    font-size: 12px;
-    color: #666;
-    margin-bottom: 3px;
-}
-
-#content-related h4 {
-    font-size: 11px;
-}
-
-#content-related .module h2 {
-    background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x;
-    color: #666;
-}
-

frameworks/django_/myapp/static/admin/css/changelists.css

-/* CHANGELISTS */
-
-#changelist {
-    position: relative;
-    width: 100%;
-}
-
-#changelist table {
-    width: 100%;
-}
-
-.change-list .hiddenfields { display:none; }
-
-.change-list .filtered table {
-    border-right: 1px solid #ddd;
-}
-
-.change-list .filtered {
-    min-height: 400px;
-}
-
-.change-list .filtered {
-    background: white url(../img/admin/changelist-bg.gif) top right repeat-y !important;
-}
-
-.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
-    margin-right: 160px !important;
-    width: auto !important;
-}
-
-.change-list .filtered table tbody th {
-    padding-right: 1em;
-}
-
-#changelist .toplinks {
-    border-bottom: 1px solid #ccc !important;
-}
-
-#changelist .paginator {
-    color: #666;
-    border-top: 1px solid #eee;
-    border-bottom: 1px solid #eee;
-    background: white url(../img/admin/nav-bg.gif) 0 180% repeat-x;
-    overflow: hidden;
-}
-
-.change-list .filtered .paginator {
-    border-right: 1px solid #ddd;
-}
-
-/* CHANGELIST TABLES */
-
-#changelist table thead th {
-    white-space: nowrap;
-    vertical-align: middle;
-}
-
-#changelist table thead th.action-checkbox-column {
-    width: 1.5em;
-    text-align: center;
-}
-
-#changelist table tbody td, #changelist table tbody th {
-    border-left: 1px solid #ddd;
-}
-
-#changelist table tbody td:first-child, #changelist table tbody th:first-child {
-    border-left: 0;
-    border-right: 1px solid #ddd;
-}
-
-#changelist table tbody td.action-checkbox {
-    text-align:center;
-}
-
-#changelist table tfoot {
-    color: #666;
-}
-
-/* TOOLBAR */
-
-#changelist #toolbar {
-    padding: 3px;
-    border-bottom: 1px solid #ddd;
-    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
-    color: #666;
-}
-
-#changelist #toolbar form input {
-    font-size: 11px;
-    padding: 1px 2px;
-}
-
-#changelist #toolbar form #searchbar {
-    padding: 2px;
-}
-
-#changelist #changelist-search img {
-    vertical-align: middle;
-}
-
-/* FILTER COLUMN */
-
-#changelist-filter {
-    position: absolute;
-    top: 0;
-    right: 0;
-    z-index: 1000;
-    width: 160px;
-    border-left: 1px solid #ddd;
-    background: #efefef;
-    margin: 0;
-}
-
-#changelist-filter h2 {
-    font-size: 11px;
-    padding: 2px 5px;
-    border-bottom: 1px solid #ddd;
-}
-
-#changelist-filter h3 {
-    font-size: 12px;
-    margin-bottom: 0;
-}
-
-#changelist-filter ul {
-    padding-left: 0;
-    margin-left: 10px;
-}
-
-#changelist-filter li {
-    list-style-type: none;
-    margin-left: 0;
-    padding-left: 0;
-}
-
-#changelist-filter a {
-    color: #999;
-}
-
-#changelist-filter a:hover {
-    color: #036;
-}
-
-#changelist-filter li.selected {
-    border-left: 5px solid #ccc;
-    padding-left: 5px;
-    margin-left: -10px;
-}
-
-#changelist-filter li.selected a {
-    color: #5b80b2 !important;
-}
-
-/* DATE DRILLDOWN */
-
-.change-list ul.toplinks {
-    display: block;
-    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
-    border-top: 1px solid white;
-    float: left;
-    padding: 0 !important;
-    margin: 0 !important;
-    width: 100%;
-}
-
-.change-list ul.toplinks li {
-    float: left;
-    width: 9em;
-    padding: 3px 6px;
-    font-weight: bold;
-    list-style-type: none;
-}
-
-.change-list ul.toplinks .date-back a {
-    color: #999;
-}
-
-.change-list ul.toplinks .date-back a:hover {
-    color: #036;
-}
-
-/* PAGINATOR */
-
-.paginator {
-    font-size: 11px;
-    padding-top: 10px;
-    padding-bottom: 10px;
-    line-height: 22px;
-    margin: 0;
-    border-top: 1px solid #ddd;
-}
-
-.paginator a:link, .paginator a:visited {
-    padding: 2px 6px;
-    border: solid 1px #ccc;
-    background: white;
-    text-decoration: none;
-}
-
-.paginator a.showall {
-    padding: 0 !important;
-    border: none !important;
-}
-
-.paginator a.showall:hover {
-    color: #036 !important;
-    background: transparent !important;
-}
-
-.paginator .end {
-    border-width: 2px !important;
-    margin-right: 6px;
-}
-
-.paginator .this-page {
-    padding: 2px 6px;
-    font-weight: bold;
-    font-size: 13px;
-    vertical-align: top;
-}
-
-.paginator a:hover {
-    color: white;
-    background: #5b80b2;
-    border-color: #036;
-}
-
-/* ACTIONS */
-
-.filtered .actions {
-    margin-right: 160px !important;
-    border-right: 1px solid #ddd;
-}
-
-#changelist table input {
-    margin: 0;
-}
-
-#changelist table tbody tr.selected {
-    background-color: #FFFFCC;
-}
-
-#changelist .actions {
-    color: #999;
-    padding: 3px;
-    border-top: 1px solid #fff;
-    border-bottom: 1px solid #ddd;
-    background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x;
-}
-
-#changelist .actions.selected {
-    background: #fffccf;
-    border-top: 1px solid #fffee8;
-    border-bottom: 1px solid #edecd6;
-}
-
-#changelist .actions span.all,
-#changelist .actions span.action-counter,
-#changelist .actions span.clear,
-#changelist .actions span.question {
-    font-size: 11px;
-    margin: 0 0.5em;
-    display: none;
-}
-
-#changelist .actions:last-child {
-    border-bottom: none;
-}
-
-#changelist .actions select {
-    border: 1px solid #aaa;
-    margin-left: 0.5em;
-    padding: 1px 2px;
-}
-
-#changelist .actions label {
-    font-size: 11px;
-    margin-left: 0.5em;
-}
-
-#changelist #action-toggle {
-    display: none;
-}
-
-#changelist .actions .button {
-    font-size: 11px;
-    padding: 1px 2px;
-}

frameworks/django_/myapp/static/admin/css/dashboard.css

-/* DASHBOARD */
-
-.dashboard .module table th {
-    width: 100%;
-}
-
-.dashboard .module table td {
-    white-space: nowrap;
-}
-
-.dashboard .module table td a {
-    display: block;
-    padding-right: .6em;
-}
-
-/* RECENT ACTIONS MODULE */
-
-.module ul.actionlist {
-    margin-left: 0;
-}
-
-ul.actionlist li {
-    list-style-type: none;
-}
-
-ul.actionlist li.changelink {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    -o-text-overflow: ellipsis;
-}

frameworks/django_/myapp/static/admin/css/forms.css

-@import url('widgets.css');
-
-/* FORM ROWS */
-
-.form-row {
-    overflow: hidden;
-    padding: 8px 12px;
-    font-size: 11px;
-    border-bottom: 1px solid #eee;
-}
-
-.form-row img, .form-row input {
-    vertical-align: middle;
-}
-
-form .form-row p {
-    padding-left: 0;
-    font-size: 11px;
-}
-
-/* FORM LABELS */
-
-form h4 {
-    margin: 0 !important;
-    padding: 0 !important;
-    border: none !important;
-}
-
-label {
-    font-weight: normal !important;
-    color: #666;
-    font-size: 12px;
-}
-
-.required label, label.required {
-    font-weight: bold !important;
-    color: #333 !important;
-}
-
-/* RADIO BUTTONS */
-
-form ul.radiolist li {
-    list-style-type: none;
-}
-
-form ul.radiolist label {
-    float: none;
-    display: inline;
-}
-
-form ul.inline {
-    margin-left: 0;
-    padding: 0;
-}
-
-form ul.inline li {
-    float: left;
-    padding-right: 7px;
-}
-
-/* ALIGNED FIELDSETS */
-
-.aligned label {
-    display: block;
-    padding: 3px 10px 0 0;
-    float: left;
-    width: 8em;
-}
-
-.aligned ul label {
-    display: inline;
-    float: none;
-    width: auto;
-}
-
-.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {
-    width: 350px;
-}
-
-form .aligned p, form .aligned ul {
-    margin-left: 7em;
-    padding-left: 30px;
-}
-
-form .aligned table p {
-    margin-left: 0;
-    padding-left: 0;
-}
-
-form .aligned p.help {
-    padding-left: 38px;
-}
-
-.aligned .vCheckboxLabel {
-    float: none !important;
-    display: inline;
-    padding-left: 4px;
-}
-
-.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {
-    width: 610px;
-}
-
-.checkbox-row p.help {
-    margin-left: 0;
-    padding-left: 0 !important;
-}
-
-fieldset .field-box {
-    float: left;
-    margin-right: 20px;
-}
-
-/* WIDE FIELDSETS */
-
-.wide label {
-    width: 15em !important;
-}
-
-form .wide p {
-    margin-left: 15em;
-}
-
-form .wide p.help {
-    padding-left: 38px;
-}
-
-.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {
-    width: 450px;
-}
-
-/* COLLAPSED FIELDSETS */
-
-fieldset.collapsed * {
-    display: none;
-}
-
-fieldset.collapsed h2, fieldset.collapsed {
-    display: block !important;
-}
-
-fieldset.collapsed h2 {
-    background-image: url(../img/admin/nav-bg.gif);
-    background-position: bottom left;
-    color: #999;
-}
-
-fieldset.collapsed .collapse-toggle {
-    background: transparent;
-    display: inline !important;
-}
-
-/* MONOSPACE TEXTAREAS */
-
-fieldset.monospace textarea {
-    font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace;
-}
-
-/* SUBMIT ROW */
-
-.submit-row {
-    padding: 5px 7px;
-    text-align: right;
-    background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x;
-    border: 1px solid #ccc;
-    margin: 5px 0;
-    overflow: hidden;
-}
-
-.submit-row input {
-    margin: 0 0 0 5px;
-}
-
-.submit-row p {
-    margin: 0.3em;
-}
-
-.submit-row p.deletelink-box {
-    float: left;
-}
-
-.submit-row .deletelink {
-    background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat;
-    padding-left: 14px;
-}
-
-/* CUSTOM FORM FIELDS */
-
-.vSelectMultipleField {
-    vertical-align: top !important;
-}
-
-.vCheckboxField {
-    border: none;
-}
-
-.vDateField, .vTimeField {
-    margin-right: 2px;
-}
-
-.vURLField {
-    width: 30em;
-}
-
-.vLargeTextField, .vXMLLargeTextField {
-    width: 48em;
-}
-
-.flatpages-flatpage #id_content {
-    height: 40.2em;
-}
-
-.module table .vPositiveSmallIntegerField {
-    width: 2.2em;
-}
-
-.vTextField {
-    width: 20em;
-}
-
-.vIntegerField {
-    width: 5em;
-}
-
-.vForeignKeyRawIdAdminField {
-    width: 5em;
-}
-
-/* INLINES */
-
-.inline-group {
-    padding: 0;
-    border: 1px solid #ccc;
-    margin: 10px 0;
-}
-
-.inline-group .aligned label {
-    width: 8em;
-}
-
-.inline-related {
-    position: relative;
-}
-
-.inline-related h3 {
-    margin: 0;
-    color: #666;
-    padding: 3px 5px;
-    font-size: 11px;
-    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
-    border-bottom: 1px solid #ddd;
-}
-
-.inline-related h3 span.delete {
-    float: right;
-}
-
-.inline-related h3 span.delete label {
-    margin-left: 2px;
-    font-size: 11px;
-}
-
-.inline-related fieldset {
-    margin: 0;
-    background: #fff;
-    border: none;
-}
-
-.inline-related fieldset.module h3 {
-    margin: 0;
-    padding: 2px 5px 3px 5px;
-    font-size: 11px;
-    text-align: left;
-    font-weight: bold;
-    background: #bcd;
-    color: #fff;
-}
-
-.inline-group .tabular fieldset.module {
-    border: none;
-    border-bottom: 1px solid #ddd;
-}
-
-.inline-related.tabular fieldset.module table {
-    width: 100%;
-}
-
-.last-related fieldset {
-    border: none;
-}
-
-.inline-group .tabular tr.has_original td {
-    padding-top: 2em;
-}
-
-.inline-group .tabular tr td.original {
-    padding: 2px 0 0 0;
-    width: 0;
-    _position: relative;
-}
-
-.inline-group .tabular th.original {
-    width: 0px;
-    padding: 0;
-}
-
-.inline-group .tabular td.original p {
-    position: absolute;
-    left: 0;
-    height: 1.1em;
-    padding: 2px 7px;
-    overflow: hidden;
-    font-size: 9px;
-    font-weight: bold;
-    color: #666;
-    _width: 700px;
-}
-
-.inline-group ul.tools {
-    padding: 0;
-    margin: 0;
-    list-style: none;
-}
-
-.inline-group ul.tools li {
-    display: inline;
-    padding: 0 5px;
-}
-
-.inline-group div.add-row,
-.inline-group .tabular tr.add-row td {
-    color: #666;
-    padding: 3px 5px;
-    border-bottom: 1px solid #ddd;
-    background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x;
-}
-
-.inline-group .tabular tr.add-row td {
-    padding: 4px 5px 3px;
-    border-bottom: none;
-}
-
-.inline-group ul.tools a.add,
-.inline-group div.add-row a,
-.inline-group .tabular tr.add-row td a {
-    background: url(../img/admin/icon_addlink.gif) 0 50% no-repeat;
-    padding-left: 14px;
-    font-size: 11px;
-    outline: 0; /* Remove dotted border around link */
-}
-
-.empty-form {
-    display: none;
-}
-
-/* IE7 specific bug fixes */
-
-.submit-row input {
-    float: right;
-}

frameworks/django_/myapp/static/admin/css/ie.css

-/* IE 6 & 7 */
-
-/* Proper fixed width for dashboard in IE6 */
-
-.dashboard #content {
-    *width: 768px;
-}
-
-.dashboard #content-main {
-    *width: 535px;
-}
-
-/* IE 6 ONLY */
-
-/* Keep header from flowing off the page */
-
-#container {
-    _position: static;
-}
-
-/* Put the right sidebars back on the page */
-
-.colMS #content-related {
-    _margin-right: 0;
-    _margin-left: 10px;
-    _position: static;
-}
-
-/* Put the left sidebars back on the page */
-
-.colSM #content-related {
-    _margin-right: 10px;
-    _margin-left: -115px;
-    _position: static;
-}
-
-.form-row {
-    _height: 1%;
-}
-
-/* Fix right margin for changelist filters in IE6 */
-
-#changelist-filter ul {
-    _margin-right: -10px;
-}
-
-/* IE ignores min-height, but treats height as if it were min-height */
-
-.change-list .filtered {
-    _height: 400px;
-}
-
-/* IE doesn't know alpha transparency in PNGs */
-
-.inline-deletelink {
-    background: transparent url(../img/admin/inline-delete-8bit.png) no-repeat;
-}

frameworks/django_/myapp/static/admin/css/login.css

-/* LOGIN FORM */
-
-body.login {
-    background: #eee;
-}
-
-.login #container {
-    background: white;
-    border: 1px solid #ccc;
-    width: 28em;
-    min-width: 300px;
-    margin-left: auto;
-    margin-right: auto;
-    margin-top: 100px;
-}
-
-.login #content-main {
-    width: 100%;
-}
-
-.login form {
-    margin-top: 1em;
-}
-
-.login .form-row {
-    padding: 4px 0;
-    float: left;
-    width: 100%;
-}
-
-.login .form-row label {
-    float: left;
-    width: 9em;
-    padding-right: 0.5em;
-    line-height: 2em;
-    text-align: right;
-    font-size: 1em;
-    color: #333;
-}
-
-.login .form-row #id_username, .login .form-row #id_password {
-    width: 14em;
-}
-
-.login span.help {
-    font-size: 10px;
-    display: block;
-}
-
-.login .submit-row {
-    clear: both;
-    padding: 1em 0 0 9.4em;
-}
-

frameworks/django_/myapp/static/admin/css/rtl.css

-body {
-    direction: rtl;
-}
-
-/* LOGIN */
-
-.login .form-row {
-    float: right;
-}
-
-.login .form-row label {
-    float: right;
-    padding-left: 0.5em;
-    padding-right: 0;
-    text-align: left;
-}
-
-.login .submit-row {
-    clear: both;
-    padding: 1em 9.4em 0 0;
-}
-
-/* GLOBAL */
-
-th {
-    text-align: right;
-}
-
-.module h2, .module caption {
-    text-align: right;
-}
-
-.addlink, .changelink {
-    padding-left: 0px;
-    padding-right: 12px;
-    background-position: 100% 0.2em;
-}
-
-.deletelink {
-    padding-left: 0px;
-    padding-right: 12px;
-    background-position: 100% 0.25em;
-}
-
-.object-tools {
-    float: left;
-}
-
-thead th:first-child,
-tfoot td:first-child {
-    border-left: 1px solid #ddd !important;
-}
-
-/* LAYOUT */
-
-#user-tools {
-    right: auto;
-    left: 0;
-    text-align: left;
-}
-
-div.breadcrumbs {
-    text-align: right;
-}
-
-#content-main {
-    float: right;
-}
-
-#content-related {
-    float: left;
-    margin-left: -19em;
-    margin-right: auto;
-}
-
-.colMS {
-    margin-left: 20em !important;
-    margin-right: 10px !important;
-}
-
-/* SORTABLE TABLES */
-
-
-table thead th.sorted a {
-    padding-left: 13px;
-    padding-right: 0px;
-}
-
-table thead th.ascending a,
-table thead th.descending a {
-    background-position: left;
-}
-
-/* dashboard styles */
-
-.dashboard .module table td a {
-    padding-left: .6em;
-    padding-right: 12px;
-}
-
-/* changelists styles */
-
-.change-list ul.toplinks li {
-    float: right;
-}
-
-.change-list .filtered {
-    background: white url(../img/admin/changelist-bg_rtl.gif) top left repeat-y !important;
-}
-
-.change-list .filtered table {
-    border-left: 1px solid #ddd;
-    border-right: 0px none;
-}
-
-#changelist-filter {
-    right: auto;
-    left: 0;
-    border-left: 0px none;
-    border-right: 1px solid #ddd;
-}
-
-.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
-    margin-right: 0px !important;
-    margin-left: 160px !important;
-}
-
-#changelist-filter li.selected {
-    border-left: 0px none;
-    padding-left: 0px;
-    margin-left: 0;
-    border-right: 5px solid #ccc;
-    padding-right: 5px;
-    margin-right: -10px;
-}
-
-.filtered .actions {
-    border-left:1px solid #DDDDDD;
-    margin-left:160px !important;
-    border-right: 0 none;
-    margin-right:0 !important;