From 9c8ca51c78b96835d4f2aa09bdf38d5c9dc01102 Mon Sep 17 00:00:00 2001 From: Paul Oswald Date: Tue, 14 Feb 2012 11:19:40 +0900 Subject: Delete robots.txt, favicon.ico views; Move style to a new static namespace --- .../static/css/djangorestframework.css | 1209 -------------------- .../static/djangorestframework/css/style.css | 1209 ++++++++++++++++++++ djangorestframework/static/favicon.ico | Bin 1286 -> 0 bytes djangorestframework/static/robots.txt | 2 - djangorestframework/templates/api_login.html | 2 +- djangorestframework/templates/renderer.html | 2 +- djangorestframework/tests/views.py | 14 - djangorestframework/urls.py | 10 - djangorestframework/utils/staticviews.py | 9 - 9 files changed, 1211 insertions(+), 1246 deletions(-) delete mode 100644 djangorestframework/static/css/djangorestframework.css create mode 100644 djangorestframework/static/djangorestframework/css/style.css delete mode 100644 djangorestframework/static/favicon.ico delete mode 100644 djangorestframework/static/robots.txt (limited to 'djangorestframework') diff --git a/djangorestframework/static/css/djangorestframework.css b/djangorestframework/static/css/djangorestframework.css deleted file mode 100644 index 1e75b8e8..00000000 --- a/djangorestframework/static/css/djangorestframework.css +++ /dev/null @@ -1,1209 +0,0 @@ -/********************** admin 'base.css' ************************/ - -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; -} - -/********************** admin 'forms.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; -} - -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; -} - -/* Overrides specific to REST framework */ - -#site-name a { - color: #F4F379 !important; -} - -.errorlist { - display: inline !important; -} - -.errorlist li { - display: inline !important; - background: white !important; - color: black !important; - border: 0 !important; -} - -/* Custom styles */ - -.version { - font-size: 8px; -} - -.form-row { - border-bottom: 0.25em !important; -} diff --git a/djangorestframework/static/djangorestframework/css/style.css b/djangorestframework/static/djangorestframework/css/style.css new file mode 100644 index 00000000..1e75b8e8 --- /dev/null +++ b/djangorestframework/static/djangorestframework/css/style.css @@ -0,0 +1,1209 @@ +/********************** admin 'base.css' ************************/ + +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; +} + +/********************** admin 'forms.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; +} + +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; +} + +/* Overrides specific to REST framework */ + +#site-name a { + color: #F4F379 !important; +} + +.errorlist { + display: inline !important; +} + +.errorlist li { + display: inline !important; + background: white !important; + color: black !important; + border: 0 !important; +} + +/* Custom styles */ + +.version { + font-size: 8px; +} + +.form-row { + border-bottom: 0.25em !important; +} diff --git a/djangorestframework/static/favicon.ico b/djangorestframework/static/favicon.ico deleted file mode 100644 index 17080106..00000000 Binary files a/djangorestframework/static/favicon.ico and /dev/null differ diff --git a/djangorestframework/static/robots.txt b/djangorestframework/static/robots.txt deleted file mode 100644 index 1f53798b..00000000 --- a/djangorestframework/static/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: / diff --git a/djangorestframework/templates/api_login.html b/djangorestframework/templates/api_login.html index 016a4e10..07929f0c 100644 --- a/djangorestframework/templates/api_login.html +++ b/djangorestframework/templates/api_login.html @@ -2,7 +2,7 @@ - + diff --git a/djangorestframework/templates/renderer.html b/djangorestframework/templates/renderer.html index e396a58f..bda49e6f 100644 --- a/djangorestframework/templates/renderer.html +++ b/djangorestframework/templates/renderer.html @@ -6,7 +6,7 @@ {% load static %} - + Django REST framework - {{ name }} diff --git a/djangorestframework/tests/views.py b/djangorestframework/tests/views.py index ab5d75d6..d4189087 100644 --- a/djangorestframework/tests/views.py +++ b/djangorestframework/tests/views.py @@ -46,8 +46,6 @@ class MockResource(ModelResource): fields = ('foo', 'bar', 'baz') urlpatterns = patterns('djangorestframework.utils.staticviews', - url(r'^robots.txt$', 'deny_robots'), - url(r'^favicon.ico$', 'favicon'), url(r'^accounts/login$', 'api_login'), url(r'^accounts/logout$', 'api_logout'), url(r'^mock/$', MockView.as_view()), @@ -123,18 +121,6 @@ class ExtraViewsTests(TestCase): """Test the extra views djangorestframework provides""" urls = 'djangorestframework.tests.views' - def test_robots_view(self): - """Ensure the robots view exists""" - response = self.client.get('/robots.txt') - self.assertEqual(response.status_code, 200) - self.assertEqual(response['Content-Type'], 'text/plain') - - def test_favicon_view(self): - """Ensure the favicon view exists""" - response = self.client.get('/favicon.ico') - self.assertEqual(response.status_code, 200) - self.assertEqual(response['Content-Type'], 'image/vnd.microsoft.icon') - def test_login_view(self): """Ensure the login view exists""" response = self.client.get('/accounts/login') diff --git a/djangorestframework/urls.py b/djangorestframework/urls.py index 827aac9c..5c797bcd 100644 --- a/djangorestframework/urls.py +++ b/djangorestframework/urls.py @@ -1,16 +1,6 @@ from django.conf.urls.defaults import patterns -from django.conf import settings urlpatterns = patterns('djangorestframework.utils.staticviews', - (r'robots.txt', 'deny_robots'), (r'^accounts/login/$', 'api_login'), (r'^accounts/logout/$', 'api_logout'), ) - -# Only serve favicon in production because otherwise chrome users will pretty much -# permanantly have the django-rest-framework favicon whenever they navigate to -# 127.0.0.1:8000 or whatever, which gets annoying -if not settings.DEBUG: - urlpatterns += patterns('djangorestframework.utils.staticviews', - (r'favicon.ico', 'favicon'), - ) diff --git a/djangorestframework/utils/staticviews.py b/djangorestframework/utils/staticviews.py index 12a36f6c..9bae0ee7 100644 --- a/djangorestframework/utils/staticviews.py +++ b/djangorestframework/utils/staticviews.py @@ -6,15 +6,6 @@ from django.template import RequestContext import base64 -def deny_robots(request): - return HttpResponse('User-agent: *\nDisallow: /', mimetype='text/plain') - - -def favicon(request): - data = 'AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADLy8tLy8vL3svLy1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAy8vLBsvLywkAAAAATkZFS1xUVPqhn57/y8vL0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJmVlQ/GxcXiy8vL88vLy4FdVlXzTkZF/2RdXP/Ly8vty8vLtMvLy5DLy8vty8vLxgAAAAAAAAAAAAAAAAAAAABORkUJTkZF4lNMS/+Lh4f/cWtq/05GRf9ORkX/Vk9O/3JtbP+Ef3//Vk9O/2ljYv/Ly8v5y8vLCQAAAAAAAAAAAAAAAE5GRQlORkX2TkZF/05GRf9ORkX/TkZF/05GRf9ORkX/TkZF/05GRf9ORkX/UElI/8PDw5cAAAAAAAAAAAAAAAAAAAAAAAAAAE5GRZZORkX/TkZF/05GRf9ORkX/TkZF/05GRf9ORkX/TkZF/05GRf+Cfn3/y8vLvQAAAAAAAAAAAAAAAAAAAADLy8tIaWNi805GRf9ORkX/YVpZ/396eV7Ly8t7qaen9lZOTu5ORkX/TkZF/25oZ//Ly8v/y8vLycvLy0gAAAAATkZFSGNcXPpORkX/TkZF/05GRf+ysLDzTkZFe1NLSv6Oior/raur805GRf9ORkX/TkZF/2hiYf+npaX/y8vL5wAAAABORkXnTkZF/05GRf9ORkX/VU1M/8vLy/9PR0b1TkZF/1VNTP/Ly8uQT0dG+E5GRf9ORkX/TkZF/1hRUP3Ly8tmAAAAAE5GRWBORkXkTkZF/05GRf9ORkX/t7a2/355eOpORkX/TkZFkISAf1BORkX/TkZF/05GRf9XT075TkZFZgAAAAAAAAAAAAAAAAAAAABORkXDTkZF/05GRf9lX17/ubi4/8vLy/+2tbT/Yltb/05GRf9ORkX/a2Vk/8vLy5MAAAAAAAAAAAAAAAAAAAAAAAAAAFNLSqNORkX/TkZF/05GRf9ORkX/TkZF/05GRf9ORkX/TkZF/05GRf+Cfn3/y8vL+cvLyw8AAAAAAAAAAAAAAABORkUSTkZF+U5GRf9ORkX/TkZF/05GRf9ORkX/TkZF/05GRf9ORkX/TkZF/1BJSP/CwsLmy8vLDwAAAAAAAAAAAAAAAE5GRRJORkXtTkZF9FFJSJ1ORkXJTkZF/05GRf9ORkX/ZF5d9k5GRZ9ORkXtTkZF5HFsaxUAAAAAAAAAAAAAAAAAAAAAAAAAAE5GRQxORkUJAAAAAAAAAABORkXhTkZF/2JbWv7Ly8tgAAAAAAAAAABORkUGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5GRWBORkX2TkZFYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+AAP9/gAD+P4AA4AOAAMADgADAA4AAwAOAAMMBgACCAIAAAAGAAIBDgADAA4AAwAOAAMADgADAB4AA/H+AAP7/gAA=' - return HttpResponse(base64.b64decode(data), mimetype='image/vnd.microsoft.icon') - - # BLERGH # Replicate django.contrib.auth.views.login simply so we don't have get users to update TEMPLATE_CONTEXT_PROCESSORS # to add ADMIN_MEDIA_PREFIX to the RequestContext. I don't like this but really really want users to not have to -- cgit v1.2.3 From 78daa32566cbdc9016d6c4df5429feb9684c8032 Mon Sep 17 00:00:00 2001 From: Paul Oswald Date: Tue, 14 Feb 2012 14:50:11 +0900 Subject: Move stylesheet references to the new relative namespace --- .../static/djangorestframework/css/style.css | 72 +++++++++++----------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'djangorestframework') diff --git a/djangorestframework/static/djangorestframework/css/style.css b/djangorestframework/static/djangorestframework/css/style.css index 1e75b8e8..d47aa16a 100644 --- a/djangorestframework/static/djangorestframework/css/style.css +++ b/djangorestframework/static/djangorestframework/css/style.css @@ -257,7 +257,7 @@ tfoot td { color: #666; padding: 2px 5px; font-size: 11px; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; border-left: 1px solid #ddd; border-bottom: 1px solid #ddd; } @@ -317,11 +317,11 @@ table thead th.sorted a { } table thead th.ascending a { - background: url(../img/admin/arrow-up.gif) right .4em no-repeat; + background: url(../../admin/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; + background: url(../../admin/img/admin/arrow-down.gif) right .4em no-repeat; } /* ORDERABLE TABLES */ @@ -332,7 +332,7 @@ table.orderable tbody tr td:hover { table.orderable tbody tr td:first-child { padding-left: 14px; - background-image: url(../img/admin/nav-bg-grabber.gif); + background-image: url(../../admin/img/admin/nav-bg-grabber.gif); background-repeat: repeat-y; } @@ -362,7 +362,7 @@ input[type=text], input[type=password], textarea, select, .vTextField { /* FORM BUTTONS */ .button, input[type=submit], input[type=button], .submit-row input { - background: white url(../img/admin/nav-bg.gif) bottom repeat-x; + background: white url(../../admin/img/admin/nav-bg.gif) bottom repeat-x; padding: 3px 5px; color: black; border: 1px solid #bbb; @@ -370,31 +370,31 @@ input[type=text], input[type=password], textarea, select, .vTextField { } .button:active, input[type=submit]:active, input[type=button]:active { - background-image: url(../img/admin/nav-bg-reverse.gif); + background-image: url(../../admin/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-image: url(../../admin/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; + background: #7CA0C7 url(../../admin/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-image: url(../../admin/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-image: url(../../admin/img/admin/default-bg.gif); background-position: bottom; opacity: 0.4; } @@ -431,7 +431,7 @@ input[type=text], input[type=password], textarea, select, .vTextField { font-size: 11px; text-align: left; font-weight: bold; - background: #7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; + background: #7CA0C7 url(../../admin/img/admin/default-bg.gif) top left repeat-x; color: white; } @@ -453,15 +453,15 @@ ul.messagelist li { margin: 0 0 3px 0; border-bottom: 1px solid #ddd; color: #666; - background: #ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; + background: #ffc url(../../admin/img/admin/icon_success.gif) 5px .3em no-repeat; } ul.messagelist li.warning{ - background-image: url(../img/admin/icon_alert.gif); + background-image: url(../../admin/img/admin/icon_alert.gif); } ul.messagelist li.error{ - background-image: url(../img/admin/icon_error.gif); + background-image: url(../../admin/img/admin/icon_error.gif); } .errornote { @@ -471,7 +471,7 @@ ul.messagelist li.error{ margin: 0 0 3px 0; border: 1px solid red; color: red; - background: #ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; + background: #ffc url(../../admin/img/admin/icon_error.gif) 5px .3em no-repeat; } ul.errorlist { @@ -486,7 +486,7 @@ ul.errorlist { margin: 0 0 3px 0; border: 1px solid red; color: white; - background: red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; + background: red url(../../admin/img/admin/icon_alert.gif) 5px .3em no-repeat; } .errorlist li a { @@ -522,7 +522,7 @@ 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; + background: #ffc url(../../admin/img/admin/icon_error.gif) 5px .3em no-repeat; } .description { @@ -533,7 +533,7 @@ div.system-message p.system-message-title { /* BREADCRUMBS */ div.breadcrumbs { - background: white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; + background: white url(../../admin/img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding: 2px 8px 3px 8px; font-size: 11px; color: #999; @@ -546,17 +546,17 @@ div.breadcrumbs { .addlink { padding-left: 12px; - background: url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; + background: url(../../admin/img/admin/icon_addlink.gif) 0 .2em no-repeat; } .changelink { padding-left: 12px; - background: url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; + background: url(../../admin/img/admin/icon_changelink.gif) 0 .2em no-repeat; } .deletelink { padding-left: 12px; - background: url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat; + background: url(../../admin/img/admin/icon_deletelink.gif) 0 .25em no-repeat; } a.deletelink:link, a.deletelink:visited { @@ -591,14 +591,14 @@ a.deletelink:hover { .object-tools li { display: block; float: left; - background: url(../img/admin/tool-left.gif) 0 0 no-repeat; + background: url(../../admin/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; + background: url(../../admin/img/admin/tool-left_over.gif) 0 0 no-repeat; } .object-tools a:link, .object-tools a:visited { @@ -607,29 +607,29 @@ a.deletelink:hover { color: white; padding: .1em 14px .1em 8px; height: 14px; - background: #999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; + background: #999 url(../../admin/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; + background: #5b80b2 url(../../admin/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; + background: #999 url(../../admin/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; + background: #5b80b2 url(../../admin/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; + background: #999 url(../../admin/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; + background: #5b80b2 url(../../admin/img/admin/tooltag-add_over.gif) top right no-repeat; } /* OBJECT HISTORY */ @@ -764,7 +764,7 @@ table#change-history tbody th { } #content-related .module h2 { - background: #eee url(../img/admin/nav-bg.gif) bottom left repeat-x; + background: #eee url(../../admin/img/admin/nav-bg.gif) bottom left repeat-x; color: #666; } @@ -910,7 +910,7 @@ fieldset.collapsed h2, fieldset.collapsed { } fieldset.collapsed h2 { - background-image: url(../img/admin/nav-bg.gif); + background-image: url(../../admin/img/admin/nav-bg.gif); background-position: bottom left; color: #999; } @@ -931,7 +931,7 @@ fieldset.monospace textarea { .submit-row { padding: 5px 7px; text-align: right; - background: white url(../img/admin/nav-bg.gif) 0 100% repeat-x; + background: white url(../../admin/img/admin/nav-bg.gif) 0 100% repeat-x; border: 1px solid #ccc; margin: 5px 0; overflow: hidden; @@ -950,7 +950,7 @@ fieldset.monospace textarea { } .submit-row .deletelink { - background: url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; + background: url(../../admin/img/admin/icon_deletelink.gif) 0 50% no-repeat; padding-left: 14px; } @@ -1017,7 +1017,7 @@ fieldset.monospace textarea { color: #666; padding: 3px 5px; font-size: 11px; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; border-bottom: 1px solid #ddd; } @@ -1102,7 +1102,7 @@ fieldset.monospace textarea { color: #666; padding: 3px 5px; border-bottom: 1px solid #ddd; - background: #e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; + background: #e1e1e1 url(../../admin/img/admin/nav-bg.gif) top left repeat-x; } .inline-group .tabular tr.add-row td { @@ -1113,7 +1113,7 @@ fieldset.monospace textarea { .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; + background: url(../../admin/img/admin/icon_addlink.gif) 0 50% no-repeat; padding-left: 14px; font-size: 11px; outline: 0; /* Remove dotted border around link */ -- cgit v1.2.3 From 21fcd3a90631e96e3fa210dd526abab9571ad6e1 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 20 Feb 2012 09:36:03 +0000 Subject: Some cleanup --- djangorestframework/mixins.py | 1 - djangorestframework/request.py | 6 ++---- djangorestframework/response.py | 16 ++++++++-------- djangorestframework/tests/mixins.py | 2 +- djangorestframework/views.py | 29 ++++++++++++++--------------- 5 files changed, 25 insertions(+), 29 deletions(-) (limited to 'djangorestframework') diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py index cf746839..aae0f76f 100644 --- a/djangorestframework/mixins.py +++ b/djangorestframework/mixins.py @@ -13,7 +13,6 @@ from djangorestframework.renderers import BaseRenderer from djangorestframework.resources import Resource, FormResource, ModelResource from djangorestframework.response import Response, ImmediateResponse from djangorestframework.request import Request -from djangorestframework.utils import as_tuple, allowed_methods __all__ = ( diff --git a/djangorestframework/request.py b/djangorestframework/request.py index d4ea1e01..e8f2b8c3 100644 --- a/djangorestframework/request.py +++ b/djangorestframework/request.py @@ -9,11 +9,9 @@ The wrapped request then offers a richer API, in particular : - form overloading of HTTP method, content type and content """ -from django.http import HttpRequest - from djangorestframework.response import ImmediateResponse from djangorestframework import status -from djangorestframework.utils.mediatypes import is_form_media_type, order_by_precedence +from djangorestframework.utils.mediatypes import is_form_media_type from djangorestframework.utils import as_tuple from StringIO import StringIO @@ -105,7 +103,7 @@ class Request(object): """ self._content_type = self.META.get('HTTP_CONTENT_TYPE', self.META.get('CONTENT_TYPE', '')) self._perform_form_overloading() - # if the HTTP method was not overloaded, we take the raw HTTP method + # if the HTTP method was not overloaded, we take the raw HTTP method if not hasattr(self, '_method'): self._method = self.request.method diff --git a/djangorestframework/response.py b/djangorestframework/response.py index be2c3ebe..714cd5b8 100644 --- a/djangorestframework/response.py +++ b/djangorestframework/response.py @@ -6,13 +6,13 @@ from any view. It is a bit smarter than Django's `HttpResponse`, for it renders its content to a serial format by using a list of :mod:`renderers`. To determine the content type to which it must render, default behaviour is to use standard -HTTP Accept header content negotiation. But `Response` also supports overriding the content type +HTTP Accept header content negotiation. But `Response` also supports overriding the content type by specifying an ``_accept=`` parameter in the URL. Also, `Response` will ignore `Accept` headers from Internet Explorer user agents and use a sensible browser `Accept` header instead. `ImmediateResponse` is an exception that inherits from `Response`. It can be used -to abort the request handling (i.e. ``View.get``, ``View.put``, ...), +to abort the request handling (i.e. ``View.get``, ``View.put``, ...), and immediately returning a response. """ @@ -31,8 +31,8 @@ class Response(SimpleTemplateResponse): """ An HttpResponse that may include content that hasn't yet been serialized. - Kwargs: - - content(object). The raw content, not yet serialized. This must be simple Python \ + Kwargs: + - content(object). The raw content, not yet serialized. This must be simple Python data that renderers can handle (e.g.: `dict`, `str`, ...) - renderers(list/tuple). The renderers to use for rendering the response content. """ @@ -47,7 +47,7 @@ class Response(SimpleTemplateResponse): # We need to store our content in raw content to avoid overriding HttpResponse's # `content` property - self.raw_content = content + self.raw_content = content self.has_content_body = content is not None self.request = request if renderers is not None: @@ -56,7 +56,7 @@ class Response(SimpleTemplateResponse): @property def rendered_content(self): """ - The final rendered content. Accessing this attribute triggers the complete rendering cycle : + The final rendered content. Accessing this attribute triggers the complete rendering cycle : selecting suitable renderer, setting response's actual content type, rendering data. """ renderer, media_type = self._determine_renderer() @@ -80,9 +80,9 @@ class Response(SimpleTemplateResponse): def _determine_accept_list(self): """ Returns a list of accepted media types. This list is determined from : - + 1. overload with `_ACCEPT_QUERY_PARAM` - 2. `Accept` header of the request + 2. `Accept` header of the request If those are useless, a default value is returned instead. """ diff --git a/djangorestframework/tests/mixins.py b/djangorestframework/tests/mixins.py index 85c95d61..bf0f29f7 100644 --- a/djangorestframework/tests/mixins.py +++ b/djangorestframework/tests/mixins.py @@ -281,6 +281,6 @@ class TestPagination(TestCase): paginated URLs. So page 1 should contain ?page=2, not ?page=1&page=2 """ request = self.req.get('/paginator/?page=1') response = MockPaginatorView.as_view()(request) - content = json.loads(response.content) + content = json.loads(response.rendered_content) self.assertTrue('page=2' in content['next']) self.assertFalse('page=1' in content['next']) diff --git a/djangorestframework/views.py b/djangorestframework/views.py index 93e2d3a3..95fa119d 100644 --- a/djangorestframework/views.py +++ b/djangorestframework/views.py @@ -7,13 +7,12 @@ By setting or modifying class attributes on your view, you change it's predefine import re from django.core.urlresolvers import set_script_prefix, get_script_prefix -from django.http import HttpResponse from django.utils.html import escape from django.utils.safestring import mark_safe from django.views.decorators.csrf import csrf_exempt from djangorestframework.compat import View as DjangoView, apply_markdown -from djangorestframework.response import Response, ImmediateResponse +from djangorestframework.response import ImmediateResponse from djangorestframework.mixins import * from djangorestframework.utils import allowed_methods from djangorestframework import resources, renderers, parsers, authentication, permissions, status @@ -163,6 +162,9 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): return description def markup_description(self, description): + """ + Apply HTML markup to the description of this view. + """ if apply_markdown: description = apply_markdown(description) else: @@ -171,11 +173,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): def http_method_not_allowed(self, request, *args, **kwargs): """ - Return an HTTP 405 error if an operation is called which does not have a handler method. + Return an HTTP 405 error if an operation is called which does not have + a handler method. """ - raise ImmediateResponse( - {'detail': 'Method \'%s\' not allowed on this resource.' % request.method}, - status=status.HTTP_405_METHOD_NOT_ALLOWED) + content = { + 'detail': "Method '%s' not allowed on this resource." % request.method + } + raise ImmediateResponse(content, status.HTTP_405_METHOD_NOT_ALLOWED) def initial(self, request, *args, **kargs): """ @@ -211,17 +215,12 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): # all other authentication is CSRF exempt. @csrf_exempt def dispatch(self, request, *args, **kwargs): - self.request = request + self.request = self.create_request(request) self.args = args self.kwargs = kwargs try: - # Get a custom request, built form the original request instance - self.request = request = self.create_request(request) - - # `initial` is the opportunity to temper with the request, - # even completely replace it. - self.request = request = self.initial(request, *args, **kwargs) + self.initial(request, *args, **kwargs) # Authenticate and check request has the relevant permissions self._check_permissions() @@ -231,7 +230,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed - + # TODO: should we enforce HttpResponse, like Django does ? response = handler(request, *args, **kwargs) @@ -239,7 +238,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): self.response = response = self.prepare_response(response) # Pre-serialize filtering (eg filter complex objects into natively serializable types) - # TODO: ugly hack to handle both HttpResponse and Response. + # TODO: ugly hack to handle both HttpResponse and Response. if hasattr(response, 'raw_content'): response.raw_content = self.filter_response(response.raw_content) else: -- cgit v1.2.3 From af9e4f69d732cc643d6ec7ae13d4a19ac0332d44 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 21 Feb 2012 20:12:14 +0000 Subject: Merging master into develop --- djangorestframework/__init__.py | 2 +- djangorestframework/mixins.py | 6 +- djangorestframework/renderers.py | 6 +- djangorestframework/resources.py | 6 +- djangorestframework/response.py | 3 +- djangorestframework/serializer.py | 2 +- djangorestframework/templates/api_login.html | 44 ------- .../templates/djangorestframework/api.html | 3 + .../templates/djangorestframework/api.txt | 8 ++ .../templates/djangorestframework/base.html | 142 +++++++++++++++++++++ .../templates/djangorestframework/login.html | 44 +++++++ djangorestframework/templates/renderer.html | 129 ------------------- djangorestframework/templates/renderer.txt | 8 -- .../templatetags/add_query_param.py | 3 +- djangorestframework/tests/reverse.py | 4 +- djangorestframework/utils/__init__.py | 21 ++- djangorestframework/utils/staticviews.py | 4 +- djangorestframework/views.py | 11 +- 18 files changed, 236 insertions(+), 210 deletions(-) delete mode 100644 djangorestframework/templates/api_login.html create mode 100644 djangorestframework/templates/djangorestframework/api.html create mode 100644 djangorestframework/templates/djangorestframework/api.txt create mode 100644 djangorestframework/templates/djangorestframework/base.html create mode 100644 djangorestframework/templates/djangorestframework/login.html delete mode 100644 djangorestframework/templates/renderer.html delete mode 100644 djangorestframework/templates/renderer.txt (limited to 'djangorestframework') diff --git a/djangorestframework/__init__.py b/djangorestframework/__init__.py index 0aaa2915..efe7f566 100644 --- a/djangorestframework/__init__.py +++ b/djangorestframework/__init__.py @@ -1,3 +1,3 @@ -__version__ = '0.3.3-dev' +__version__ = '0.3.3' VERSION = __version__ # synonym diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py index aae0f76f..51c859cd 100644 --- a/djangorestframework/mixins.py +++ b/djangorestframework/mixins.py @@ -497,12 +497,12 @@ class PaginatorMixin(object): """ Constructs a url used for getting the next/previous urls """ - url = URLObject.parse(self.request.get_full_path()) - url = url.set_query_param('page', page_number) + url = URLObject(self.request.get_full_path()) + url = url.set_query_param('page', str(page_number)) limit = self.get_limit() if limit != self.limit: - url = url.add_query_param('limit', limit) + url = url.set_query_param('limit', str(limit)) return url diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index 2cc9cc88..d24bcfce 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -379,7 +379,7 @@ class DocumentingHTMLRenderer(DocumentingTemplateRenderer): media_type = 'text/html' format = 'html' - template = 'renderer.html' + template = 'djangorestframework/api.html' class DocumentingXHTMLRenderer(DocumentingTemplateRenderer): @@ -391,7 +391,7 @@ class DocumentingXHTMLRenderer(DocumentingTemplateRenderer): media_type = 'application/xhtml+xml' format = 'xhtml' - template = 'renderer.html' + template = 'djangorestframework/api.html' class DocumentingPlainTextRenderer(DocumentingTemplateRenderer): @@ -403,7 +403,7 @@ class DocumentingPlainTextRenderer(DocumentingTemplateRenderer): media_type = 'text/plain' format = 'txt' - template = 'renderer.txt' + template = 'djangorestframework/api.txt' DEFAULT_RENDERERS = ( diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index 15b3579d..eadc11d0 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -1,10 +1,10 @@ from django import forms -from django.core.urlresolvers import reverse, get_urlconf, get_resolver, NoReverseMatch +from django.core.urlresolvers import get_urlconf, get_resolver, NoReverseMatch from django.db import models from djangorestframework.response import ImmediateResponse from djangorestframework.serializer import Serializer, _SkipField -from djangorestframework.utils import as_tuple +from djangorestframework.utils import as_tuple, reverse class BaseResource(Serializer): @@ -354,7 +354,7 @@ class ModelResource(FormResource): instance_attrs[param] = attr try: - return reverse(self.view_callable[0], kwargs=instance_attrs) + return reverse(self.view_callable[0], self.view.request, kwargs=instance_attrs) except NoReverseMatch: pass raise _SkipField diff --git a/djangorestframework/response.py b/djangorestframework/response.py index 714cd5b8..1c260ecb 100644 --- a/djangorestframework/response.py +++ b/djangorestframework/response.py @@ -40,7 +40,7 @@ class Response(SimpleTemplateResponse): _ACCEPT_QUERY_PARAM = '_accept' # Allow override of Accept header in URL query params _IGNORE_IE_ACCEPT_HEADER = True - def __init__(self, content=None, status=None, request=None, renderers=None): + def __init__(self, content=None, status=None, request=None, renderers=None, headers=None): # First argument taken by `SimpleTemplateResponse.__init__` is template_name, # which we don't need super(Response, self).__init__(None, status=status) @@ -50,6 +50,7 @@ class Response(SimpleTemplateResponse): self.raw_content = content self.has_content_body = content is not None self.request = request + self.headers = headers and headers[:] or [] if renderers is not None: self.renderers = renderers diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index 71c0d93a..b0c02675 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -146,7 +146,7 @@ class Serializer(object): # then the second element of the tuple is the fields to # set on the related serializer if isinstance(info, (list, tuple)): - class OnTheFlySerializer(Serializer): + class OnTheFlySerializer(self.__class__): fields = info return OnTheFlySerializer diff --git a/djangorestframework/templates/api_login.html b/djangorestframework/templates/api_login.html deleted file mode 100644 index 07929f0c..00000000 --- a/djangorestframework/templates/api_login.html +++ /dev/null @@ -1,44 +0,0 @@ -{% load static %} - - - - - - - - -
- - - -
-
-
- {% csrf_token %} -
- {{ form.username }} -
-
- {{ form.password }} - -
-
- -
-
- -
-
-
- - - -
- - diff --git a/djangorestframework/templates/djangorestframework/api.html b/djangorestframework/templates/djangorestframework/api.html new file mode 100644 index 00000000..fd9bcc98 --- /dev/null +++ b/djangorestframework/templates/djangorestframework/api.html @@ -0,0 +1,3 @@ +{% extends "djangorestframework/base.html" %} + +{# Override this template in your own templates directory to customize #} \ No newline at end of file diff --git a/djangorestframework/templates/djangorestframework/api.txt b/djangorestframework/templates/djangorestframework/api.txt new file mode 100644 index 00000000..b584952c --- /dev/null +++ b/djangorestframework/templates/djangorestframework/api.txt @@ -0,0 +1,8 @@ +{% autoescape off %}{{ name }} + +{{ description }} + +HTTP/1.0 {{ response.status }} {{ response.status_text }} +{% for key, val in response.headers.items %}{{ key }}: {{ val }} +{% endfor %} +{{ content }}{% endautoescape %} diff --git a/djangorestframework/templates/djangorestframework/base.html b/djangorestframework/templates/djangorestframework/base.html new file mode 100644 index 00000000..fa913c33 --- /dev/null +++ b/djangorestframework/templates/djangorestframework/base.html @@ -0,0 +1,142 @@ + + +{% load urlize_quoted_links %} +{% load add_query_param %} +{% load static %} + + + + {% block extrastyle %}{% endblock %} + {% block title %}Django REST framework - {{ name }}{% endblock %} + {% block extrahead %}{% endblock %} + {% block blockbots %}{% endblock %} + + +
+ + + + + + +
+ + {% if 'OPTIONS' in allowed_methods %} +
+ {% csrf_token %} + + +
+ {% endif %} + +
+

{{ name }}

+

{{ description }}

+
+
{{ response.status_code }} {{ response.status_text }}{% autoescape off %}
+{% for key, val in response.items %}{{ key }}: {{ val|urlize_quoted_links }}
+{% endfor %}
+{{ content|urlize_quoted_links }}
{% endautoescape %}
+ + {% if 'GET' in allowed_methods %} +
+
+

GET {{ name }}

+
+ GET + {% for format in available_formats %} + {% with FORMAT_PARAM|add:"="|add:format as param %} + [{{ format }}] + {% endwith %} + {% endfor %} +
+
+
+ {% endif %} + + {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled and the user has permissions on this view. #} + {% if METHOD_PARAM and response.status_code != 403 %} + + {% if 'POST' in allowed_methods %} +
+
+

POST {{ name }}

+ {% csrf_token %} + {{ post_form.non_field_errors }} + {% for field in post_form %} +
+ {{ field.label_tag }} + {{ field }} + {{ field.help_text }} + {{ field.errors }} +
+ {% endfor %} +
+ +
+
+
+ {% endif %} + + {% if 'PUT' in allowed_methods %} +
+
+

PUT {{ name }}

+ + {% csrf_token %} + {{ put_form.non_field_errors }} + {% for field in put_form %} +
+ {{ field.label_tag }} + {{ field }} + {{ field.help_text }} + {{ field.errors }} +
+ {% endfor %} +
+ +
+
+
+ {% endif %} + + {% if 'DELETE' in allowed_methods %} +
+
+

DELETE {{ name }}

+ {% csrf_token %} + +
+ +
+
+
+ {% endif %} + + {% endif %} +
+ + +
+ + + {% block footer %}{% endblock %} +
+ + diff --git a/djangorestframework/templates/djangorestframework/login.html b/djangorestframework/templates/djangorestframework/login.html new file mode 100644 index 00000000..07929f0c --- /dev/null +++ b/djangorestframework/templates/djangorestframework/login.html @@ -0,0 +1,44 @@ +{% load static %} + + + + + + + + +
+ + + +
+
+
+ {% csrf_token %} +
+ {{ form.username }} +
+
+ {{ form.password }} + +
+
+ +
+
+ +
+
+
+ + + +
+ + diff --git a/djangorestframework/templates/renderer.html b/djangorestframework/templates/renderer.html deleted file mode 100644 index 18e60110..00000000 --- a/djangorestframework/templates/renderer.html +++ /dev/null @@ -1,129 +0,0 @@ - - -{% load urlize_quoted_links %} -{% load add_query_param %} -{% load static %} - - - - Django REST framework - {{ name }} - - -
- - - - - -
- - {% if 'OPTIONS' in allowed_methods %} -
- {% csrf_token %} - - -
- {% endif %} - -
-

{{ name }}

-

{{ description }}

-
-
{{ response.status_code }} {{ response.status_text }}{% autoescape off %}
-{% for key, val in response.items %}{{ key }}: {{ val|urlize_quoted_links }}
-{% endfor %}
-{{ content|urlize_quoted_links }}
{% endautoescape %}
- - {% if 'GET' in allowed_methods %} -
-
-

GET {{ name }}

-
- GET - {% for format in available_formats %} - {% with FORMAT_PARAM|add:"="|add:format as param %} - [{{ format }}] - {% endwith %} - {% endfor %} -
-
-
- {% endif %} - - {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled and the user has permissions on this view. #} - {% if METHOD_PARAM and response.status_code != 403 %} - - {% if 'POST' in allowed_methods %} -
-
-

POST {{ name }}

- {% csrf_token %} - {{ post_form.non_field_errors }} - {% for field in post_form %} -
- {{ field.label_tag }} - {{ field }} - {{ field.help_text }} - {{ field.errors }} -
- {% endfor %} -
- -
-
-
- {% endif %} - - {% if 'PUT' in allowed_methods %} -
-
-

PUT {{ name }}

- - {% csrf_token %} - {{ put_form.non_field_errors }} - {% for field in put_form %} -
- {{ field.label_tag }} - {{ field }} - {{ field.help_text }} - {{ field.errors }} -
- {% endfor %} -
- -
-
-
- {% endif %} - - {% if 'DELETE' in allowed_methods %} -
-
-

DELETE {{ name }}

- {% csrf_token %} - -
- -
-
-
- {% endif %} - - {% endif %} -
-
-
- - diff --git a/djangorestframework/templates/renderer.txt b/djangorestframework/templates/renderer.txt deleted file mode 100644 index b584952c..00000000 --- a/djangorestframework/templates/renderer.txt +++ /dev/null @@ -1,8 +0,0 @@ -{% autoescape off %}{{ name }} - -{{ description }} - -HTTP/1.0 {{ response.status }} {{ response.status_text }} -{% for key, val in response.headers.items %}{{ key }}: {{ val }} -{% endfor %} -{{ content }}{% endautoescape %} diff --git a/djangorestframework/templatetags/add_query_param.py b/djangorestframework/templatetags/add_query_param.py index 11709730..4cf0133b 100644 --- a/djangorestframework/templatetags/add_query_param.py +++ b/djangorestframework/templatetags/add_query_param.py @@ -4,8 +4,7 @@ register = Library() def add_query_param(url, param): - (key, sep, val) = param.partition('=') - return unicode(URLObject.parse(url) & (key, val)) + return unicode(URLObject(url).with_query(param)) register.filter('add_query_param', add_query_param) diff --git a/djangorestframework/tests/reverse.py b/djangorestframework/tests/reverse.py index c49caca0..05c21faa 100644 --- a/djangorestframework/tests/reverse.py +++ b/djangorestframework/tests/reverse.py @@ -1,8 +1,8 @@ from django.conf.urls.defaults import patterns, url -from django.core.urlresolvers import reverse from django.test import TestCase from django.utils import simplejson as json +from djangorestframework.utils import reverse from djangorestframework.views import View from djangorestframework.response import Response @@ -12,7 +12,7 @@ class MockView(View): permissions = () def get(self, request): - return Response(reverse('another')) + return Response(reverse('another', request)) urlpatterns = patterns('', url(r'^$', MockView.as_view()), diff --git a/djangorestframework/utils/__init__.py b/djangorestframework/utils/__init__.py index fbe55474..afef4f19 100644 --- a/djangorestframework/utils/__init__.py +++ b/djangorestframework/utils/__init__.py @@ -1,6 +1,7 @@ +import django from django.utils.encoding import smart_unicode from django.utils.xmlutils import SimplerXMLGenerator -from django.core.urlresolvers import resolve +from django.core.urlresolvers import resolve, reverse as django_reverse from django.conf import settings from djangorestframework.compat import StringIO @@ -180,3 +181,21 @@ class XMLRenderer(): def dict2xml(input): return XMLRenderer().dict2xml(input) + + +def reverse(viewname, request, *args, **kwargs): + """ + Do the same as :py:func:`django.core.urlresolvers.reverse` but using + *request* to build a fully qualified URL. + """ + return request.build_absolute_uri(django_reverse(viewname, *args, **kwargs)) + +if django.VERSION >= (1, 4): + from django.core.urlresolvers import reverse_lazy as django_reverse_lazy + + def reverse_lazy(viewname, request, *args, **kwargs): + """ + Do the same as :py:func:`django.core.urlresolvers.reverse_lazy` but using + *request* to build a fully qualified URL. + """ + return request.build_absolute_uri(django_reverse_lazy(viewname, *args, **kwargs)) diff --git a/djangorestframework/utils/staticviews.py b/djangorestframework/utils/staticviews.py index 9bae0ee7..7cbc0b9b 100644 --- a/djangorestframework/utils/staticviews.py +++ b/djangorestframework/utils/staticviews.py @@ -12,7 +12,7 @@ import base64 # be making settings changes in order to accomodate django-rest-framework @csrf_protect @never_cache -def api_login(request, template_name='api_login.html', +def api_login(request, template_name='djangorestframework/login.html', redirect_field_name=REDIRECT_FIELD_NAME, authentication_form=AuthenticationForm): """Displays the login form and handles the login action.""" @@ -57,5 +57,5 @@ def api_login(request, template_name='api_login.html', }, context_instance=RequestContext(request)) -def api_logout(request, next_page=None, template_name='api_login.html', redirect_field_name=REDIRECT_FIELD_NAME): +def api_logout(request, next_page=None, template_name='djangorestframework/login.html', redirect_field_name=REDIRECT_FIELD_NAME): return logout(request, next_page, template_name, redirect_field_name) diff --git a/djangorestframework/views.py b/djangorestframework/views.py index 95fa119d..6bfc4192 100644 --- a/djangorestframework/views.py +++ b/djangorestframework/views.py @@ -188,22 +188,13 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): Required if you want to do things like set `request.upload_handlers` before the authentication and dispatch handling is run. """ - # Calls to 'reverse' will not be fully qualified unless we set the - # scheme/host/port here. - self.orig_prefix = get_script_prefix() - if not (self.orig_prefix.startswith('http:') or self.orig_prefix.startswith('https:')): - prefix = '%s://%s' % (request.is_secure() and 'https' or 'http', request.get_host()) - set_script_prefix(prefix + self.orig_prefix) - return request + pass def final(self, request, response, *args, **kargs): """ Returns an `HttpResponse`. This method is a hook for any code that needs to run after everything else in the view. """ - # Restore script_prefix. - set_script_prefix(self.orig_prefix) - # Always add these headers. response['Allow'] = ', '.join(allowed_methods(self)) # sample to allow caching using Vary http header -- cgit v1.2.3 From 5fd4c639d7c64572dd07dc31dcd627bed9469b05 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 21 Feb 2012 20:57:36 +0000 Subject: Merge master into develop --- djangorestframework/compat.py | 8 ++++++++ djangorestframework/resources.py | 1 + djangorestframework/reverse.py | 23 +++++++++++++++++++++++ djangorestframework/tests/reverse.py | 23 ++++++++++++++--------- 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 djangorestframework/reverse.py (limited to 'djangorestframework') diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index 7690316c..b818b446 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -457,3 +457,11 @@ except ImportError: # python < 2.7 return decorator unittest.skip = skip + +# reverse_lazy (Django 1.4 onwards) +try: + from django.core.urlresolvers import reverse_lazy +except: + from django.core.urlresolvers import reverse + from django.utils.functional import lazy + reverse_lazy = lazy(reverse, str) diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index eadc11d0..8ee49f82 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -3,6 +3,7 @@ from django.core.urlresolvers import get_urlconf, get_resolver, NoReverseMatch from django.db import models from djangorestframework.response import ImmediateResponse +from djangorestframework.reverse import reverse from djangorestframework.serializer import Serializer, _SkipField from djangorestframework.utils import as_tuple, reverse diff --git a/djangorestframework/reverse.py b/djangorestframework/reverse.py new file mode 100644 index 00000000..ad06f966 --- /dev/null +++ b/djangorestframework/reverse.py @@ -0,0 +1,23 @@ +""" +Provide reverse functions that return fully qualified URLs +""" +from django.core.urlresolvers import reverse as django_reverse +from djangorestframework.compat import reverse_lazy as django_reverse_lazy + + +def reverse(viewname, request, *args, **kwargs): + """ + Do the same as `django.core.urlresolvers.reverse` but using + *request* to build a fully qualified URL. + """ + url = django_reverse(viewname, *args, **kwargs) + return request.build_absolute_uri(url) + + +def reverse_lazy(viewname, request, *args, **kwargs): + """ + Do the same as `django.core.urlresolvers.reverse_lazy` but using + *request* to build a fully qualified URL. + """ + url = django_reverse_lazy(viewname, *args, **kwargs) + return request.build_absolute_uri(url) diff --git a/djangorestframework/tests/reverse.py b/djangorestframework/tests/reverse.py index 05c21faa..c2388d62 100644 --- a/djangorestframework/tests/reverse.py +++ b/djangorestframework/tests/reverse.py @@ -2,28 +2,33 @@ from django.conf.urls.defaults import patterns, url from django.test import TestCase from django.utils import simplejson as json -from djangorestframework.utils import reverse +from djangorestframework.renderers import JSONRenderer +from djangorestframework.reverse import reverse from djangorestframework.views import View from djangorestframework.response import Response -class MockView(View): - """Mock resource which simply returns a URL, so that we can ensure that reversed URLs are fully qualified""" - permissions = () +class MyView(View): + """ + Mock resource which simply returns a URL, so that we can ensure + that reversed URLs are fully qualified. + """ + renderers = (JSONRenderer, ) def get(self, request): return Response(reverse('another', request)) urlpatterns = patterns('', - url(r'^$', MockView.as_view()), - url(r'^another$', MockView.as_view(), name='another'), + url(r'^myview$', MyView.as_view(), name='myview'), ) class ReverseTests(TestCase): - """Tests for """ + """ + Tests for fully qualifed URLs when using `reverse`. + """ urls = 'djangorestframework.tests.reverse' def test_reversed_urls_are_fully_qualified(self): - response = self.client.get('/') - self.assertEqual(json.loads(response.content), 'http://testserver/another') + response = self.client.get('/myview') + self.assertEqual(json.loads(response.content), 'http://testserver/myview') -- cgit v1.2.3