diff --git a/htmlcov/coverage_html.js b/htmlcov/coverage_html.js deleted file mode 100644 index da3e22c81..000000000 --- a/htmlcov/coverage_html.js +++ /dev/null @@ -1,372 +0,0 @@ -// Coverage.py HTML report browser code. -/*jslint browser: true, sloppy: true, vars: true, plusplus: true, maxerr: 50, indent: 4 */ -/*global coverage: true, document, window, $ */ - -coverage = {}; - -// Find all the elements with shortkey_* class, and use them to assign a shotrtcut key. -coverage.assign_shortkeys = function () { - $("*[class*='shortkey_']").each(function (i, e) { - $.each($(e).attr("class").split(" "), function (i, c) { - if (/^shortkey_/.test(c)) { - $(document).bind('keydown', c.substr(9), function () { - $(e).click(); - }); - } - }); - }); -}; - -// Create the events for the help panel. -coverage.wire_up_help_panel = function () { - $("#keyboard_icon").click(function () { - // Show the help panel, and position it so the keyboard icon in the - // panel is in the same place as the keyboard icon in the header. - $(".help_panel").show(); - var koff = $("#keyboard_icon").offset(); - var poff = $("#panel_icon").position(); - $(".help_panel").offset({ - top: koff.top-poff.top, - left: koff.left-poff.left - }); - }); - $("#panel_icon").click(function () { - $(".help_panel").hide(); - }); -}; - -// Loaded on index.html -coverage.index_ready = function ($) { - // Look for a cookie containing previous sort settings: - var sort_list = []; - var cookie_name = "COVERAGE_INDEX_SORT"; - var i; - - // This almost makes it worth installing the jQuery cookie plugin: - if (document.cookie.indexOf(cookie_name) > -1) { - var cookies = document.cookie.split(";"); - for (i = 0; i < cookies.length; i++) { - var parts = cookies[i].split("="); - - if ($.trim(parts[0]) === cookie_name && parts[1]) { - sort_list = eval("[[" + parts[1] + "]]"); - break; - } - } - } - - // Create a new widget which exists only to save and restore - // the sort order: - $.tablesorter.addWidget({ - id: "persistentSort", - - // Format is called by the widget before displaying: - format: function (table) { - if (table.config.sortList.length === 0 && sort_list.length > 0) { - // This table hasn't been sorted before - we'll use - // our stored settings: - $(table).trigger('sorton', [sort_list]); - } - else { - // This is not the first load - something has - // already defined sorting so we'll just update - // our stored value to match: - sort_list = table.config.sortList; - } - } - }); - - // Configure our tablesorter to handle the variable number of - // columns produced depending on report options: - var headers = []; - var col_count = $("table.index > thead > tr > th").length; - - headers[0] = { sorter: 'text' }; - for (i = 1; i < col_count-1; i++) { - headers[i] = { sorter: 'digit' }; - } - headers[col_count-1] = { sorter: 'percent' }; - - // Enable the table sorter: - $("table.index").tablesorter({ - widgets: ['persistentSort'], - headers: headers - }); - - coverage.assign_shortkeys(); - coverage.wire_up_help_panel(); - - // Watch for page unload events so we can save the final sort settings: - $(window).unload(function () { - document.cookie = cookie_name + "=" + sort_list.toString() + "; path=/"; - }); -}; - -// -- pyfile stuff -- - -coverage.pyfile_ready = function ($) { - // If we're directed to a particular line number, highlight the line. - var frag = location.hash; - if (frag.length > 2 && frag[1] === 'n') { - $(frag).addClass('highlight'); - coverage.set_sel(parseInt(frag.substr(2), 10)); - } - else { - coverage.set_sel(0); - } - - $(document) - .bind('keydown', 'j', coverage.to_next_chunk_nicely) - .bind('keydown', 'k', coverage.to_prev_chunk_nicely) - .bind('keydown', '0', coverage.to_top) - .bind('keydown', '1', coverage.to_first_chunk) - ; - - coverage.assign_shortkeys(); - coverage.wire_up_help_panel(); -}; - -coverage.toggle_lines = function (btn, cls) { - btn = $(btn); - var hide = "hide_"+cls; - if (btn.hasClass(hide)) { - $("#source ."+cls).removeClass(hide); - btn.removeClass(hide); - } - else { - $("#source ."+cls).addClass(hide); - btn.addClass(hide); - } -}; - -// Return the nth line div. -coverage.line_elt = function (n) { - return $("#t" + n); -}; - -// Return the nth line number div. -coverage.num_elt = function (n) { - return $("#n" + n); -}; - -// Return the container of all the code. -coverage.code_container = function () { - return $(".linenos"); -}; - -// Set the selection. b and e are line numbers. -coverage.set_sel = function (b, e) { - // The first line selected. - coverage.sel_begin = b; - // The next line not selected. - coverage.sel_end = (e === undefined) ? b+1 : e; -}; - -coverage.to_top = function () { - coverage.set_sel(0, 1); - coverage.scroll_window(0); -}; - -coverage.to_first_chunk = function () { - coverage.set_sel(0, 1); - coverage.to_next_chunk(); -}; - -coverage.is_transparent = function (color) { - // Different browsers return different colors for "none". - return color === "transparent" || color === "rgba(0, 0, 0, 0)"; -}; - -coverage.to_next_chunk = function () { - var c = coverage; - - // Find the start of the next colored chunk. - var probe = c.sel_end; - while (true) { - var probe_line = c.line_elt(probe); - if (probe_line.length === 0) { - return; - } - var color = probe_line.css("background-color"); - if (!c.is_transparent(color)) { - break; - } - probe++; - } - - // There's a next chunk, `probe` points to it. - var begin = probe; - - // Find the end of this chunk. - var next_color = color; - while (next_color === color) { - probe++; - probe_line = c.line_elt(probe); - next_color = probe_line.css("background-color"); - } - c.set_sel(begin, probe); - c.show_selection(); -}; - -coverage.to_prev_chunk = function () { - var c = coverage; - - // Find the end of the prev colored chunk. - var probe = c.sel_begin-1; - var probe_line = c.line_elt(probe); - if (probe_line.length === 0) { - return; - } - var color = probe_line.css("background-color"); - while (probe > 0 && c.is_transparent(color)) { - probe--; - probe_line = c.line_elt(probe); - if (probe_line.length === 0) { - return; - } - color = probe_line.css("background-color"); - } - - // There's a prev chunk, `probe` points to its last line. - var end = probe+1; - - // Find the beginning of this chunk. - var prev_color = color; - while (prev_color === color) { - probe--; - probe_line = c.line_elt(probe); - prev_color = probe_line.css("background-color"); - } - c.set_sel(probe+1, end); - c.show_selection(); -}; - -// Return the line number of the line nearest pixel position pos -coverage.line_at_pos = function (pos) { - var l1 = coverage.line_elt(1), - l2 = coverage.line_elt(2), - result; - if (l1.length && l2.length) { - var l1_top = l1.offset().top, - line_height = l2.offset().top - l1_top, - nlines = (pos - l1_top) / line_height; - if (nlines < 1) { - result = 1; - } - else { - result = Math.ceil(nlines); - } - } - else { - result = 1; - } - return result; -}; - -// Returns 0, 1, or 2: how many of the two ends of the selection are on -// the screen right now? -coverage.selection_ends_on_screen = function () { - if (coverage.sel_begin === 0) { - return 0; - } - - var top = coverage.line_elt(coverage.sel_begin); - var next = coverage.line_elt(coverage.sel_end-1); - - return ( - (top.isOnScreen() ? 1 : 0) + - (next.isOnScreen() ? 1 : 0) - ); -}; - -coverage.to_next_chunk_nicely = function () { - coverage.finish_scrolling(); - if (coverage.selection_ends_on_screen() === 0) { - // The selection is entirely off the screen: select the top line on - // the screen. - var win = $(window); - coverage.select_line_or_chunk(coverage.line_at_pos(win.scrollTop())); - } - coverage.to_next_chunk(); -}; - -coverage.to_prev_chunk_nicely = function () { - coverage.finish_scrolling(); - if (coverage.selection_ends_on_screen() === 0) { - var win = $(window); - coverage.select_line_or_chunk(coverage.line_at_pos(win.scrollTop() + win.height())); - } - coverage.to_prev_chunk(); -}; - -// Select line number lineno, or if it is in a colored chunk, select the -// entire chunk -coverage.select_line_or_chunk = function (lineno) { - var c = coverage; - var probe_line = c.line_elt(lineno); - if (probe_line.length === 0) { - return; - } - var the_color = probe_line.css("background-color"); - if (!c.is_transparent(the_color)) { - // The line is in a highlighted chunk. - // Search backward for the first line. - var probe = lineno; - var color = the_color; - while (probe > 0 && color === the_color) { - probe--; - probe_line = c.line_elt(probe); - if (probe_line.length === 0) { - break; - } - color = probe_line.css("background-color"); - } - var begin = probe + 1; - - // Search forward for the last line. - probe = lineno; - color = the_color; - while (color === the_color) { - probe++; - probe_line = c.line_elt(probe); - color = probe_line.css("background-color"); - } - - coverage.set_sel(begin, probe); - } - else { - coverage.set_sel(lineno); - } -}; - -coverage.show_selection = function () { - var c = coverage; - - // Highlight the lines in the chunk - c.code_container().find(".highlight").removeClass("highlight"); - for (var probe = c.sel_begin; probe > 0 && probe < c.sel_end; probe++) { - c.num_elt(probe).addClass("highlight"); - } - - c.scroll_to_selection(); -}; - -coverage.scroll_to_selection = function () { - // Scroll the page if the chunk isn't fully visible. - if (coverage.selection_ends_on_screen() < 2) { - // Need to move the page. The html,body trick makes it scroll in all - // browsers, got it from http://stackoverflow.com/questions/3042651 - var top = coverage.line_elt(coverage.sel_begin); - var top_pos = parseInt(top.offset().top, 10); - coverage.scroll_window(top_pos - 30); - } -}; - -coverage.scroll_window = function (to_pos) { - $("html,body").animate({scrollTop: to_pos}, 200); -}; - -coverage.finish_scrolling = function () { - $("html,body").stop(true, true); -}; - diff --git a/htmlcov/index.html b/htmlcov/index.html deleted file mode 100644 index 983451658..000000000 --- a/htmlcov/index.html +++ /dev/null @@ -1,404 +0,0 @@ - - - - - Coverage report - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- n - s - m - x - - c   change column sorting -

-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Modulestatementsmissingexcludedcoverage
Total3621406089%
rest_framework/__init__400100%
rest_framework/authentication16933080%
rest_framework/authtoken/__init__000100%
rest_framework/authtoken/models211095%
rest_framework/authtoken/serializers172088%
rest_framework/authtoken/views2100100%
rest_framework/decorators6000100%
rest_framework/exceptions512096%
rest_framework/fields59480087%
rest_framework/filters776092%
rest_framework/generics19634083%
rest_framework/mixins977093%
rest_framework/models000100%
rest_framework/negotiation414090%
rest_framework/pagination4300100%
rest_framework/parsers15313092%
rest_framework/permissions6312081%
rest_framework/relations36588076%
rest_framework/renderers28223092%
rest_framework/request1618095%
rest_framework/response421098%
rest_framework/reverse123075%
rest_framework/routers1087094%
rest_framework/serializers46427094%
rest_framework/settings442095%
rest_framework/status4600100%
rest_framework/throttling9017081%
rest_framework/urlpatterns314087%
rest_framework/urls400100%
rest_framework/utils/__init__000100%
rest_framework/utils/breadcrumbs2700100%
rest_framework/utils/encoders7019073%
rest_framework/utils/formatting391097%
rest_framework/utils/mediatypes4410077%
rest_framework/views14600100%
rest_framework/viewsets392095%
-
- - - - - diff --git a/htmlcov/jquery-1.4.3.min.js b/htmlcov/jquery-1.4.3.min.js deleted file mode 100644 index c941a5f7a..000000000 --- a/htmlcov/jquery-1.4.3.min.js +++ /dev/null @@ -1,166 +0,0 @@ -/*! - * jQuery JavaScript Library v1.4.3 - * http://jquery.com/ - * - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2010, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Oct 14 23:10:06 2010 -0400 - */ -(function(E,A){function U(){return false}function ba(){return true}function ja(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ga(a){var b,d,e=[],f=[],h,k,l,n,s,v,B,D;k=c.data(this,this.nodeType?"events":"__events__");if(typeof k==="function")k=k.events;if(!(a.liveFired===this||!k||!k.live||a.button&&a.type==="click")){if(a.namespace)D=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var H=k.live.slice(0);for(n=0;nd)break;a.currentTarget=f.elem;a.data=f.handleObj.data; -a.handleObj=f.handleObj;D=f.handleObj.origHandler.apply(f.elem,arguments);if(D===false||a.isPropagationStopped()){d=f.level;if(D===false)b=false}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(Ha,"`").replace(Ia,"&")}function ka(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Ja.test(b))return c.filter(b, -e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function la(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var k in e[h])c.event.add(this,h,e[h][k],e[h][k].data)}}})}function Ka(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)} -function ma(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?La:Ma,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function ca(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Na.test(a)?e(a,h):ca(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)? -e(a,""):c.each(b,function(f,h){ca(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(na.concat.apply([],na.slice(0,b)),function(){d[this]=a});return d}function oa(a){if(!da[a]){var b=c("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";da[a]=d}return da[a]}function ea(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var u=E.document,c=function(){function a(){if(!b.isReady){try{u.documentElement.doScroll("left")}catch(i){setTimeout(a, -1);return}b.ready()}}var b=function(i,r){return new b.fn.init(i,r)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,k=/\S/,l=/^\s+/,n=/\s+$/,s=/\W/,v=/\d/,B=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,D=/^[\],:{}\s]*$/,H=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,G=/(?:^|:|,)(?:\s*\[)+/g,M=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,j=/(msie) ([\w.]+)/,o=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false, -q=[],t,x=Object.prototype.toString,C=Object.prototype.hasOwnProperty,P=Array.prototype.push,N=Array.prototype.slice,R=String.prototype.trim,Q=Array.prototype.indexOf,L={};b.fn=b.prototype={init:function(i,r){var y,z,F;if(!i)return this;if(i.nodeType){this.context=this[0]=i;this.length=1;return this}if(i==="body"&&!r&&u.body){this.context=u;this[0]=u.body;this.selector="body";this.length=1;return this}if(typeof i==="string")if((y=h.exec(i))&&(y[1]||!r))if(y[1]){F=r?r.ownerDocument||r:u;if(z=B.exec(i))if(b.isPlainObject(r)){i= -[u.createElement(z[1])];b.fn.attr.call(i,r,true)}else i=[F.createElement(z[1])];else{z=b.buildFragment([y[1]],[F]);i=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,i)}else{if((z=u.getElementById(y[2]))&&z.parentNode){if(z.id!==y[2])return f.find(i);this.length=1;this[0]=z}this.context=u;this.selector=i;return this}else if(!r&&!s.test(i)){this.selector=i;this.context=u;i=u.getElementsByTagName(i);return b.merge(this,i)}else return!r||r.jquery?(r||f).find(i):b(r).find(i); -else if(b.isFunction(i))return f.ready(i);if(i.selector!==A){this.selector=i.selector;this.context=i.context}return b.makeArray(i,this)},selector:"",jquery:"1.4.3",length:0,size:function(){return this.length},toArray:function(){return N.call(this,0)},get:function(i){return i==null?this.toArray():i<0?this.slice(i)[0]:this[i]},pushStack:function(i,r,y){var z=b();b.isArray(i)?P.apply(z,i):b.merge(z,i);z.prevObject=this;z.context=this.context;if(r==="find")z.selector=this.selector+(this.selector?" ": -"")+y;else if(r)z.selector=this.selector+"."+r+"("+y+")";return z},each:function(i,r){return b.each(this,i,r)},ready:function(i){b.bindReady();if(b.isReady)i.call(u,b);else q&&q.push(i);return this},eq:function(i){return i===-1?this.slice(i):this.slice(i,+i+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(i){return this.pushStack(b.map(this,function(r,y){return i.call(r, -y,r)}))},end:function(){return this.prevObject||b(null)},push:P,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var i=arguments[0]||{},r=1,y=arguments.length,z=false,F,I,K,J,fa;if(typeof i==="boolean"){z=i;i=arguments[1]||{};r=2}if(typeof i!=="object"&&!b.isFunction(i))i={};if(y===r){i=this;--r}for(;r0)){if(q){for(var r=0;i=q[r++];)i.call(u,b);q=null}b.fn.triggerHandler&&b(u).triggerHandler("ready")}}},bindReady:function(){if(!p){p=true;if(u.readyState==="complete")return setTimeout(b.ready, -1);if(u.addEventListener){u.addEventListener("DOMContentLoaded",t,false);E.addEventListener("load",b.ready,false)}else if(u.attachEvent){u.attachEvent("onreadystatechange",t);E.attachEvent("onload",b.ready);var i=false;try{i=E.frameElement==null}catch(r){}u.documentElement.doScroll&&i&&a()}}},isFunction:function(i){return b.type(i)==="function"},isArray:Array.isArray||function(i){return b.type(i)==="array"},isWindow:function(i){return i&&typeof i==="object"&&"setInterval"in i},isNaN:function(i){return i== -null||!v.test(i)||isNaN(i)},type:function(i){return i==null?String(i):L[x.call(i)]||"object"},isPlainObject:function(i){if(!i||b.type(i)!=="object"||i.nodeType||b.isWindow(i))return false;if(i.constructor&&!C.call(i,"constructor")&&!C.call(i.constructor.prototype,"isPrototypeOf"))return false;for(var r in i);return r===A||C.call(i,r)},isEmptyObject:function(i){for(var r in i)return false;return true},error:function(i){throw i;},parseJSON:function(i){if(typeof i!=="string"||!i)return null;i=b.trim(i); -if(D.test(i.replace(H,"@").replace(w,"]").replace(G,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(i):(new Function("return "+i))();else b.error("Invalid JSON: "+i)},noop:function(){},globalEval:function(i){if(i&&k.test(i)){var r=u.getElementsByTagName("head")[0]||u.documentElement,y=u.createElement("script");y.type="text/javascript";if(b.support.scriptEval)y.appendChild(u.createTextNode(i));else y.text=i;r.insertBefore(y,r.firstChild);r.removeChild(y)}},nodeName:function(i,r){return i.nodeName&&i.nodeName.toUpperCase()=== -r.toUpperCase()},each:function(i,r,y){var z,F=0,I=i.length,K=I===A||b.isFunction(i);if(y)if(K)for(z in i){if(r.apply(i[z],y)===false)break}else for(;F";a=u.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var s=u.createElement("div"); -s.style.width=s.style.paddingLeft="1px";u.body.appendChild(s);c.boxModel=c.support.boxModel=s.offsetWidth===2;if("zoom"in s.style){s.style.display="inline";s.style.zoom=1;c.support.inlineBlockNeedsLayout=s.offsetWidth===2;s.style.display="";s.innerHTML="
";c.support.shrinkWrapBlocks=s.offsetWidth!==2}s.innerHTML="
t
";var v=s.getElementsByTagName("td");c.support.reliableHiddenOffsets=v[0].offsetHeight=== -0;v[0].style.display="";v[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&v[0].offsetHeight===0;s.innerHTML="";u.body.removeChild(s).style.display="none"});a=function(s){var v=u.createElement("div");s="on"+s;var B=s in v;if(!B){v.setAttribute(s,"return;");B=typeof v[s]==="function"}return B};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength", -cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var pa={},Oa=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?pa:a;var e=a.nodeType,f=e?a[c.expando]:null,h=c.cache;if(!(e&&!f&&typeof b==="string"&&d===A)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]= -c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==A)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?pa:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);else if(d)delete f[e];else for(var k in a)delete a[k]}},acceptData:function(a){if(a.nodeName){var b= -c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){if(typeof a==="undefined")return this.length?c.data(this[0]):null;else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===A){var e=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(e===A&&this.length){e=c.data(this[0],a);if(e===A&&this[0].nodeType===1){e=this[0].getAttribute("data-"+a);if(typeof e=== -"string")try{e=e==="true"?true:e==="false"?false:e==="null"?null:!c.isNaN(e)?parseFloat(e):Oa.test(e)?c.parseJSON(e):e}catch(f){}else e=A}}return e===A&&d[1]?this.data(d[0]):e}else return this.each(function(){var h=c(this),k=[d[0],b];h.triggerHandler("setData"+d[1]+"!",k);c.data(this,a,b);h.triggerHandler("changeData"+d[1]+"!",k)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=c.data(a,b);if(!d)return e|| -[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===A)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this, -a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var qa=/[\n\t]/g,ga=/\s+/,Pa=/\r/g,Qa=/^(?:href|src|style)$/,Ra=/^(?:button|input)$/i,Sa=/^(?:button|input|object|select|textarea)$/i,Ta=/^a(?:rea)?$/i,ra=/^(?:radio|checkbox)$/i;c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this, -a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(s){var v=c(this);v.addClass(a.call(this,s,v.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ga),d=0,e=this.length;d-1)return true;return false}, -val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h=0;else if(c.nodeName(this,"select")){var B=c.makeArray(v);c("option",this).each(function(){this.selected= -c.inArray(c(this).val(),B)>=0});if(!B.length)this.selectedIndex=-1}else this.value=v}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return A;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==A;b=e&&c.props[b]||b;if(a.nodeType===1){var h=Qa.test(b);if((b in a||a[b]!==A)&&e&&!h){if(f){b==="type"&&Ra.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); -if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Sa.test(a.nodeName)||Ta.test(a.nodeName)&&a.href?0:A;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return A;a=!c.support.hrefNormalized&&e&& -h?a.getAttribute(b,2):a.getAttribute(b);return a===null?A:a}}});var X=/\.(.*)$/,ha=/^(?:textarea|input|select)$/i,Ha=/\./g,Ia=/ /g,Ua=/[^\w\s.|`]/g,Va=function(a){return a.replace(Ua,"\\$&")},sa={focusin:0,focusout:0};c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var k=a.nodeType?"events":"__events__",l=h[k],n=h.handle;if(typeof l=== -"function"){n=l.handle;l=l.events}else if(!l){a.nodeType||(h[k]=h=function(){});h.events=l={}}if(!n)h.handle=n=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(n.elem,arguments):A};n.elem=a;b=b.split(" ");for(var s=0,v;k=b[s++];){h=f?c.extend({},f):{handler:d,data:e};if(k.indexOf(".")>-1){v=k.split(".");k=v.shift();h.namespace=v.slice(0).sort().join(".")}else{v=[];h.namespace=""}h.type=k;if(!h.guid)h.guid=d.guid;var B=l[k],D=c.event.special[k]||{};if(!B){B=l[k]=[]; -if(!D.setup||D.setup.call(a,e,v,n)===false)if(a.addEventListener)a.addEventListener(k,n,false);else a.attachEvent&&a.attachEvent("on"+k,n)}if(D.add){D.add.call(a,h);if(!h.handler.guid)h.handler.guid=d.guid}B.push(h);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,k=0,l,n,s,v,B,D,H=a.nodeType?"events":"__events__",w=c.data(a),G=w&&w[H];if(w&&G){if(typeof G==="function"){w=G;G=G.events}if(b&&b.type){d=b.handler;b=b.type}if(!b|| -typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in G)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[k++];){v=f;l=f.indexOf(".")<0;n=[];if(!l){n=f.split(".");f=n.shift();s=RegExp("(^|\\.)"+c.map(n.slice(0).sort(),Va).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(B=G[f])if(d){v=c.event.special[f]||{};for(h=e||0;h=0){a.type= -f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return A;a.result=A;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)=== -false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){e=a.target;var k,l=f.replace(X,""),n=c.nodeName(e,"a")&&l==="click",s=c.event.special[l]||{};if((!s._default||s._default.call(d,a)===false)&&!n&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[l]){if(k=e["on"+l])e["on"+l]=null;c.event.triggered=true;e[l]()}}catch(v){}if(k)e["on"+l]=k;c.event.triggered=false}}},handle:function(a){var b,d,e; -d=[];var f,h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var k=d.length;f-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ha.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=va(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===A||f===e))if(e!=null||f){a.type="change";a.liveFired= -A;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",va(a))}},setup:function(){if(this.type=== -"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ha.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ha.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}u.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){sa[b]++===0&&u.addEventListener(a,d,true)},teardown:function(){--sa[b]=== -0&&u.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=A}var k=b==="one"?c.proxy(f,function(n){c(this).unbind(n,k);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var l=this.length;h0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}}); -(function(){function a(g,j,o,m,p,q){p=0;for(var t=m.length;p0){C=x;break}}x=x[g]}m[p]=C}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,k=true;[0,0].sort(function(){k=false;return 0});var l=function(g,j,o,m){o=o||[];var p=j=j||u;if(j.nodeType!==1&&j.nodeType!==9)return[];if(!g||typeof g!=="string")return o;var q=[],t,x,C,P,N=true,R=l.isXML(j),Q=g,L;do{d.exec("");if(t=d.exec(Q)){Q=t[3];q.push(t[1]);if(t[2]){P=t[3]; -break}}}while(t);if(q.length>1&&s.exec(g))if(q.length===2&&n.relative[q[0]])x=M(q[0]+q[1],j);else for(x=n.relative[q[0]]?[j]:l(q.shift(),j);q.length;){g=q.shift();if(n.relative[g])g+=q.shift();x=M(g,x)}else{if(!m&&q.length>1&&j.nodeType===9&&!R&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){t=l.find(q.shift(),j,R);j=t.expr?l.filter(t.expr,t.set)[0]:t.set[0]}if(j){t=m?{expr:q.pop(),set:D(m)}:l.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&j.parentNode?j.parentNode:j,R);x=t.expr?l.filter(t.expr, -t.set):t.set;if(q.length>0)C=D(x);else N=false;for(;q.length;){t=L=q.pop();if(n.relative[L])t=q.pop();else L="";if(t==null)t=j;n.relative[L](C,t,R)}}else C=[]}C||(C=x);C||l.error(L||g);if(f.call(C)==="[object Array]")if(N)if(j&&j.nodeType===1)for(g=0;C[g]!=null;g++){if(C[g]&&(C[g]===true||C[g].nodeType===1&&l.contains(j,C[g])))o.push(x[g])}else for(g=0;C[g]!=null;g++)C[g]&&C[g].nodeType===1&&o.push(x[g]);else o.push.apply(o,C);else D(C,o);if(P){l(P,p,o,m);l.uniqueSort(o)}return o};l.uniqueSort=function(g){if(w){h= -k;g.sort(w);if(h)for(var j=1;j0};l.find=function(g,j,o){var m;if(!g)return[];for(var p=0,q=n.order.length;p":function(g,j){var o=typeof j==="string",m,p=0,q=g.length;if(o&&!/\W/.test(j))for(j=j.toLowerCase();p=0))o||m.push(t);else if(o)j[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var j=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=j[1]+(j[2]||1)-0;g[3]=j[3]-0}g[0]=e++;return g},ATTR:function(g,j,o, -m,p,q){j=g[1].replace(/\\/g,"");if(!q&&n.attrMap[j])g[1]=n.attrMap[j];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,j,o,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=l(g[3],null,null,j);else{g=l.filter(g[3],j,o,true^p);o||m.push.apply(m,g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled=== -true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,j,o){return!!l(o[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"=== -g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,j){return j===0},last:function(g,j,o,m){return j===m.length-1},even:function(g,j){return j%2===0},odd:function(g,j){return j%2===1},lt:function(g,j,o){return jo[3]-0},nth:function(g,j,o){return o[3]- -0===j},eq:function(g,j,o){return o[3]-0===j}},filter:{PSEUDO:function(g,j,o,m){var p=j[1],q=n.filters[p];if(q)return q(g,o,j,m);else if(p==="contains")return(g.textContent||g.innerText||l.getText([g])||"").indexOf(j[3])>=0;else if(p==="not"){j=j[3];o=0;for(m=j.length;o=0}},ID:function(g,j){return g.nodeType===1&&g.getAttribute("id")===j},TAG:function(g,j){return j==="*"&&g.nodeType===1||g.nodeName.toLowerCase()=== -j},CLASS:function(g,j){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(j)>-1},ATTR:function(g,j){var o=j[1];o=n.attrHandle[o]?n.attrHandle[o](g):g[o]!=null?g[o]:g.getAttribute(o);var m=o+"",p=j[2],q=j[4];return o==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&o!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,j,o,m){var p=n.setFilters[j[2]]; -if(p)return p(g,o,j,m)}}},s=n.match.POS,v=function(g,j){return"\\"+(j-0+1)},B;for(B in n.match){n.match[B]=RegExp(n.match[B].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[B]=RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[B].source.replace(/\\(\d+)/g,v))}var D=function(g,j){g=Array.prototype.slice.call(g,0);if(j){j.push.apply(j,g);return j}return g};try{Array.prototype.slice.call(u.documentElement.childNodes,0)}catch(H){D=function(g,j){var o=j||[],m=0;if(f.call(g)==="[object Array]")Array.prototype.push.apply(o, -g);else if(typeof g.length==="number")for(var p=g.length;m";var o=u.documentElement;o.insertBefore(g,o.firstChild);if(u.getElementById(j)){n.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:A:[]};n.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}o.removeChild(g); -o=g=null})();(function(){var g=u.createElement("div");g.appendChild(u.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(j,o){var m=o.getElementsByTagName(j[1]);if(j[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(j){return j.getAttribute("href",2)};g=null})();u.querySelectorAll&& -function(){var g=l,j=u.createElement("div");j.innerHTML="

";if(!(j.querySelectorAll&&j.querySelectorAll(".TEST").length===0)){l=function(m,p,q,t){p=p||u;if(!t&&!l.isXML(p))if(p.nodeType===9)try{return D(p.querySelectorAll(m),q)}catch(x){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var C=p.id,P=p.id="__sizzle__";try{return D(p.querySelectorAll("#"+P+" "+m),q)}catch(N){}finally{if(C)p.id=C;else p.removeAttribute("id")}}return g(m,p,q,t)};for(var o in g)l[o]=g[o]; -j=null}}();(function(){var g=u.documentElement,j=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,o=false;try{j.call(u.documentElement,":sizzle")}catch(m){o=true}if(j)l.matchesSelector=function(p,q){try{if(o||!n.match.PSEUDO.test(q))return j.call(p,q)}catch(t){}return l(q,null,null,[p]).length>0}})();(function(){var g=u.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length=== -0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(j,o,m){if(typeof o.getElementsByClassName!=="undefined"&&!m)return o.getElementsByClassName(j[1])};g=null}}})();l.contains=u.documentElement.contains?function(g,j){return g!==j&&(g.contains?g.contains(j):true)}:function(g,j){return!!(g.compareDocumentPosition(j)&16)};l.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var M=function(g, -j){for(var o=[],m="",p,q=j.nodeType?[j]:j;p=n.match.PSEUDO.exec(g);){m+=p[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;p=0;for(var t=q.length;p0)for(var h=d;h0},closest:function(a, -b){var d=[],e,f,h=this[0];if(c.isArray(a)){var k={},l,n=1;if(h&&a.length){e=0;for(f=a.length;e-1:c(h).is(e))d.push({selector:l,elem:h,level:n})}h=h.parentNode;n++}}return d}k=$a.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h|| -!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}}); -c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling", -d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Wa.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||Ya.test(e))&&Xa.test(a))f=f.reverse();return this.pushStack(f,a,Za.call(arguments).join(","))}}); -c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===A||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var xa=/ jQuery\d+="(?:\d+|null)"/g, -$=/^\s+/,ya=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,za=/<([\w:]+)/,ab=/\s]+\/)>/g,O={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"], -area:[1,"",""],_default:[0,"",""]};O.optgroup=O.option;O.tbody=O.tfoot=O.colgroup=O.caption=O.thead;O.th=O.td;if(!c.support.htmlSerialize)O._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==A)return this.empty().append((this[0]&&this[0].ownerDocument||u).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this, -d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})}, -unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a= -c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*")); -c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(xa,"").replace(cb,'="$1">').replace($, -"")],e)[0]}else return this.cloneNode(true)});if(a===true){la(this,b);la(this.find("*"),b.find("*"))}return b},html:function(a){if(a===A)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(xa,""):null;else if(typeof a==="string"&&!Aa.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!O[(za.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ya,"<$1>");try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?l.cloneNode(true):l)}k.length&&c.each(k,Ka)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:u;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===u&&!Aa.test(a[0])&&(c.support.checkClone|| -!Ba.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h= -d.length;f0?this.clone(true):this).get();c(d[f])[b](k);e=e.concat(k)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||u;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||u;for(var f=[],h=0,k;(k=a[h])!=null;h++){if(typeof k==="number")k+="";if(k){if(typeof k==="string"&&!bb.test(k))k=b.createTextNode(k);else if(typeof k==="string"){k=k.replace(ya,"<$1>");var l=(za.exec(k)||["",""])[1].toLowerCase(),n=O[l]||O._default, -s=n[0],v=b.createElement("div");for(v.innerHTML=n[1]+k+n[2];s--;)v=v.lastChild;if(!c.support.tbody){s=ab.test(k);l=l==="table"&&!s?v.firstChild&&v.firstChild.childNodes:n[1]===""&&!s?v.childNodes:[];for(n=l.length-1;n>=0;--n)c.nodeName(l[n],"tbody")&&!l[n].childNodes.length&&l[n].parentNode.removeChild(l[n])}!c.support.leadingWhitespace&&$.test(k)&&v.insertBefore(b.createTextNode($.exec(k)[0]),v.firstChild);k=v.childNodes}if(k.nodeType)f.push(k);else f=c.merge(f,k)}}if(d)for(h=0;f[h];h++)if(e&& -c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,k=0,l;(l=a[k])!=null;k++)if(!(l.nodeName&&c.noData[l.nodeName.toLowerCase()]))if(d=l[c.expando]){if((b=e[d])&&b.events)for(var n in b.events)f[n]? -c.event.remove(l,n):c.removeEvent(l,n,b.handle);if(h)delete l[c.expando];else l.removeAttribute&&l.removeAttribute(c.expando);delete e[d]}}});var Ca=/alpha\([^)]*\)/i,db=/opacity=([^)]*)/,eb=/-([a-z])/ig,fb=/([A-Z])/g,Da=/^-?\d+(?:px)?$/i,gb=/^-?\d/,hb={position:"absolute",visibility:"hidden",display:"block"},La=["Left","Right"],Ma=["Top","Bottom"],W,ib=u.defaultView&&u.defaultView.getComputedStyle,jb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===A)return this; -return c.access(this,a,b,true,function(d,e,f){return f!==A?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),k=a.style,l=c.cssHooks[h];b=c.cssProps[h]|| -h;if(d!==A){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!l||!("set"in l)||(d=l.set(a,d))!==A)try{k[b]=d}catch(n){}}}else{if(l&&"get"in l&&(f=l.get(a,false,e))!==A)return f;return k[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==A)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]= -e[f]},camelCase:function(a){return a.replace(eb,jb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=ma(d,b,f);else c.swap(d,hb,function(){h=ma(d,b,f)});return h+"px"}},set:function(d,e){if(Da.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return db.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"": -b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=d.filter||"";d.filter=Ca.test(f)?f.replace(Ca,e):d.filter+" "+e}};if(ib)W=function(a,b,d){var e;d=d.replace(fb,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return A;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};else if(u.documentElement.currentStyle)W=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b], -h=a.style;if(!Da.test(f)&&gb.test(f)){d=h.left;e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f};if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var kb=c.now(),lb=/)<[^<]*)*<\/script>/gi, -mb=/^(?:select|textarea)/i,nb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,ob=/^(?:GET|HEAD|DELETE)$/,Na=/\[\]$/,T=/\=\?(&|$)/,ia=/\?/,pb=/([?&])_=[^&]*/,qb=/^(\w+:)?\/\/([^\/?#]+)/,rb=/%20/g,sb=/#.*$/,Ea=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ea)return Ea.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d= -b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(k,l){if(l==="success"||l==="notmodified")h.html(f?c("
").append(k.responseText.replace(lb,"")).find(f):k.responseText);d&&h.each(d,[k.responseText,l,k])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&& -!this.disabled&&(this.checked||mb.test(this.nodeName)||nb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})}, -getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html", -script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),k=ob.test(h);b.url=b.url.replace(sb,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ia.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data|| -!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+kb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var l=E[d];E[d]=function(m){f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);if(c.isFunction(l))l(m);else{E[d]=A;try{delete E[d]}catch(p){}}v&&v.removeChild(B)}}if(b.dataType==="script"&&b.cache===null)b.cache= -false;if(b.cache===false&&h==="GET"){var n=c.now(),s=b.url.replace(pb,"$1_="+n);b.url=s+(s===b.url?(ia.test(b.url)?"&":"?")+"_="+n:"")}if(b.data&&h==="GET")b.url+=(ia.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");n=(n=qb.exec(b.url))&&(n[1]&&n[1]!==location.protocol||n[2]!==location.host);if(b.dataType==="script"&&h==="GET"&&n){var v=u.getElementsByTagName("head")[0]||u.documentElement,B=u.createElement("script");if(b.scriptCharset)B.charset=b.scriptCharset;B.src= -b.url;if(!d){var D=false;B.onload=B.onreadystatechange=function(){if(!D&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){D=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);B.onload=B.onreadystatechange=null;v&&B.parentNode&&v.removeChild(B)}}}v.insertBefore(B,v.firstChild);return A}var H=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!k||a&&a.contentType)w.setRequestHeader("Content-Type", -b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}n||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(G){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&& -c.triggerGlobal(b,"ajaxSend",[w,b]);var M=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){H||c.handleComplete(b,w,e,f);H=true;if(w)w.onreadystatechange=c.noop}else if(!H&&w&&(w.readyState===4||m==="timeout")){H=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d|| -c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&g.call&&g.call(w);M("abort")}}catch(j){}b.async&&b.timeout>0&&setTimeout(function(){w&&!H&&M("timeout")},b.timeout);try{w.send(k||b.data==null?null:b.data)}catch(o){c.handleError(b,w,null,o);c.handleComplete(b,w,e,f)}b.async||M();return w}},param:function(a,b){var d=[],e=function(h,k){k=c.isFunction(k)?k():k;d[d.length]=encodeURIComponent(h)+ -"="+encodeURIComponent(k)};if(b===A)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)ca(f,a[f],b,e);return d.join("&").replace(rb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",[b,a])},handleComplete:function(a, -b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),e=a.getResponseHeader("Etag"); -if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});if(E.ActiveXObject)c.ajaxSettings.xhr= -function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var da={},tb=/^(?:toggle|show|hide)$/,ub=/^([+\-]=)?([\d+.\-]+)(.*)$/,aa,na=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",3),a,b,d);else{a= -0;for(b=this.length;a=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b, -d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a* -Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(h){return f.step(h)} -this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var f=this;a=c.fx;e.elem=this.elem;if(e()&&c.timers.push(e)&&!aa)aa=setInterval(a.tick,a.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true; -this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(l,n){f.style["overflow"+n]=h.overflow[l]})}this.options.hide&&c(this.elem).hide();if(this.options.hide|| -this.options.show)for(var k in this.options.curAnim)c.style(this.elem,k,this.options.orig[k]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a= -c.timers,b=0;b-1;e={};var s={};if(n)s=f.position();k=n?s.top:parseInt(k,10)||0;l=n?s.left:parseInt(l,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+k;if(b.left!=null)e.left=b.left-h.left+l;"using"in b?b.using.call(a, -e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Fa.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||u.body;a&&!Fa.test(a.nodeName)&& -c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==A)return this.each(function(){if(h=ea(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=ea(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase(); -c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(h){var k=c(this);k[d](e.call(this,h,k[d]()))});return c.isWindow(f)?f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b]:f.nodeType===9?Math.max(f.documentElement["client"+ -b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]):e===A?parseFloat(c.css(f,d)):this.css(d,typeof e==="string"?e:e+"px")}})})(window); diff --git a/htmlcov/jquery.hotkeys.js b/htmlcov/jquery.hotkeys.js deleted file mode 100644 index 09b21e03c..000000000 --- a/htmlcov/jquery.hotkeys.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * jQuery Hotkeys Plugin - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * - * Based upon the plugin by Tzury Bar Yochay: - * http://github.com/tzuryby/hotkeys - * - * Original idea by: - * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ -*/ - -(function(jQuery){ - - jQuery.hotkeys = { - version: "0.8", - - specialKeys: { - 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", - 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", - 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", - 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", - 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", - 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", - 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta" - }, - - shiftNums: { - "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", - "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", - ".": ">", "/": "?", "\\": "|" - } - }; - - function keyHandler( handleObj ) { - // Only care when a possible input has been specified - if ( typeof handleObj.data !== "string" ) { - return; - } - - var origHandler = handleObj.handler, - keys = handleObj.data.toLowerCase().split(" "); - - handleObj.handler = function( event ) { - // Don't fire in text-accepting inputs that we didn't directly bind to - if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) || - event.target.type === "text") ) { - return; - } - - // Keypress represents characters, not special keys - var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ], - character = String.fromCharCode( event.which ).toLowerCase(), - key, modif = "", possible = {}; - - // check combinations (alt|ctrl|shift+anything) - if ( event.altKey && special !== "alt" ) { - modif += "alt+"; - } - - if ( event.ctrlKey && special !== "ctrl" ) { - modif += "ctrl+"; - } - - // TODO: Need to make sure this works consistently across platforms - if ( event.metaKey && !event.ctrlKey && special !== "meta" ) { - modif += "meta+"; - } - - if ( event.shiftKey && special !== "shift" ) { - modif += "shift+"; - } - - if ( special ) { - possible[ modif + special ] = true; - - } else { - possible[ modif + character ] = true; - possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true; - - // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" - if ( modif === "shift+" ) { - possible[ jQuery.hotkeys.shiftNums[ character ] ] = true; - } - } - - for ( var i = 0, l = keys.length; i < l; i++ ) { - if ( possible[ keys[i] ] ) { - return origHandler.apply( this, arguments ); - } - } - }; - } - - jQuery.each([ "keydown", "keyup", "keypress" ], function() { - jQuery.event.special[ this ] = { add: keyHandler }; - }); - -})( jQuery ); diff --git a/htmlcov/jquery.isonscreen.js b/htmlcov/jquery.isonscreen.js deleted file mode 100644 index 0182ebd21..000000000 --- a/htmlcov/jquery.isonscreen.js +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2010 - * @author Laurence Wheway - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * @version 1.2.0 - */ -(function($) { - jQuery.extend({ - isOnScreen: function(box, container) { - //ensure numbers come in as intgers (not strings) and remove 'px' is it's there - for(var i in box){box[i] = parseFloat(box[i])}; - for(var i in container){container[i] = parseFloat(container[i])}; - - if(!container){ - container = { - left: $(window).scrollLeft(), - top: $(window).scrollTop(), - width: $(window).width(), - height: $(window).height() - } - } - - if( box.left+box.width-container.left > 0 && - box.left < container.width+container.left && - box.top+box.height-container.top > 0 && - box.top < container.height+container.top - ) return true; - return false; - } - }) - - - jQuery.fn.isOnScreen = function (container) { - for(var i in container){container[i] = parseFloat(container[i])}; - - if(!container){ - container = { - left: $(window).scrollLeft(), - top: $(window).scrollTop(), - width: $(window).width(), - height: $(window).height() - } - } - - if( $(this).offset().left+$(this).width()-container.left > 0 && - $(this).offset().left < container.width+container.left && - $(this).offset().top+$(this).height()-container.top > 0 && - $(this).offset().top < container.height+container.top - ) return true; - return false; - } -})(jQuery); diff --git a/htmlcov/jquery.tablesorter.min.js b/htmlcov/jquery.tablesorter.min.js deleted file mode 100644 index 64c700712..000000000 --- a/htmlcov/jquery.tablesorter.min.js +++ /dev/null @@ -1,2 +0,0 @@ - -(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('
').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;ib)?1:0));};function sortTextDesc(a,b){return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i - - - - - - - Coverage for rest_framework/__init__: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
-
- - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

- -
-

__version__ = '2.3.5' 

-

 

-

VERSION = __version__  # synonym 

-

 

-

# Header encoding (see RFC5987) 

-

HTTP_HEADER_ENCODING = 'iso-8859-1' 

-

 

-

# Default datetime input and output formats 

-

ISO_8601 = 'iso-8601' 

- -
- - - - - - diff --git a/htmlcov/rest_framework_authentication.html b/htmlcov/rest_framework_authentication.html deleted file mode 100644 index 899d06777..000000000 --- a/htmlcov/rest_framework_authentication.html +++ /dev/null @@ -1,767 +0,0 @@ - - - - - - - - Coverage for rest_framework/authentication: 80% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

- -
-

""" 

-

Provides various authentication policies. 

-

""" 

-

from __future__ import unicode_literals 

-

import base64 

-

from datetime import datetime 

-

 

-

from django.contrib.auth import authenticate 

-

from django.core.exceptions import ImproperlyConfigured 

-

from rest_framework import exceptions, HTTP_HEADER_ENCODING 

-

from rest_framework.compat import CsrfViewMiddleware 

-

from rest_framework.compat import oauth, oauth_provider, oauth_provider_store 

-

from rest_framework.compat import oauth2_provider 

-

from rest_framework.authtoken.models import Token 

-

 

-

 

-

def get_authorization_header(request): 

-

    """ 

-

    Return request's 'Authorization:' header, as a bytestring. 

-

 

-

    Hide some test client ickyness where the header can be unicode. 

-

    """ 

-

    auth = request.META.get('HTTP_AUTHORIZATION', b'') 

-

    if type(auth) == type(''): 

-

        # Work around django test client oddness 

-

        auth = auth.encode(HTTP_HEADER_ENCODING) 

-

    return auth 

-

 

-

 

-

class BaseAuthentication(object): 

-

    """ 

-

    All authentication classes should extend BaseAuthentication. 

-

    """ 

-

 

-

    def authenticate(self, request): 

-

        """ 

-

        Authenticate the request and return a two-tuple of (user, token). 

-

        """ 

-

        raise NotImplementedError(".authenticate() must be overridden.") 

-

 

-

    def authenticate_header(self, request): 

-

        """ 

-

        Return a string to be used as the value of the `WWW-Authenticate` 

-

        header in a `401 Unauthenticated` response, or `None` if the 

-

        authentication scheme should return `403 Permission Denied` responses. 

-

        """ 

-

        pass 

-

 

-

 

-

class BasicAuthentication(BaseAuthentication): 

-

    """ 

-

    HTTP Basic authentication against username/password. 

-

    """ 

-

    www_authenticate_realm = 'api' 

-

 

-

    def authenticate(self, request): 

-

        """ 

-

        Returns a `User` if a correct username and password have been supplied 

-

        using HTTP Basic authentication.  Otherwise returns `None`. 

-

        """ 

-

        auth = get_authorization_header(request).split() 

-

 

-

        if not auth or auth[0].lower() != b'basic': 

-

            return None 

-

 

-

        if len(auth) == 1: 

-

            msg = 'Invalid basic header. No credentials provided.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

        elif len(auth) > 2: 

-

            msg = 'Invalid basic header. Credentials string should not contain spaces.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        try: 

-

            auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':') 

-

        except (TypeError, UnicodeDecodeError): 

-

            msg = 'Invalid basic header. Credentials not correctly base64 encoded' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        userid, password = auth_parts[0], auth_parts[2] 

-

        return self.authenticate_credentials(userid, password) 

-

 

-

    def authenticate_credentials(self, userid, password): 

-

        """ 

-

        Authenticate the userid and password against username and password. 

-

        """ 

-

        user = authenticate(username=userid, password=password) 

-

        if user is None or not user.is_active: 

-

            raise exceptions.AuthenticationFailed('Invalid username/password') 

-

        return (user, None) 

-

 

-

    def authenticate_header(self, request): 

-

        return 'Basic realm="%s"' % self.www_authenticate_realm 

-

 

-

 

-

class SessionAuthentication(BaseAuthentication): 

-

    """ 

-

    Use Django's session framework for authentication. 

-

    """ 

-

 

-

    def authenticate(self, request): 

-

        """ 

-

        Returns a `User` if the request session currently has a logged in user. 

-

        Otherwise returns `None`. 

-

        """ 

-

 

-

        # Get the underlying HttpRequest object 

-

        http_request = request._request 

-

        user = getattr(http_request, 'user', None) 

-

 

-

        # Unauthenticated, CSRF validation not required 

-

        if not user or not user.is_active: 

-

            return None 

-

 

-

        # Enforce CSRF validation for session based authentication. 

-

        class CSRFCheck(CsrfViewMiddleware): 

-

            def _reject(self, request, reason): 

-

                # Return the failure reason instead of an HttpResponse 

-

                return reason 

-

 

-

        reason = CSRFCheck().process_view(http_request, None, (), {}) 

-

        if reason: 

-

            # CSRF failed, bail with explicit error message 

-

            raise exceptions.AuthenticationFailed('CSRF Failed: %s' % reason) 

-

 

-

        # CSRF passed with authenticated user 

-

        return (user, None) 

-

 

-

 

-

class TokenAuthentication(BaseAuthentication): 

-

    """ 

-

    Simple token based authentication. 

-

 

-

    Clients should authenticate by passing the token key in the "Authorization" 

-

    HTTP header, prepended with the string "Token ".  For example: 

-

 

-

        Authorization: Token 401f7ac837da42b97f613d789819ff93537bee6a 

-

    """ 

-

 

-

    model = Token 

-

    """ 

-

    A custom token model may be used, but must have the following properties. 

-

 

-

    * key -- The string identifying the token 

-

    * user -- The user to which the token belongs 

-

    """ 

-

 

-

    def authenticate(self, request): 

-

        auth = get_authorization_header(request).split() 

-

 

-

        if not auth or auth[0].lower() != b'token': 

-

            return None 

-

 

-

        if len(auth) == 1: 

-

            msg = 'Invalid token header. No credentials provided.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

        elif len(auth) > 2: 

-

            msg = 'Invalid token header. Token string should not contain spaces.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        return self.authenticate_credentials(auth[1]) 

-

 

-

    def authenticate_credentials(self, key): 

-

        try: 

-

            token = self.model.objects.get(key=key) 

-

        except self.model.DoesNotExist: 

-

            raise exceptions.AuthenticationFailed('Invalid token') 

-

 

-

        if not token.user.is_active: 

-

            raise exceptions.AuthenticationFailed('User inactive or deleted') 

-

 

-

        return (token.user, token) 

-

 

-

    def authenticate_header(self, request): 

-

        return 'Token' 

-

 

-

 

-

class OAuthAuthentication(BaseAuthentication): 

-

    """ 

-

    OAuth 1.0a authentication backend using `django-oauth-plus` and `oauth2`. 

-

 

-

    Note: The `oauth2` package actually provides oauth1.0a support.  Urg. 

-

          We import it from the `compat` module as `oauth`. 

-

    """ 

-

    www_authenticate_realm = 'api' 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        super(OAuthAuthentication, self).__init__(*args, **kwargs) 

-

 

-

        if oauth is None: 

-

            raise ImproperlyConfigured( 

-

                "The 'oauth2' package could not be imported." 

-

                "It is required for use with the 'OAuthAuthentication' class.") 

-

 

-

        if oauth_provider is None: 

-

            raise ImproperlyConfigured( 

-

                "The 'django-oauth-plus' package could not be imported." 

-

                "It is required for use with the 'OAuthAuthentication' class.") 

-

 

-

    def authenticate(self, request): 

-

        """ 

-

        Returns two-tuple of (user, token) if authentication succeeds, 

-

        or None otherwise. 

-

        """ 

-

        try: 

-

            oauth_request = oauth_provider.utils.get_oauth_request(request) 

-

        except oauth.Error as err: 

-

            raise exceptions.AuthenticationFailed(err.message) 

-

 

-

        if not oauth_request: 

-

            return None 

-

 

-

        oauth_params = oauth_provider.consts.OAUTH_PARAMETERS_NAMES 

-

 

-

        found = any(param for param in oauth_params if param in oauth_request) 

-

        missing = list(param for param in oauth_params if param not in oauth_request) 

-

 

-

        if not found: 

-

            # OAuth authentication was not attempted. 

-

            return None 

-

 

-

        if missing: 

-

            # OAuth was attempted but missing parameters. 

-

            msg = 'Missing parameters: %s' % (', '.join(missing)) 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        if not self.check_nonce(request, oauth_request): 

-

            msg = 'Nonce check failed' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        try: 

-

            consumer_key = oauth_request.get_parameter('oauth_consumer_key') 

-

            consumer = oauth_provider_store.get_consumer(request, oauth_request, consumer_key) 

-

        except oauth_provider.store.InvalidConsumerError: 

-

            msg = 'Invalid consumer token: %s' % oauth_request.get_parameter('oauth_consumer_key') 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        if consumer.status != oauth_provider.consts.ACCEPTED: 

-

            msg = 'Invalid consumer key status: %s' % consumer.get_status_display() 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        try: 

-

            token_param = oauth_request.get_parameter('oauth_token') 

-

            token = oauth_provider_store.get_access_token(request, oauth_request, consumer, token_param) 

-

        except oauth_provider.store.InvalidTokenError: 

-

            msg = 'Invalid access token: %s' % oauth_request.get_parameter('oauth_token') 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        try: 

-

            self.validate_token(request, consumer, token) 

-

        except oauth.Error as err: 

-

            raise exceptions.AuthenticationFailed(err.message) 

-

 

-

        user = token.user 

-

 

-

        if not user.is_active: 

-

            msg = 'User inactive or deleted: %s' % user.username 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        return (token.user, token) 

-

 

-

    def authenticate_header(self, request): 

-

        """ 

-

        If permission is denied, return a '401 Unauthorized' response, 

-

        with an appropraite 'WWW-Authenticate' header. 

-

        """ 

-

        return 'OAuth realm="%s"' % self.www_authenticate_realm 

-

 

-

    def validate_token(self, request, consumer, token): 

-

        """ 

-

        Check the token and raise an `oauth.Error` exception if invalid. 

-

        """ 

-

        oauth_server, oauth_request = oauth_provider.utils.initialize_server_request(request) 

-

        oauth_server.verify_request(oauth_request, consumer, token) 

-

 

-

    def check_nonce(self, request, oauth_request): 

-

        """ 

-

        Checks nonce of request, and return True if valid. 

-

        """ 

-

        return oauth_provider_store.check_nonce(request, oauth_request, oauth_request['oauth_nonce']) 

-

 

-

 

-

class OAuth2Authentication(BaseAuthentication): 

-

    """ 

-

    OAuth 2 authentication backend using `django-oauth2-provider` 

-

    """ 

-

    www_authenticate_realm = 'api' 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        super(OAuth2Authentication, self).__init__(*args, **kwargs) 

-

 

-

        if oauth2_provider is None: 

-

            raise ImproperlyConfigured( 

-

                "The 'django-oauth2-provider' package could not be imported. " 

-

                "It is required for use with the 'OAuth2Authentication' class.") 

-

 

-

    def authenticate(self, request): 

-

        """ 

-

        Returns two-tuple of (user, token) if authentication succeeds, 

-

        or None otherwise. 

-

        """ 

-

 

-

        auth = get_authorization_header(request).split() 

-

 

-

        if not auth or auth[0].lower() != b'bearer': 

-

            return None 

-

 

-

        if len(auth) == 1: 

-

            msg = 'Invalid bearer header. No credentials provided.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

        elif len(auth) > 2: 

-

            msg = 'Invalid bearer header. Token string should not contain spaces.' 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        return self.authenticate_credentials(request, auth[1]) 

-

 

-

    def authenticate_credentials(self, request, access_token): 

-

        """ 

-

        Authenticate the request, given the access token. 

-

        """ 

-

 

-

        try: 

-

            token = oauth2_provider.models.AccessToken.objects.select_related('user') 

-

            # TODO: Change to timezone aware datetime when oauth2_provider add 

-

            # support to it. 

-

            token = token.get(token=access_token, expires__gt=datetime.now()) 

-

        except oauth2_provider.models.AccessToken.DoesNotExist: 

-

            raise exceptions.AuthenticationFailed('Invalid token') 

-

 

-

        user = token.user 

-

 

-

        if not user.is_active: 

-

            msg = 'User inactive or deleted: %s' % user.username 

-

            raise exceptions.AuthenticationFailed(msg) 

-

 

-

        return (user, token) 

-

 

-

    def authenticate_header(self, request): 

-

        """ 

-

        Bearer is the only finalized type currently 

-

 

-

        Check details on the `OAuth2Authentication.authenticate` method 

-

        """ 

-

        return 'Bearer realm="%s"' % self.www_authenticate_realm 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_authtoken___init__.html b/htmlcov/rest_framework_authtoken___init__.html deleted file mode 100644 index f72574937..000000000 --- a/htmlcov/rest_framework_authtoken___init__.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - Coverage for rest_framework/authtoken/__init__: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
- - - -
-
- - - - - diff --git a/htmlcov/rest_framework_authtoken_models.html b/htmlcov/rest_framework_authtoken_models.html deleted file mode 100644 index 27d2fff1d..000000000 --- a/htmlcov/rest_framework_authtoken_models.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - Coverage for rest_framework/authtoken/models: 95% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

- -
-

import uuid 

-

import hmac 

-

from hashlib import sha1 

-

from rest_framework.compat import User 

-

from django.conf import settings 

-

from django.db import models 

-

 

-

 

-

class Token(models.Model): 

-

    """ 

-

    The default authorization token model. 

-

    """ 

-

    key = models.CharField(max_length=40, primary_key=True) 

-

    user = models.OneToOneField(User, related_name='auth_token') 

-

    created = models.DateTimeField(auto_now_add=True) 

-

 

-

    class Meta: 

-

        # Work around for a bug in Django: 

-

        # https://code.djangoproject.com/ticket/19422 

-

        # 

-

        # Also see corresponding ticket: 

-

        # https://github.com/tomchristie/django-rest-framework/issues/705 

-

        abstract = 'rest_framework.authtoken' not in settings.INSTALLED_APPS 

-

 

-

    def save(self, *args, **kwargs): 

-

        if not self.key: 

-

            self.key = self.generate_key() 

-

        return super(Token, self).save(*args, **kwargs) 

-

 

-

    def generate_key(self): 

-

        unique = uuid.uuid4() 

-

        return hmac.new(unique.bytes, digestmod=sha1).hexdigest() 

-

 

-

    def __unicode__(self): 

-

        return self.key 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_authtoken_serializers.html b/htmlcov/rest_framework_authtoken_serializers.html deleted file mode 100644 index 8997d9a7b..000000000 --- a/htmlcov/rest_framework_authtoken_serializers.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - Coverage for rest_framework/authtoken/serializers: 88% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

- -
-

from django.contrib.auth import authenticate 

-

from rest_framework import serializers 

-

 

-

 

-

class AuthTokenSerializer(serializers.Serializer): 

-

    username = serializers.CharField() 

-

    password = serializers.CharField() 

-

 

-

    def validate(self, attrs): 

-

        username = attrs.get('username') 

-

        password = attrs.get('password') 

-

 

-

        if username and password: 

-

            user = authenticate(username=username, password=password) 

-

 

-

            if user: 

-

                if not user.is_active: 

-

                    raise serializers.ValidationError('User account is disabled.') 

-

                attrs['user'] = user 

-

                return attrs 

-

            else: 

-

                raise serializers.ValidationError('Unable to login with provided credentials.') 

-

        else: 

-

            raise serializers.ValidationError('Must include "username" and "password"') 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_authtoken_views.html b/htmlcov/rest_framework_authtoken_views.html deleted file mode 100644 index d13746ea8..000000000 --- a/htmlcov/rest_framework_authtoken_views.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - Coverage for rest_framework/authtoken/views: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

- -
-

from rest_framework.views import APIView 

-

from rest_framework import status 

-

from rest_framework import parsers 

-

from rest_framework import renderers 

-

from rest_framework.response import Response 

-

from rest_framework.authtoken.models import Token 

-

from rest_framework.authtoken.serializers import AuthTokenSerializer 

-

 

-

 

-

class ObtainAuthToken(APIView): 

-

    throttle_classes = () 

-

    permission_classes = () 

-

    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) 

-

    renderer_classes = (renderers.JSONRenderer,) 

-

    serializer_class = AuthTokenSerializer 

-

    model = Token 

-

 

-

    def post(self, request): 

-

        serializer = self.serializer_class(data=request.DATA) 

-

        if serializer.is_valid(): 

-

            token, created = Token.objects.get_or_create(user=serializer.object['user']) 

-

            return Response({'token': token.key}) 

-

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

-

 

-

 

-

obtain_auth_token = ObtainAuthToken.as_view() 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_decorators.html b/htmlcov/rest_framework_decorators.html deleted file mode 100644 index 6ad6f6b51..000000000 --- a/htmlcov/rest_framework_decorators.html +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - Coverage for rest_framework/decorators: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

- -
-

""" 

-

The most important decorator in this module is `@api_view`, which is used 

-

for writing function-based views with REST framework. 

-

 

-

There are also various decorators for setting the API policies on function 

-

based views, as well as the `@action` and `@link` decorators, which are 

-

used to annotate methods on viewsets that should be included by routers. 

-

""" 

-

from __future__ import unicode_literals 

-

from rest_framework.compat import six 

-

from rest_framework.views import APIView 

-

import types 

-

 

-

 

-

def api_view(http_method_names): 

-

 

-

    """ 

-

    Decorator that converts a function-based view into an APIView subclass. 

-

    Takes a list of allowed methods for the view as an argument. 

-

    """ 

-

 

-

    def decorator(func): 

-

 

-

        WrappedAPIView = type( 

-

            six.PY3 and 'WrappedAPIView' or b'WrappedAPIView', 

-

            (APIView,), 

-

            {'__doc__': func.__doc__} 

-

        ) 

-

 

-

        # Note, the above allows us to set the docstring. 

-

        # It is the equivalent of: 

-

        # 

-

        #     class WrappedAPIView(APIView): 

-

        #         pass 

-

        #     WrappedAPIView.__doc__ = func.doc    <--- Not possible to do this 

-

 

-

        # api_view applied without (method_names) 

-

        assert not(isinstance(http_method_names, types.FunctionType)), \ 

-

            '@api_view missing list of allowed HTTP methods' 

-

 

-

        # api_view applied with eg. string instead of list of strings 

-

        assert isinstance(http_method_names, (list, tuple)), \ 

-

            '@api_view expected a list of strings, received %s' % type(http_method_names).__name__ 

-

 

-

        allowed_methods = set(http_method_names) | set(('options',)) 

-

        WrappedAPIView.http_method_names = [method.lower() for method in allowed_methods] 

-

 

-

        def handler(self, *args, **kwargs): 

-

            return func(*args, **kwargs) 

-

 

-

        for method in http_method_names: 

-

            setattr(WrappedAPIView, method.lower(), handler) 

-

 

-

        WrappedAPIView.__name__ = func.__name__ 

-

 

-

        WrappedAPIView.renderer_classes = getattr(func, 'renderer_classes', 

-

                                                  APIView.renderer_classes) 

-

 

-

        WrappedAPIView.parser_classes = getattr(func, 'parser_classes', 

-

                                                APIView.parser_classes) 

-

 

-

        WrappedAPIView.authentication_classes = getattr(func, 'authentication_classes', 

-

                                                        APIView.authentication_classes) 

-

 

-

        WrappedAPIView.throttle_classes = getattr(func, 'throttle_classes', 

-

                                                  APIView.throttle_classes) 

-

 

-

        WrappedAPIView.permission_classes = getattr(func, 'permission_classes', 

-

                                                    APIView.permission_classes) 

-

 

-

        return WrappedAPIView.as_view() 

-

    return decorator 

-

 

-

 

-

def renderer_classes(renderer_classes): 

-

    def decorator(func): 

-

        func.renderer_classes = renderer_classes 

-

        return func 

-

    return decorator 

-

 

-

 

-

def parser_classes(parser_classes): 

-

    def decorator(func): 

-

        func.parser_classes = parser_classes 

-

        return func 

-

    return decorator 

-

 

-

 

-

def authentication_classes(authentication_classes): 

-

    def decorator(func): 

-

        func.authentication_classes = authentication_classes 

-

        return func 

-

    return decorator 

-

 

-

 

-

def throttle_classes(throttle_classes): 

-

    def decorator(func): 

-

        func.throttle_classes = throttle_classes 

-

        return func 

-

    return decorator 

-

 

-

 

-

def permission_classes(permission_classes): 

-

    def decorator(func): 

-

        func.permission_classes = permission_classes 

-

        return func 

-

    return decorator 

-

 

-

 

-

def link(**kwargs): 

-

    """ 

-

    Used to mark a method on a ViewSet that should be routed for GET requests. 

-

    """ 

-

    def decorator(func): 

-

        func.bind_to_methods = ['get'] 

-

        func.kwargs = kwargs 

-

        return func 

-

    return decorator 

-

 

-

 

-

def action(methods=['post'], **kwargs): 

-

    """ 

-

    Used to mark a method on a ViewSet that should be routed for POST requests. 

-

    """ 

-

    def decorator(func): 

-

        func.bind_to_methods = methods 

-

        func.kwargs = kwargs 

-

        return func 

-

    return decorator 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_exceptions.html b/htmlcov/rest_framework_exceptions.html deleted file mode 100644 index d975a8481..000000000 --- a/htmlcov/rest_framework_exceptions.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - - - - Coverage for rest_framework/exceptions: 96% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

- -
-

""" 

-

Handled exceptions raised by REST framework. 

-

 

-

In addition Django's built in 403 and 404 exceptions are handled. 

-

(`django.http.Http404` and `django.core.exceptions.PermissionDenied`) 

-

""" 

-

from __future__ import unicode_literals 

-

from rest_framework import status 

-

 

-

 

-

class APIException(Exception): 

-

    """ 

-

    Base class for REST framework exceptions. 

-

    Subclasses should provide `.status_code` and `.detail` properties. 

-

    """ 

-

    pass 

-

 

-

 

-

class ParseError(APIException): 

-

    status_code = status.HTTP_400_BAD_REQUEST 

-

    default_detail = 'Malformed request.' 

-

 

-

    def __init__(self, detail=None): 

-

        self.detail = detail or self.default_detail 

-

 

-

 

-

class AuthenticationFailed(APIException): 

-

    status_code = status.HTTP_401_UNAUTHORIZED 

-

    default_detail = 'Incorrect authentication credentials.' 

-

 

-

    def __init__(self, detail=None): 

-

        self.detail = detail or self.default_detail 

-

 

-

 

-

class NotAuthenticated(APIException): 

-

    status_code = status.HTTP_401_UNAUTHORIZED 

-

    default_detail = 'Authentication credentials were not provided.' 

-

 

-

    def __init__(self, detail=None): 

-

        self.detail = detail or self.default_detail 

-

 

-

 

-

class PermissionDenied(APIException): 

-

    status_code = status.HTTP_403_FORBIDDEN 

-

    default_detail = 'You do not have permission to perform this action.' 

-

 

-

    def __init__(self, detail=None): 

-

        self.detail = detail or self.default_detail 

-

 

-

 

-

class MethodNotAllowed(APIException): 

-

    status_code = status.HTTP_405_METHOD_NOT_ALLOWED 

-

    default_detail = "Method '%s' not allowed." 

-

 

-

    def __init__(self, method, detail=None): 

-

        self.detail = (detail or self.default_detail) % method 

-

 

-

 

-

class NotAcceptable(APIException): 

-

    status_code = status.HTTP_406_NOT_ACCEPTABLE 

-

    default_detail = "Could not satisfy the request's Accept header" 

-

 

-

    def __init__(self, detail=None, available_renderers=None): 

-

        self.detail = detail or self.default_detail 

-

        self.available_renderers = available_renderers 

-

 

-

 

-

class UnsupportedMediaType(APIException): 

-

    status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE 

-

    default_detail = "Unsupported media type '%s' in request." 

-

 

-

    def __init__(self, media_type, detail=None): 

-

        self.detail = (detail or self.default_detail) % media_type 

-

 

-

 

-

class Throttled(APIException): 

-

    status_code = status.HTTP_429_TOO_MANY_REQUESTS 

-

    default_detail = "Request was throttled." 

-

    extra_detail = "Expected available in %d second%s." 

-

 

-

    def __init__(self, wait=None, detail=None): 

-

        import math 

-

        self.wait = wait and math.ceil(wait) or None 

-

        if wait is not None: 

-

            format = detail or self.default_detail + self.extra_detail 

-

            self.detail = format % (self.wait, self.wait != 1 and 's' or '') 

-

        else: 

-

            self.detail = detail or self.default_detail 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_fields.html b/htmlcov/rest_framework_fields.html deleted file mode 100644 index cf2731d25..000000000 --- a/htmlcov/rest_framework_fields.html +++ /dev/null @@ -1,1991 +0,0 @@ - - - - - - - - Coverage for rest_framework/fields: 87% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

-

370

-

371

-

372

-

373

-

374

-

375

-

376

-

377

-

378

-

379

-

380

-

381

-

382

-

383

-

384

-

385

-

386

-

387

-

388

-

389

-

390

-

391

-

392

-

393

-

394

-

395

-

396

-

397

-

398

-

399

-

400

-

401

-

402

-

403

-

404

-

405

-

406

-

407

-

408

-

409

-

410

-

411

-

412

-

413

-

414

-

415

-

416

-

417

-

418

-

419

-

420

-

421

-

422

-

423

-

424

-

425

-

426

-

427

-

428

-

429

-

430

-

431

-

432

-

433

-

434

-

435

-

436

-

437

-

438

-

439

-

440

-

441

-

442

-

443

-

444

-

445

-

446

-

447

-

448

-

449

-

450

-

451

-

452

-

453

-

454

-

455

-

456

-

457

-

458

-

459

-

460

-

461

-

462

-

463

-

464

-

465

-

466

-

467

-

468

-

469

-

470

-

471

-

472

-

473

-

474

-

475

-

476

-

477

-

478

-

479

-

480

-

481

-

482

-

483

-

484

-

485

-

486

-

487

-

488

-

489

-

490

-

491

-

492

-

493

-

494

-

495

-

496

-

497

-

498

-

499

-

500

-

501

-

502

-

503

-

504

-

505

-

506

-

507

-

508

-

509

-

510

-

511

-

512

-

513

-

514

-

515

-

516

-

517

-

518

-

519

-

520

-

521

-

522

-

523

-

524

-

525

-

526

-

527

-

528

-

529

-

530

-

531

-

532

-

533

-

534

-

535

-

536

-

537

-

538

-

539

-

540

-

541

-

542

-

543

-

544

-

545

-

546

-

547

-

548

-

549

-

550

-

551

-

552

-

553

-

554

-

555

-

556

-

557

-

558

-

559

-

560

-

561

-

562

-

563

-

564

-

565

-

566

-

567

-

568

-

569

-

570

-

571

-

572

-

573

-

574

-

575

-

576

-

577

-

578

-

579

-

580

-

581

-

582

-

583

-

584

-

585

-

586

-

587

-

588

-

589

-

590

-

591

-

592

-

593

-

594

-

595

-

596

-

597

-

598

-

599

-

600

-

601

-

602

-

603

-

604

-

605

-

606

-

607

-

608

-

609

-

610

-

611

-

612

-

613

-

614

-

615

-

616

-

617

-

618

-

619

-

620

-

621

-

622

-

623

-

624

-

625

-

626

-

627

-

628

-

629

-

630

-

631

-

632

-

633

-

634

-

635

-

636

-

637

-

638

-

639

-

640

-

641

-

642

-

643

-

644

-

645

-

646

-

647

-

648

-

649

-

650

-

651

-

652

-

653

-

654

-

655

-

656

-

657

-

658

-

659

-

660

-

661

-

662

-

663

-

664

-

665

-

666

-

667

-

668

-

669

-

670

-

671

-

672

-

673

-

674

-

675

-

676

-

677

-

678

-

679

-

680

-

681

-

682

-

683

-

684

-

685

-

686

-

687

-

688

-

689

-

690

-

691

-

692

-

693

-

694

-

695

-

696

-

697

-

698

-

699

-

700

-

701

-

702

-

703

-

704

-

705

-

706

-

707

-

708

-

709

-

710

-

711

-

712

-

713

-

714

-

715

-

716

-

717

-

718

-

719

-

720

-

721

-

722

-

723

-

724

-

725

-

726

-

727

-

728

-

729

-

730

-

731

-

732

-

733

-

734

-

735

-

736

-

737

-

738

-

739

-

740

-

741

-

742

-

743

-

744

-

745

-

746

-

747

-

748

-

749

-

750

-

751

-

752

-

753

-

754

-

755

-

756

-

757

-

758

-

759

-

760

-

761

-

762

-

763

-

764

-

765

-

766

-

767

-

768

-

769

-

770

-

771

-

772

-

773

-

774

-

775

-

776

-

777

-

778

-

779

-

780

-

781

-

782

-

783

-

784

-

785

-

786

-

787

-

788

-

789

-

790

-

791

-

792

-

793

-

794

-

795

-

796

-

797

-

798

-

799

-

800

-

801

-

802

-

803

-

804

-

805

-

806

-

807

-

808

-

809

-

810

-

811

-

812

-

813

-

814

-

815

-

816

-

817

-

818

-

819

-

820

-

821

-

822

-

823

-

824

-

825

-

826

-

827

-

828

-

829

-

830

-

831

-

832

-

833

-

834

-

835

-

836

-

837

-

838

-

839

-

840

-

841

-

842

-

843

-

844

-

845

-

846

-

847

-

848

-

849

-

850

-

851

-

852

-

853

-

854

-

855

-

856

-

857

-

858

-

859

-

860

-

861

-

862

-

863

-

864

-

865

-

866

-

867

-

868

-

869

-

870

-

871

-

872

-

873

-

874

-

875

-

876

-

877

-

878

-

879

-

880

-

881

-

882

-

883

-

884

-

885

-

886

-

887

-

888

-

889

-

890

-

891

-

892

-

893

-

894

-

895

-

896

-

897

-

898

-

899

-

900

-

901

-

902

-

903

-

904

-

905

-

906

-

907

-

908

-

909

-

910

-

911

-

912

-

913

-

914

-

915

-

916

-

917

-

918

-

919

-

920

-

921

-

922

-

923

-

924

-

925

-

926

-

927

-

928

-

929

-

930

-

931

-

932

-

933

-

934

-

935

-

936

-

937

-

938

-

939

-

940

-

941

-

942

-

943

-

944

-

945

-

946

-

947

-

948

-

949

-

950

-

951

-

952

-

953

-

954

-

955

- -
-

""" 

-

Serializer fields perform validation on incoming data. 

-

 

-

They are very similar to Django's form fields. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

import copy 

-

import datetime 

-

import inspect 

-

import re 

-

import warnings 

-

from decimal import Decimal, DecimalException 

-

from django import forms 

-

from django.core import validators 

-

from django.core.exceptions import ValidationError 

-

from django.conf import settings 

-

from django.db.models.fields import BLANK_CHOICE_DASH 

-

from django.forms import widgets 

-

from django.utils.encoding import is_protected_type 

-

from django.utils.translation import ugettext_lazy as _ 

-

from django.utils.datastructures import SortedDict 

-

from rest_framework import ISO_8601 

-

from rest_framework.compat import ( 

-

    timezone, parse_date, parse_datetime, parse_time, BytesIO, six, smart_text, 

-

    force_text, is_non_str_iterable 

-

) 

-

from rest_framework.settings import api_settings 

-

 

-

 

-

def is_simple_callable(obj): 

-

    """ 

-

    True if the object is a callable that takes no arguments. 

-

    """ 

-

    function = inspect.isfunction(obj) 

-

    method = inspect.ismethod(obj) 

-

 

-

    if not (function or method): 

-

        return False 

-

 

-

    args, _, _, defaults = inspect.getargspec(obj) 

-

    len_args = len(args) if function else len(args) - 1 

-

    len_defaults = len(defaults) if defaults else 0 

-

    return len_args <= len_defaults 

-

 

-

 

-

def get_component(obj, attr_name): 

-

    """ 

-

    Given an object, and an attribute name, 

-

    return that attribute on the object. 

-

    """ 

-

    if isinstance(obj, dict): 

-

        val = obj.get(attr_name) 

-

    else: 

-

        val = getattr(obj, attr_name) 

-

 

-

    if is_simple_callable(val): 

-

        return val() 

-

    return val 

-

 

-

 

-

def readable_datetime_formats(formats): 

-

    format = ', '.join(formats).replace(ISO_8601, 

-

             'YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HHMM|-HHMM|Z]') 

-

    return humanize_strptime(format) 

-

 

-

 

-

def readable_date_formats(formats): 

-

    format = ', '.join(formats).replace(ISO_8601, 'YYYY[-MM[-DD]]') 

-

    return humanize_strptime(format) 

-

 

-

 

-

def readable_time_formats(formats): 

-

    format = ', '.join(formats).replace(ISO_8601, 'hh:mm[:ss[.uuuuuu]]') 

-

    return humanize_strptime(format) 

-

 

-

 

-

def humanize_strptime(format_string): 

-

    # Note that we're missing some of the locale specific mappings that 

-

    # don't really make sense. 

-

    mapping = { 

-

        "%Y": "YYYY", 

-

        "%y": "YY", 

-

        "%m": "MM", 

-

        "%b": "[Jan-Dec]", 

-

        "%B": "[January-December]", 

-

        "%d": "DD", 

-

        "%H": "hh", 

-

        "%I": "hh",  # Requires '%p' to differentiate from '%H'. 

-

        "%M": "mm", 

-

        "%S": "ss", 

-

        "%f": "uuuuuu", 

-

        "%a": "[Mon-Sun]", 

-

        "%A": "[Monday-Sunday]", 

-

        "%p": "[AM|PM]", 

-

        "%z": "[+HHMM|-HHMM]" 

-

    } 

-

    for key, val in mapping.items(): 

-

        format_string = format_string.replace(key, val) 

-

    return format_string 

-

 

-

 

-

class Field(object): 

-

    read_only = True 

-

    creation_counter = 0 

-

    empty = '' 

-

    type_name = None 

-

    partial = False 

-

    use_files = False 

-

    form_field_class = forms.CharField 

-

    type_label = 'field' 

-

 

-

    def __init__(self, source=None, label=None, help_text=None): 

-

        self.parent = None 

-

 

-

        self.creation_counter = Field.creation_counter 

-

        Field.creation_counter += 1 

-

 

-

        self.source = source 

-

 

-

        if label is not None: 

-

            self.label = smart_text(label) 

-

 

-

        if help_text is not None: 

-

            self.help_text = smart_text(help_text) 

-

 

-

    def initialize(self, parent, field_name): 

-

        """ 

-

        Called to set up a field prior to field_to_native or field_from_native. 

-

 

-

        parent - The parent serializer. 

-

        model_field - The model field this field corresponds to, if one exists. 

-

        """ 

-

        self.parent = parent 

-

        self.root = parent.root or parent 

-

        self.context = self.root.context 

-

        self.partial = self.root.partial 

-

        if self.partial: 

-

            self.required = False 

-

 

-

    def field_from_native(self, data, files, field_name, into): 

-

        """ 

-

        Given a dictionary and a field name, updates the dictionary `into`, 

-

        with the field and it's deserialized value. 

-

        """ 

-

        return 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        """ 

-

        Given and object and a field name, returns the value that should be 

-

        serialized for that field. 

-

        """ 

-

        if obj is None: 

-

            return self.empty 

-

 

-

        if self.source == '*': 

-

            return self.to_native(obj) 

-

 

-

        source = self.source or field_name 

-

        value = obj 

-

 

-

        for component in source.split('.'): 

-

            value = get_component(value, component) 

-

            if value is None: 

-

                break 

-

 

-

        return self.to_native(value) 

-

 

-

    def to_native(self, value): 

-

        """ 

-

        Converts the field's value into it's simple representation. 

-

        """ 

-

        if is_simple_callable(value): 

-

            value = value() 

-

 

-

        if is_protected_type(value): 

-

            return value 

-

        elif (is_non_str_iterable(value) and 

-

              not isinstance(value, (dict, six.string_types))): 

-

            return [self.to_native(item) for item in value] 

-

        elif isinstance(value, dict): 

-

            # Make sure we preserve field ordering, if it exists 

-

            ret = SortedDict() 

-

            for key, val in value.items(): 

-

                ret[key] = self.to_native(val) 

-

            return ret 

-

        return force_text(value) 

-

 

-

    def attributes(self): 

-

        """ 

-

        Returns a dictionary of attributes to be used when serializing to xml. 

-

        """ 

-

        if self.type_name: 

-

            return {'type': self.type_name} 

-

        return {} 

-

 

-

    def metadata(self): 

-

        metadata = SortedDict() 

-

        metadata['type'] = self.type_label 

-

        metadata['required'] = getattr(self, 'required', False) 

-

        optional_attrs = ['read_only', 'label', 'help_text', 

-

                          'min_length', 'max_length'] 

-

        for attr in optional_attrs: 

-

            value = getattr(self, attr, None) 

-

            if value is not None and value != '': 

-

                metadata[attr] = force_text(value, strings_only=True) 

-

        return metadata 

-

 

-

 

-

class WritableField(Field): 

-

    """ 

-

    Base for read/write fields. 

-

    """ 

-

    default_validators = [] 

-

    default_error_messages = { 

-

        'required': _('This field is required.'), 

-

        'invalid': _('Invalid value.'), 

-

    } 

-

    widget = widgets.TextInput 

-

    default = None 

-

 

-

    def __init__(self, source=None, label=None, help_text=None, 

-

                 read_only=False, required=None, 

-

                 validators=[], error_messages=None, widget=None, 

-

                 default=None, blank=None): 

-

 

-

        # 'blank' is to be deprecated in favor of 'required' 

-

        if blank is not None: 

-

            warnings.warn('The `blank` keyword argument is deprecated. ' 

-

                          'Use the `required` keyword argument instead.', 

-

                          DeprecationWarning, stacklevel=2) 

-

            required = not(blank) 

-

 

-

        super(WritableField, self).__init__(source=source, label=label, help_text=help_text) 

-

 

-

        self.read_only = read_only 

-

        if required is None: 

-

            self.required = not(read_only) 

-

        else: 

-

            assert not (read_only and required), "Cannot set required=True and read_only=True" 

-

            self.required = required 

-

 

-

        messages = {} 

-

        for c in reversed(self.__class__.__mro__): 

-

            messages.update(getattr(c, 'default_error_messages', {})) 

-

        messages.update(error_messages or {}) 

-

        self.error_messages = messages 

-

 

-

        self.validators = self.default_validators + validators 

-

        self.default = default if default is not None else self.default 

-

 

-

        # Widgets are ony used for HTML forms. 

-

        widget = widget or self.widget 

-

        if isinstance(widget, type): 

-

            widget = widget() 

-

        self.widget = widget 

-

 

-

    def __deepcopy__(self, memo): 

-

        result = copy.copy(self) 

-

        memo[id(self)] = result 

-

        result.validators = self.validators[:] 

-

        return result 

-

 

-

    def validate(self, value): 

-

        if value in validators.EMPTY_VALUES and self.required: 

-

            raise ValidationError(self.error_messages['required']) 

-

 

-

    def run_validators(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return 

-

        errors = [] 

-

        for v in self.validators: 

-

            try: 

-

                v(value) 

-

            except ValidationError as e: 

-

                if hasattr(e, 'code') and e.code in self.error_messages: 

-

                    message = self.error_messages[e.code] 

-

                    if e.params: 

-

                        message = message % e.params 

-

                    errors.append(message) 

-

                else: 

-

                    errors.extend(e.messages) 

-

        if errors: 

-

            raise ValidationError(errors) 

-

 

-

    def field_from_native(self, data, files, field_name, into): 

-

        """ 

-

        Given a dictionary and a field name, updates the dictionary `into`, 

-

        with the field and it's deserialized value. 

-

        """ 

-

        if self.read_only: 

-

            return 

-

 

-

        try: 

-

            if self.use_files: 

-

                files = files or {} 

-

                native = files[field_name] 

-

            else: 

-

                native = data[field_name] 

-

        except KeyError: 

-

            if self.default is not None and not self.partial: 

-

                # Note: partial updates shouldn't set defaults 

-

                if is_simple_callable(self.default): 

-

                    native = self.default() 

-

                else: 

-

                    native = self.default 

-

            else: 

-

                if self.required: 

-

                    raise ValidationError(self.error_messages['required']) 

-

                return 

-

 

-

        value = self.from_native(native) 

-

        if self.source == '*': 

-

            if value: 

-

                into.update(value) 

-

        else: 

-

            self.validate(value) 

-

            self.run_validators(value) 

-

            into[self.source or field_name] = value 

-

 

-

    def from_native(self, value): 

-

        """ 

-

        Reverts a simple representation back to the field's value. 

-

        """ 

-

        return value 

-

 

-

 

-

class ModelField(WritableField): 

-

    """ 

-

    A generic field that can be used against an arbitrary model field. 

-

    """ 

-

    def __init__(self, *args, **kwargs): 

-

        try: 

-

            self.model_field = kwargs.pop('model_field') 

-

        except KeyError: 

-

            raise ValueError("ModelField requires 'model_field' kwarg") 

-

 

-

        self.min_length = kwargs.pop('min_length', 

-

                                     getattr(self.model_field, 'min_length', None)) 

-

        self.max_length = kwargs.pop('max_length', 

-

                                     getattr(self.model_field, 'max_length', None)) 

-

        self.min_value = kwargs.pop('min_value', 

-

                                    getattr(self.model_field, 'min_value', None)) 

-

        self.max_value = kwargs.pop('max_value', 

-

                                    getattr(self.model_field, 'max_value', None)) 

-

 

-

        super(ModelField, self).__init__(*args, **kwargs) 

-

 

-

        if self.min_length is not None: 

-

            self.validators.append(validators.MinLengthValidator(self.min_length)) 

-

        if self.max_length is not None: 

-

            self.validators.append(validators.MaxLengthValidator(self.max_length)) 

-

        if self.min_value is not None: 

-

            self.validators.append(validators.MinValueValidator(self.min_value)) 

-

        if self.max_value is not None: 

-

            self.validators.append(validators.MaxValueValidator(self.max_value)) 

-

 

-

    def from_native(self, value): 

-

        rel = getattr(self.model_field, "rel", None) 

-

        if rel is not None: 

-

            return rel.to._meta.get_field(rel.field_name).to_python(value) 

-

        else: 

-

            return self.model_field.to_python(value) 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        value = self.model_field._get_val_from_obj(obj) 

-

        if is_protected_type(value): 

-

            return value 

-

        return self.model_field.value_to_string(obj) 

-

 

-

    def attributes(self): 

-

        return { 

-

            "type": self.model_field.get_internal_type() 

-

        } 

-

 

-

 

-

##### Typed Fields ##### 

-

 

-

class BooleanField(WritableField): 

-

    type_name = 'BooleanField' 

-

    type_label = 'boolean' 

-

    form_field_class = forms.BooleanField 

-

    widget = widgets.CheckboxInput 

-

    default_error_messages = { 

-

        'invalid': _("'%s' value must be either True or False."), 

-

    } 

-

    empty = False 

-

 

-

    # Note: we set default to `False` in order to fill in missing value not 

-

    # supplied by html form.  TODO: Fix so that only html form input gets 

-

    # this behavior. 

-

    default = False 

-

 

-

    def from_native(self, value): 

-

        if value in ('true', 't', 'True', '1'): 

-

            return True 

-

        if value in ('false', 'f', 'False', '0'): 

-

            return False 

-

        return bool(value) 

-

 

-

 

-

class CharField(WritableField): 

-

    type_name = 'CharField' 

-

    type_label = 'string' 

-

    form_field_class = forms.CharField 

-

 

-

    def __init__(self, max_length=None, min_length=None, *args, **kwargs): 

-

        self.max_length, self.min_length = max_length, min_length 

-

        super(CharField, self).__init__(*args, **kwargs) 

-

        if min_length is not None: 

-

            self.validators.append(validators.MinLengthValidator(min_length)) 

-

        if max_length is not None: 

-

            self.validators.append(validators.MaxLengthValidator(max_length)) 

-

 

-

    def from_native(self, value): 

-

        if isinstance(value, six.string_types) or value is None: 

-

            return value 

-

        return smart_text(value) 

-

 

-

 

-

class URLField(CharField): 

-

    type_name = 'URLField' 

-

    type_label = 'url' 

-

 

-

    def __init__(self, **kwargs): 

-

        kwargs['validators'] = [validators.URLValidator()] 

-

        super(URLField, self).__init__(**kwargs) 

-

 

-

 

-

class SlugField(CharField): 

-

    type_name = 'SlugField' 

-

    type_label = 'slug' 

-

    form_field_class = forms.SlugField 

-

 

-

    default_error_messages = { 

-

        'invalid': _("Enter a valid 'slug' consisting of letters, numbers," 

-

                     " underscores or hyphens."), 

-

    } 

-

    default_validators = [validators.validate_slug] 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        super(SlugField, self).__init__(*args, **kwargs) 

-

 

-

 

-

class ChoiceField(WritableField): 

-

    type_name = 'ChoiceField' 

-

    type_label = 'multiple choice' 

-

    form_field_class = forms.ChoiceField 

-

    widget = widgets.Select 

-

    default_error_messages = { 

-

        'invalid_choice': _('Select a valid choice. %(value)s is not one of ' 

-

                            'the available choices.'), 

-

    } 

-

 

-

    def __init__(self, choices=(), *args, **kwargs): 

-

        super(ChoiceField, self).__init__(*args, **kwargs) 

-

        self.choices = choices 

-

        if not self.required: 

-

            self.choices = BLANK_CHOICE_DASH + self.choices 

-

 

-

    def _get_choices(self): 

-

        return self._choices 

-

 

-

    def _set_choices(self, value): 

-

        # Setting choices also sets the choices on the widget. 

-

        # choices can be any iterable, but we call list() on it because 

-

        # it will be consumed more than once. 

-

        self._choices = self.widget.choices = list(value) 

-

 

-

    choices = property(_get_choices, _set_choices) 

-

 

-

    def validate(self, value): 

-

        """ 

-

        Validates that the input is in self.choices. 

-

        """ 

-

        super(ChoiceField, self).validate(value) 

-

        if value and not self.valid_value(value): 

-

            raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) 

-

 

-

    def valid_value(self, value): 

-

        """ 

-

        Check to see if the provided value is a valid choice. 

-

        """ 

-

        for k, v in self.choices: 

-

            if isinstance(v, (list, tuple)): 

-

                # This is an optgroup, so look inside the group for options 

-

                for k2, v2 in v: 

-

                    if value == smart_text(k2): 

-

                        return True 

-

            else: 

-

                if value == smart_text(k) or value == k: 

-

                    return True 

-

        return False 

-

 

-

 

-

class EmailField(CharField): 

-

    type_name = 'EmailField' 

-

    type_label = 'email' 

-

    form_field_class = forms.EmailField 

-

 

-

    default_error_messages = { 

-

        'invalid': _('Enter a valid e-mail address.'), 

-

    } 

-

    default_validators = [validators.validate_email] 

-

 

-

    def from_native(self, value): 

-

        ret = super(EmailField, self).from_native(value) 

-

        if ret is None: 

-

            return None 

-

        return ret.strip() 

-

 

-

 

-

class RegexField(CharField): 

-

    type_name = 'RegexField' 

-

    type_label = 'regex' 

-

    form_field_class = forms.RegexField 

-

 

-

    def __init__(self, regex, max_length=None, min_length=None, *args, **kwargs): 

-

        super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) 

-

        self.regex = regex 

-

 

-

    def _get_regex(self): 

-

        return self._regex 

-

 

-

    def _set_regex(self, regex): 

-

        if isinstance(regex, six.string_types): 

-

            regex = re.compile(regex) 

-

        self._regex = regex 

-

        if hasattr(self, '_regex_validator') and self._regex_validator in self.validators: 

-

            self.validators.remove(self._regex_validator) 

-

        self._regex_validator = validators.RegexValidator(regex=regex) 

-

        self.validators.append(self._regex_validator) 

-

 

-

    regex = property(_get_regex, _set_regex) 

-

 

-

 

-

class DateField(WritableField): 

-

    type_name = 'DateField' 

-

    type_label = 'date' 

-

    widget = widgets.DateInput 

-

    form_field_class = forms.DateField 

-

 

-

    default_error_messages = { 

-

        'invalid': _("Date has wrong format. Use one of these formats instead: %s"), 

-

    } 

-

    empty = None 

-

    input_formats = api_settings.DATE_INPUT_FORMATS 

-

    format = api_settings.DATE_FORMAT 

-

 

-

    def __init__(self, input_formats=None, format=None, *args, **kwargs): 

-

        self.input_formats = input_formats if input_formats is not None else self.input_formats 

-

        self.format = format if format is not None else self.format 

-

        super(DateField, self).__init__(*args, **kwargs) 

-

 

-

    def from_native(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        if isinstance(value, datetime.datetime): 

-

            if timezone and settings.USE_TZ and timezone.is_aware(value): 

-

                # Convert aware datetimes to the default time zone 

-

                # before casting them to dates (#17742). 

-

                default_timezone = timezone.get_default_timezone() 

-

                value = timezone.make_naive(value, default_timezone) 

-

            return value.date() 

-

        if isinstance(value, datetime.date): 

-

            return value 

-

 

-

        for format in self.input_formats: 

-

            if format.lower() == ISO_8601: 

-

                try: 

-

                    parsed = parse_date(value) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    if parsed is not None: 

-

                        return parsed 

-

            else: 

-

                try: 

-

                    parsed = datetime.datetime.strptime(value, format) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    return parsed.date() 

-

 

-

        msg = self.error_messages['invalid'] % readable_date_formats(self.input_formats) 

-

        raise ValidationError(msg) 

-

 

-

    def to_native(self, value): 

-

        if value is None or self.format is None: 

-

            return value 

-

 

-

        if isinstance(value, datetime.datetime): 

-

            value = value.date() 

-

 

-

        if self.format.lower() == ISO_8601: 

-

            return value.isoformat() 

-

        return value.strftime(self.format) 

-

 

-

 

-

class DateTimeField(WritableField): 

-

    type_name = 'DateTimeField' 

-

    type_label = 'datetime' 

-

    widget = widgets.DateTimeInput 

-

    form_field_class = forms.DateTimeField 

-

 

-

    default_error_messages = { 

-

        'invalid': _("Datetime has wrong format. Use one of these formats instead: %s"), 

-

    } 

-

    empty = None 

-

    input_formats = api_settings.DATETIME_INPUT_FORMATS 

-

    format = api_settings.DATETIME_FORMAT 

-

 

-

    def __init__(self, input_formats=None, format=None, *args, **kwargs): 

-

        self.input_formats = input_formats if input_formats is not None else self.input_formats 

-

        self.format = format if format is not None else self.format 

-

        super(DateTimeField, self).__init__(*args, **kwargs) 

-

 

-

    def from_native(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        if isinstance(value, datetime.datetime): 

-

            return value 

-

        if isinstance(value, datetime.date): 

-

            value = datetime.datetime(value.year, value.month, value.day) 

-

            if settings.USE_TZ: 

-

                # For backwards compatibility, interpret naive datetimes in 

-

                # local time. This won't work during DST change, but we can't 

-

                # do much about it, so we let the exceptions percolate up the 

-

                # call stack. 

-

                warnings.warn("DateTimeField received a naive datetime (%s)" 

-

                              " while time zone support is active." % value, 

-

                              RuntimeWarning) 

-

                default_timezone = timezone.get_default_timezone() 

-

                value = timezone.make_aware(value, default_timezone) 

-

            return value 

-

 

-

        for format in self.input_formats: 

-

            if format.lower() == ISO_8601: 

-

                try: 

-

                    parsed = parse_datetime(value) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    if parsed is not None: 

-

                        return parsed 

-

            else: 

-

                try: 

-

                    parsed = datetime.datetime.strptime(value, format) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    return parsed 

-

 

-

        msg = self.error_messages['invalid'] % readable_datetime_formats(self.input_formats) 

-

        raise ValidationError(msg) 

-

 

-

    def to_native(self, value): 

-

        if value is None or self.format is None: 

-

            return value 

-

 

-

        if self.format.lower() == ISO_8601: 

-

            ret = value.isoformat() 

-

            if ret.endswith('+00:00'): 

-

                ret = ret[:-6] + 'Z' 

-

            return ret 

-

        return value.strftime(self.format) 

-

 

-

 

-

class TimeField(WritableField): 

-

    type_name = 'TimeField' 

-

    type_label = 'time' 

-

    widget = widgets.TimeInput 

-

    form_field_class = forms.TimeField 

-

 

-

    default_error_messages = { 

-

        'invalid': _("Time has wrong format. Use one of these formats instead: %s"), 

-

    } 

-

    empty = None 

-

    input_formats = api_settings.TIME_INPUT_FORMATS 

-

    format = api_settings.TIME_FORMAT 

-

 

-

    def __init__(self, input_formats=None, format=None, *args, **kwargs): 

-

        self.input_formats = input_formats if input_formats is not None else self.input_formats 

-

        self.format = format if format is not None else self.format 

-

        super(TimeField, self).__init__(*args, **kwargs) 

-

 

-

    def from_native(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        if isinstance(value, datetime.time): 

-

            return value 

-

 

-

        for format in self.input_formats: 

-

            if format.lower() == ISO_8601: 

-

                try: 

-

                    parsed = parse_time(value) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    if parsed is not None: 

-

                        return parsed 

-

            else: 

-

                try: 

-

                    parsed = datetime.datetime.strptime(value, format) 

-

                except (ValueError, TypeError): 

-

                    pass 

-

                else: 

-

                    return parsed.time() 

-

 

-

        msg = self.error_messages['invalid'] % readable_time_formats(self.input_formats) 

-

        raise ValidationError(msg) 

-

 

-

    def to_native(self, value): 

-

        if value is None or self.format is None: 

-

            return value 

-

 

-

        if isinstance(value, datetime.datetime): 

-

            value = value.time() 

-

 

-

        if self.format.lower() == ISO_8601: 

-

            return value.isoformat() 

-

        return value.strftime(self.format) 

-

 

-

 

-

class IntegerField(WritableField): 

-

    type_name = 'IntegerField' 

-

    type_label = 'integer' 

-

    form_field_class = forms.IntegerField 

-

 

-

    default_error_messages = { 

-

        'invalid': _('Enter a whole number.'), 

-

        'max_value': _('Ensure this value is less than or equal to %(limit_value)s.'), 

-

        'min_value': _('Ensure this value is greater than or equal to %(limit_value)s.'), 

-

    } 

-

 

-

    def __init__(self, max_value=None, min_value=None, *args, **kwargs): 

-

        self.max_value, self.min_value = max_value, min_value 

-

        super(IntegerField, self).__init__(*args, **kwargs) 

-

 

-

        if max_value is not None: 

-

            self.validators.append(validators.MaxValueValidator(max_value)) 

-

        if min_value is not None: 

-

            self.validators.append(validators.MinValueValidator(min_value)) 

-

 

-

    def from_native(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        try: 

-

            value = int(str(value)) 

-

        except (ValueError, TypeError): 

-

            raise ValidationError(self.error_messages['invalid']) 

-

        return value 

-

 

-

 

-

class FloatField(WritableField): 

-

    type_name = 'FloatField' 

-

    type_label = 'float' 

-

    form_field_class = forms.FloatField 

-

 

-

    default_error_messages = { 

-

        'invalid': _("'%s' value must be a float."), 

-

    } 

-

 

-

    def from_native(self, value): 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        try: 

-

            return float(value) 

-

        except (TypeError, ValueError): 

-

            msg = self.error_messages['invalid'] % value 

-

            raise ValidationError(msg) 

-

 

-

 

-

class DecimalField(WritableField): 

-

    type_name = 'DecimalField' 

-

    type_label = 'decimal' 

-

    form_field_class = forms.DecimalField 

-

 

-

    default_error_messages = { 

-

        'invalid': _('Enter a number.'), 

-

        'max_value': _('Ensure this value is less than or equal to %(limit_value)s.'), 

-

        'min_value': _('Ensure this value is greater than or equal to %(limit_value)s.'), 

-

        'max_digits': _('Ensure that there are no more than %s digits in total.'), 

-

        'max_decimal_places': _('Ensure that there are no more than %s decimal places.'), 

-

        'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.') 

-

    } 

-

 

-

    def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 

-

        self.max_value, self.min_value = max_value, min_value 

-

        self.max_digits, self.decimal_places = max_digits, decimal_places 

-

        super(DecimalField, self).__init__(*args, **kwargs) 

-

 

-

        if max_value is not None: 

-

            self.validators.append(validators.MaxValueValidator(max_value)) 

-

        if min_value is not None: 

-

            self.validators.append(validators.MinValueValidator(min_value)) 

-

 

-

    def from_native(self, value): 

-

        """ 

-

        Validates that the input is a decimal number. Returns a Decimal 

-

        instance. Returns None for empty values. Ensures that there are no more 

-

        than max_digits in the number, and no more than decimal_places digits 

-

        after the decimal point. 

-

        """ 

-

        if value in validators.EMPTY_VALUES: 

-

            return None 

-

        value = smart_text(value).strip() 

-

        try: 

-

            value = Decimal(value) 

-

        except DecimalException: 

-

            raise ValidationError(self.error_messages['invalid']) 

-

        return value 

-

 

-

    def validate(self, value): 

-

        super(DecimalField, self).validate(value) 

-

        if value in validators.EMPTY_VALUES: 

-

            return 

-

        # Check for NaN, Inf and -Inf values. We can't compare directly for NaN, 

-

        # since it is never equal to itself. However, NaN is the only value that 

-

        # isn't equal to itself, so we can use this to identify NaN 

-

        if value != value or value == Decimal("Inf") or value == Decimal("-Inf"): 

-

            raise ValidationError(self.error_messages['invalid']) 

-

        sign, digittuple, exponent = value.as_tuple() 

-

        decimals = abs(exponent) 

-

        # digittuple doesn't include any leading zeros. 

-

        digits = len(digittuple) 

-

        if decimals > digits: 

-

            # We have leading zeros up to or past the decimal point.  Count 

-

            # everything past the decimal point as a digit.  We do not count 

-

            # 0 before the decimal point as a digit since that would mean 

-

            # we would not allow max_digits = decimal_places. 

-

            digits = decimals 

-

        whole_digits = digits - decimals 

-

 

-

        if self.max_digits is not None and digits > self.max_digits: 

-

            raise ValidationError(self.error_messages['max_digits'] % self.max_digits) 

-

        if self.decimal_places is not None and decimals > self.decimal_places: 

-

            raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) 

-

        if self.max_digits is not None and self.decimal_places is not None and whole_digits > (self.max_digits - self.decimal_places): 

-

            raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 

-

        return value 

-

 

-

 

-

class FileField(WritableField): 

-

    use_files = True 

-

    type_name = 'FileField' 

-

    type_label = 'file upload' 

-

    form_field_class = forms.FileField 

-

    widget = widgets.FileInput 

-

 

-

    default_error_messages = { 

-

        'invalid': _("No file was submitted. Check the encoding type on the form."), 

-

        'missing': _("No file was submitted."), 

-

        'empty': _("The submitted file is empty."), 

-

        'max_length': _('Ensure this filename has at most %(max)d characters (it has %(length)d).'), 

-

        'contradiction': _('Please either submit a file or check the clear checkbox, not both.') 

-

    } 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        self.max_length = kwargs.pop('max_length', None) 

-

        self.allow_empty_file = kwargs.pop('allow_empty_file', False) 

-

        super(FileField, self).__init__(*args, **kwargs) 

-

 

-

    def from_native(self, data): 

-

        if data in validators.EMPTY_VALUES: 

-

            return None 

-

 

-

        # UploadedFile objects should have name and size attributes. 

-

        try: 

-

            file_name = data.name 

-

            file_size = data.size 

-

        except AttributeError: 

-

            raise ValidationError(self.error_messages['invalid']) 

-

 

-

        if self.max_length is not None and len(file_name) > self.max_length: 

-

            error_values = {'max': self.max_length, 'length': len(file_name)} 

-

            raise ValidationError(self.error_messages['max_length'] % error_values) 

-

        if not file_name: 

-

            raise ValidationError(self.error_messages['invalid']) 

-

        if not self.allow_empty_file and not file_size: 

-

            raise ValidationError(self.error_messages['empty']) 

-

 

-

        return data 

-

 

-

    def to_native(self, value): 

-

        return value.name 

-

 

-

 

-

class ImageField(FileField): 

-

    use_files = True 

-

    type_name = 'ImageField' 

-

    type_label = 'image upload' 

-

    form_field_class = forms.ImageField 

-

 

-

    default_error_messages = { 

-

        'invalid_image': _("Upload a valid image. The file you uploaded was " 

-

                           "either not an image or a corrupted image."), 

-

    } 

-

 

-

    def from_native(self, data): 

-

        """ 

-

        Checks that the file-upload field data contains a valid image (GIF, JPG, 

-

        PNG, possibly others -- whatever the Python Imaging Library supports). 

-

        """ 

-

        f = super(ImageField, self).from_native(data) 

-

        if f is None: 

-

            return None 

-

 

-

        from compat import Image 

-

        assert Image is not None, 'PIL must be installed for ImageField support' 

-

 

-

        # We need to get a file object for PIL. We might have a path or we might 

-

        # have to read the data into memory. 

-

        if hasattr(data, 'temporary_file_path'): 

-

            file = data.temporary_file_path() 

-

        else: 

-

            if hasattr(data, 'read'): 

-

                file = BytesIO(data.read()) 

-

            else: 

-

                file = BytesIO(data['content']) 

-

 

-

        try: 

-

            # load() could spot a truncated JPEG, but it loads the entire 

-

            # image in memory, which is a DoS vector. See #3848 and #18520. 

-

            # verify() must be called immediately after the constructor. 

-

            Image.open(file).verify() 

-

        except ImportError: 

-

            # Under PyPy, it is possible to import PIL. However, the underlying 

-

            # _imaging C module isn't available, so an ImportError will be 

-

            # raised. Catch and re-raise. 

-

            raise 

-

        except Exception:  # Python Imaging Library doesn't recognize it as an image 

-

            raise ValidationError(self.error_messages['invalid_image']) 

-

        if hasattr(f, 'seek') and callable(f.seek): 

-

            f.seek(0) 

-

        return f 

-

 

-

 

-

class SerializerMethodField(Field): 

-

    """ 

-

    A field that gets its value by calling a method on the serializer it's attached to. 

-

    """ 

-

 

-

    def __init__(self, method_name): 

-

        self.method_name = method_name 

-

        super(SerializerMethodField, self).__init__() 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        value = getattr(self.parent, self.method_name)(obj) 

-

        return self.to_native(value) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_filters.html b/htmlcov/rest_framework_filters.html deleted file mode 100644 index 28b6eaae5..000000000 --- a/htmlcov/rest_framework_filters.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - - Coverage for rest_framework/filters: 92% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

- -
-

""" 

-

Provides generic filtering backends that can be used to filter the results 

-

returned by list views. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.db import models 

-

from rest_framework.compat import django_filters, six 

-

from functools import reduce 

-

import operator 

-

 

-

FilterSet = django_filters and django_filters.FilterSet or None 

-

 

-

 

-

class BaseFilterBackend(object): 

-

    """ 

-

    A base class from which all filter backend classes should inherit. 

-

    """ 

-

 

-

    def filter_queryset(self, request, queryset, view): 

-

        """ 

-

        Return a filtered queryset. 

-

        """ 

-

        raise NotImplementedError(".filter_queryset() must be overridden.") 

-

 

-

 

-

class DjangoFilterBackend(BaseFilterBackend): 

-

    """ 

-

    A filter backend that uses django-filter. 

-

    """ 

-

    default_filter_set = FilterSet 

-

 

-

    def __init__(self): 

-

        assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed' 

-

 

-

    def get_filter_class(self, view, queryset=None): 

-

        """ 

-

        Return the django-filters `FilterSet` used to filter the queryset. 

-

        """ 

-

        filter_class = getattr(view, 'filter_class', None) 

-

        filter_fields = getattr(view, 'filter_fields', None) 

-

 

-

        if filter_class: 

-

            filter_model = filter_class.Meta.model 

-

 

-

            assert issubclass(filter_model, queryset.model), \ 

-

                'FilterSet model %s does not match queryset model %s' % \ 

-

                (filter_model, queryset.model) 

-

 

-

            return filter_class 

-

 

-

        if filter_fields: 

-

            class AutoFilterSet(self.default_filter_set): 

-

                class Meta: 

-

                    model = queryset.model 

-

                    fields = filter_fields 

-

            return AutoFilterSet 

-

 

-

        return None 

-

 

-

    def filter_queryset(self, request, queryset, view): 

-

        filter_class = self.get_filter_class(view, queryset) 

-

 

-

        if filter_class: 

-

            return filter_class(request.QUERY_PARAMS, queryset=queryset).qs 

-

 

-

        return queryset 

-

 

-

 

-

class SearchFilter(BaseFilterBackend): 

-

    search_param = 'search'  # The URL query parameter used for the search. 

-

 

-

    def get_search_terms(self, request): 

-

        """ 

-

        Search terms are set by a ?search=... query parameter, 

-

        and may be comma and/or whitespace delimited. 

-

        """ 

-

        params = request.QUERY_PARAMS.get(self.search_param, '') 

-

        return params.replace(',', ' ').split() 

-

 

-

    def construct_search(self, field_name): 

-

        if field_name.startswith('^'): 

-

            return "%s__istartswith" % field_name[1:] 

-

        elif field_name.startswith('='): 

-

            return "%s__iexact" % field_name[1:] 

-

        elif field_name.startswith('@'): 

-

            return "%s__search" % field_name[1:] 

-

        else: 

-

            return "%s__icontains" % field_name 

-

 

-

    def filter_queryset(self, request, queryset, view): 

-

        search_fields = getattr(view, 'search_fields', None) 

-

 

-

        if not search_fields: 

-

            return queryset 

-

 

-

        orm_lookups = [self.construct_search(str(search_field)) 

-

                       for search_field in search_fields] 

-

 

-

        for search_term in self.get_search_terms(request): 

-

            or_queries = [models.Q(**{orm_lookup: search_term}) 

-

                          for orm_lookup in orm_lookups] 

-

            queryset = queryset.filter(reduce(operator.or_, or_queries)) 

-

 

-

        return queryset 

-

 

-

 

-

class OrderingFilter(BaseFilterBackend): 

-

    ordering_param = 'ordering'  # The URL query parameter used for the ordering. 

-

 

-

    def get_ordering(self, request): 

-

        """ 

-

        Search terms are set by a ?search=... query parameter, 

-

        and may be comma and/or whitespace delimited. 

-

        """ 

-

        params = request.QUERY_PARAMS.get(self.ordering_param) 

-

        if params: 

-

            return [param.strip() for param in params.split(',')] 

-

 

-

    def get_default_ordering(self, view): 

-

        ordering = getattr(view, 'ordering', None) 

-

        if isinstance(ordering, six.string_types): 

-

            return (ordering,) 

-

        return ordering 

-

 

-

    def remove_invalid_fields(self, queryset, ordering): 

-

        field_names = [field.name for field in queryset.model._meta.fields] 

-

        return [term for term in ordering if term.lstrip('-') in field_names] 

-

 

-

    def filter_queryset(self, request, queryset, view): 

-

        ordering = self.get_ordering(request) 

-

 

-

        if ordering: 

-

            # Skip any incorrect parameters 

-

            ordering = self.remove_invalid_fields(queryset, ordering) 

-

 

-

        if not ordering: 

-

            # Use 'ordering' attribtue by default 

-

            ordering = self.get_default_ordering(view) 

-

 

-

        if ordering: 

-

            return queryset.order_by(*ordering) 

-

 

-

        return queryset 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_generics.html b/htmlcov/rest_framework_generics.html deleted file mode 100644 index 5f5851cbd..000000000 --- a/htmlcov/rest_framework_generics.html +++ /dev/null @@ -1,1079 +0,0 @@ - - - - - - - - Coverage for rest_framework/generics: 83% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

-

370

-

371

-

372

-

373

-

374

-

375

-

376

-

377

-

378

-

379

-

380

-

381

-

382

-

383

-

384

-

385

-

386

-

387

-

388

-

389

-

390

-

391

-

392

-

393

-

394

-

395

-

396

-

397

-

398

-

399

-

400

-

401

-

402

-

403

-

404

-

405

-

406

-

407

-

408

-

409

-

410

-

411

-

412

-

413

-

414

-

415

-

416

-

417

-

418

-

419

-

420

-

421

-

422

-

423

-

424

-

425

-

426

-

427

-

428

-

429

-

430

-

431

-

432

-

433

-

434

-

435

-

436

-

437

-

438

-

439

-

440

-

441

-

442

-

443

-

444

-

445

-

446

-

447

-

448

-

449

-

450

-

451

-

452

-

453

-

454

-

455

-

456

-

457

-

458

-

459

-

460

-

461

-

462

-

463

-

464

-

465

-

466

-

467

-

468

-

469

-

470

-

471

-

472

-

473

-

474

-

475

-

476

-

477

-

478

-

479

-

480

-

481

-

482

-

483

-

484

-

485

-

486

-

487

-

488

-

489

-

490

-

491

-

492

-

493

-

494

-

495

-

496

-

497

-

498

-

499

- -
-

""" 

-

Generic views that provide commonly needed behaviour. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from django.core.exceptions import ImproperlyConfigured, PermissionDenied 

-

from django.core.paginator import Paginator, InvalidPage 

-

from django.http import Http404 

-

from django.shortcuts import get_object_or_404 as _get_object_or_404 

-

from django.utils.translation import ugettext as _ 

-

from rest_framework import views, mixins, exceptions 

-

from rest_framework.request import clone_request 

-

from rest_framework.settings import api_settings 

-

import warnings 

-

 

-

 

-

def get_object_or_404(queryset, **filter_kwargs): 

-

    """ 

-

    Same as Django's standard shortcut, but make sure to raise 404 

-

    if the filter_kwargs don't match the required types. 

-

    """ 

-

    try: 

-

        return _get_object_or_404(queryset, **filter_kwargs) 

-

    except (TypeError, ValueError): 

-

        raise Http404 

-

 

-

 

-

class GenericAPIView(views.APIView): 

-

    """ 

-

    Base class for all other generic views. 

-

    """ 

-

 

-

    # You'll need to either set these attributes, 

-

    # or override `get_queryset()`/`get_serializer_class()`. 

-

    queryset = None 

-

    serializer_class = None 

-

 

-

    # This shortcut may be used instead of setting either or both 

-

    # of the `queryset`/`serializer_class` attributes, although using 

-

    # the explicit style is generally preferred. 

-

    model = None 

-

 

-

    # If you want to use object lookups other than pk, set this attribute. 

-

    # For more complex lookup requirements override `get_object()`. 

-

    lookup_field = 'pk' 

-

 

-

    # Pagination settings 

-

    paginate_by = api_settings.PAGINATE_BY 

-

    paginate_by_param = api_settings.PAGINATE_BY_PARAM 

-

    pagination_serializer_class = api_settings.DEFAULT_PAGINATION_SERIALIZER_CLASS 

-

    page_kwarg = 'page' 

-

 

-

    # The filter backend classes to use for queryset filtering 

-

    filter_backends = api_settings.DEFAULT_FILTER_BACKENDS 

-

 

-

    # The following attributes may be subject to change, 

-

    # and should be considered private API. 

-

    model_serializer_class = api_settings.DEFAULT_MODEL_SERIALIZER_CLASS 

-

    paginator_class = Paginator 

-

 

-

    ###################################### 

-

    # These are pending deprecation... 

-

 

-

    pk_url_kwarg = 'pk' 

-

    slug_url_kwarg = 'slug' 

-

    slug_field = 'slug' 

-

    allow_empty = True 

-

    filter_backend = api_settings.FILTER_BACKEND 

-

 

-

    def get_serializer_context(self): 

-

        """ 

-

        Extra context provided to the serializer class. 

-

        """ 

-

        return { 

-

            'request': self.request, 

-

            'format': self.format_kwarg, 

-

            'view': self 

-

        } 

-

 

-

    def get_serializer(self, instance=None, data=None, 

-

                       files=None, many=False, partial=False): 

-

        """ 

-

        Return the serializer instance that should be used for validating and 

-

        deserializing input, and for serializing output. 

-

        """ 

-

        serializer_class = self.get_serializer_class() 

-

        context = self.get_serializer_context() 

-

        return serializer_class(instance, data=data, files=files, 

-

                                many=many, partial=partial, context=context) 

-

 

-

    def get_pagination_serializer(self, page): 

-

        """ 

-

        Return a serializer instance to use with paginated data. 

-

        """ 

-

        class SerializerClass(self.pagination_serializer_class): 

-

            class Meta: 

-

                object_serializer_class = self.get_serializer_class() 

-

 

-

        pagination_serializer_class = SerializerClass 

-

        context = self.get_serializer_context() 

-

        return pagination_serializer_class(instance=page, context=context) 

-

 

-

    def paginate_queryset(self, queryset, page_size=None): 

-

        """ 

-

        Paginate a queryset if required, either returning a page object, 

-

        or `None` if pagination is not configured for this view. 

-

        """ 

-

        deprecated_style = False 

-

        if page_size is not None: 

-

            warnings.warn('The `page_size` parameter to `paginate_queryset()` ' 

-

                          'is due to be deprecated. ' 

-

                          'Note that the return style of this method is also ' 

-

                          'changed, and will simply return a page object ' 

-

                          'when called without a `page_size` argument.', 

-

                          PendingDeprecationWarning, stacklevel=2) 

-

            deprecated_style = True 

-

        else: 

-

            # Determine the required page size. 

-

            # If pagination is not configured, simply return None. 

-

            page_size = self.get_paginate_by() 

-

            if not page_size: 

-

                return None 

-

 

-

        if not self.allow_empty: 

-

            warnings.warn( 

-

                'The `allow_empty` parameter is due to be deprecated. ' 

-

                'To use `allow_empty=False` style behavior, You should override ' 

-

                '`get_queryset()` and explicitly raise a 404 on empty querysets.', 

-

                PendingDeprecationWarning, stacklevel=2 

-

            ) 

-

 

-

        paginator = self.paginator_class(queryset, page_size, 

-

                                         allow_empty_first_page=self.allow_empty) 

-

        page_kwarg = self.kwargs.get(self.page_kwarg) 

-

        page_query_param = self.request.QUERY_PARAMS.get(self.page_kwarg) 

-

        page = page_kwarg or page_query_param or 1 

-

        try: 

-

            page_number = int(page) 

-

        except ValueError: 

-

            if page == 'last': 

-

                page_number = paginator.num_pages 

-

            else: 

-

                raise Http404(_("Page is not 'last', nor can it be converted to an int.")) 

-

        try: 

-

            page = paginator.page(page_number) 

-

        except InvalidPage as e: 

-

            raise Http404(_('Invalid page (%(page_number)s): %(message)s') % { 

-

                                'page_number': page_number, 

-

                                'message': str(e) 

-

            }) 

-

 

-

        if deprecated_style: 

-

            return (paginator, page, page.object_list, page.has_other_pages()) 

-

        return page 

-

 

-

    def filter_queryset(self, queryset): 

-

        """ 

-

        Given a queryset, filter it with whichever filter backend is in use. 

-

 

-

        You are unlikely to want to override this method, although you may need 

-

        to call it either from a list view, or from a custom `get_object` 

-

        method if you want to apply the configured filtering backend to the 

-

        default queryset. 

-

        """ 

-

        filter_backends = self.filter_backends or [] 

-

        if not filter_backends and self.filter_backend: 

-

            warnings.warn( 

-

                'The `filter_backend` attribute and `FILTER_BACKEND` setting ' 

-

                'are due to be deprecated in favor of a `filter_backends` ' 

-

                'attribute and `DEFAULT_FILTER_BACKENDS` setting, that take ' 

-

                'a *list* of filter backend classes.', 

-

                PendingDeprecationWarning, stacklevel=2 

-

            ) 

-

            filter_backends = [self.filter_backend] 

-

 

-

        for backend in filter_backends: 

-

            queryset = backend().filter_queryset(self.request, queryset, self) 

-

        return queryset 

-

 

-

    ######################## 

-

    ### The following methods provide default implementations 

-

    ### that you may want to override for more complex cases. 

-

 

-

    def get_paginate_by(self, queryset=None): 

-

        """ 

-

        Return the size of pages to use with pagination. 

-

 

-

        If `PAGINATE_BY_PARAM` is set it will attempt to get the page size 

-

        from a named query parameter in the url, eg. ?page_size=100 

-

 

-

        Otherwise defaults to using `self.paginate_by`. 

-

        """ 

-

        if queryset is not None: 

-

            warnings.warn('The `queryset` parameter to `get_paginate_by()` ' 

-

                          'is due to be deprecated.', 

-

                          PendingDeprecationWarning, stacklevel=2) 

-

 

-

        if self.paginate_by_param: 

-

            query_params = self.request.QUERY_PARAMS 

-

            try: 

-

                return int(query_params[self.paginate_by_param]) 

-

            except (KeyError, ValueError): 

-

                pass 

-

 

-

        return self.paginate_by 

-

 

-

    def get_serializer_class(self): 

-

        """ 

-

        Return the class to use for the serializer. 

-

        Defaults to using `self.serializer_class`. 

-

 

-

        You may want to override this if you need to provide different 

-

        serializations depending on the incoming request. 

-

 

-

        (Eg. admins get full serialization, others get basic serialization) 

-

        """ 

-

        serializer_class = self.serializer_class 

-

        if serializer_class is not None: 

-

            return serializer_class 

-

 

-

        assert self.model is not None, \ 

-

            "'%s' should either include a 'serializer_class' attribute, " \ 

-

            "or use the 'model' attribute as a shortcut for " \ 

-

            "automatically generating a serializer class." \ 

-

            % self.__class__.__name__ 

-

 

-

        class DefaultSerializer(self.model_serializer_class): 

-

            class Meta: 

-

                model = self.model 

-

        return DefaultSerializer 

-

 

-

    def get_queryset(self): 

-

        """ 

-

        Get the list of items for this view. 

-

        This must be an iterable, and may be a queryset. 

-

        Defaults to using `self.queryset`. 

-

 

-

        You may want to override this if you need to provide different 

-

        querysets depending on the incoming request. 

-

 

-

        (Eg. return a list of items that is specific to the user) 

-

        """ 

-

        if self.queryset is not None: 

-

            return self.queryset._clone() 

-

 

-

        if self.model is not None: 

-

            return self.model._default_manager.all() 

-

 

-

        raise ImproperlyConfigured("'%s' must define 'queryset' or 'model'" 

-

                                    % self.__class__.__name__) 

-

 

-

    def get_object(self, queryset=None): 

-

        """ 

-

        Returns the object the view is displaying. 

-

 

-

        You may want to override this if you need to provide non-standard 

-

        queryset lookups.  Eg if objects are referenced using multiple 

-

        keyword arguments in the url conf. 

-

        """ 

-

        # Determine the base queryset to use. 

-

        if queryset is None: 

-

            queryset = self.filter_queryset(self.get_queryset()) 

-

        else: 

-

            pass  # Deprecation warning 

-

 

-

        # Perform the lookup filtering. 

-

        pk = self.kwargs.get(self.pk_url_kwarg, None) 

-

        slug = self.kwargs.get(self.slug_url_kwarg, None) 

-

        lookup = self.kwargs.get(self.lookup_field, None) 

-

 

-

        if lookup is not None: 

-

            filter_kwargs = {self.lookup_field: lookup} 

-

        elif pk is not None and self.lookup_field == 'pk': 

-

            warnings.warn( 

-

                'The `pk_url_kwarg` attribute is due to be deprecated. ' 

-

                'Use the `lookup_field` attribute instead', 

-

                PendingDeprecationWarning 

-

            ) 

-

            filter_kwargs = {'pk': pk} 

-

        elif slug is not None and self.lookup_field == 'pk': 

-

            warnings.warn( 

-

                'The `slug_url_kwarg` attribute is due to be deprecated. ' 

-

                'Use the `lookup_field` attribute instead', 

-

                PendingDeprecationWarning 

-

            ) 

-

            filter_kwargs = {self.slug_field: slug} 

-

        else: 

-

            raise ImproperlyConfigured( 

-

                'Expected view %s to be called with a URL keyword argument ' 

-

                'named "%s". Fix your URL conf, or set the `.lookup_field` ' 

-

                'attribute on the view correctly.' % 

-

                (self.__class__.__name__, self.lookup_field) 

-

            ) 

-

 

-

        obj = get_object_or_404(queryset, **filter_kwargs) 

-

 

-

        # May raise a permission denied 

-

        self.check_object_permissions(self.request, obj) 

-

 

-

        return obj 

-

 

-

    ######################## 

-

    ### The following are placeholder methods, 

-

    ### and are intended to be overridden. 

-

    ### 

-

    ### The are not called by GenericAPIView directly, 

-

    ### but are used by the mixin methods. 

-

 

-

    def pre_save(self, obj): 

-

        """ 

-

        Placeholder method for calling before saving an object. 

-

 

-

        May be used to set attributes on the object that are implicit 

-

        in either the request, or the url. 

-

        """ 

-

        pass 

-

 

-

    def post_save(self, obj, created=False): 

-

        """ 

-

        Placeholder method for calling after saving an object. 

-

        """ 

-

        pass 

-

 

-

    def metadata(self, request): 

-

        """ 

-

        Return a dictionary of metadata about the view. 

-

        Used to return responses for OPTIONS requests. 

-

 

-

        We override the default behavior, and add some extra information 

-

        about the required request body for POST and PUT operations. 

-

        """ 

-

        ret = super(GenericAPIView, self).metadata(request) 

-

 

-

        actions = {} 

-

        for method in ('PUT', 'POST'): 

-

            if method not in self.allowed_methods: 

-

                continue 

-

 

-

            cloned_request = clone_request(request, method) 

-

            try: 

-

                # Test global permissions 

-

                self.check_permissions(cloned_request) 

-

                # Test object permissions 

-

                if method == 'PUT': 

-

                    self.get_object() 

-

            except (exceptions.APIException, PermissionDenied, Http404): 

-

                pass 

-

            else: 

-

                # If user has appropriate permissions for the view, include 

-

                # appropriate metadata about the fields that should be supplied. 

-

                serializer = self.get_serializer() 

-

                actions[method] = serializer.metadata() 

-

 

-

        if actions: 

-

            ret['actions'] = actions 

-

 

-

        return ret 

-

 

-

 

-

########################################################## 

-

### Concrete view classes that provide method handlers ### 

-

### by composing the mixin classes with the base view. ### 

-

########################################################## 

-

 

-

class CreateAPIView(mixins.CreateModelMixin, 

-

                    GenericAPIView): 

-

 

-

    """ 

-

    Concrete view for creating a model instance. 

-

    """ 

-

    def post(self, request, *args, **kwargs): 

-

        return self.create(request, *args, **kwargs) 

-

 

-

 

-

class ListAPIView(mixins.ListModelMixin, 

-

                  GenericAPIView): 

-

    """ 

-

    Concrete view for listing a queryset. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.list(request, *args, **kwargs) 

-

 

-

 

-

class RetrieveAPIView(mixins.RetrieveModelMixin, 

-

                      GenericAPIView): 

-

    """ 

-

    Concrete view for retrieving a model instance. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.retrieve(request, *args, **kwargs) 

-

 

-

 

-

class DestroyAPIView(mixins.DestroyModelMixin, 

-

                     GenericAPIView): 

-

 

-

    """ 

-

    Concrete view for deleting a model instance. 

-

    """ 

-

    def delete(self, request, *args, **kwargs): 

-

        return self.destroy(request, *args, **kwargs) 

-

 

-

 

-

class UpdateAPIView(mixins.UpdateModelMixin, 

-

                    GenericAPIView): 

-

 

-

    """ 

-

    Concrete view for updating a model instance. 

-

    """ 

-

    def put(self, request, *args, **kwargs): 

-

        return self.update(request, *args, **kwargs) 

-

 

-

    def patch(self, request, *args, **kwargs): 

-

        return self.partial_update(request, *args, **kwargs) 

-

 

-

 

-

class ListCreateAPIView(mixins.ListModelMixin, 

-

                        mixins.CreateModelMixin, 

-

                        GenericAPIView): 

-

    """ 

-

    Concrete view for listing a queryset or creating a model instance. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.list(request, *args, **kwargs) 

-

 

-

    def post(self, request, *args, **kwargs): 

-

        return self.create(request, *args, **kwargs) 

-

 

-

 

-

class RetrieveUpdateAPIView(mixins.RetrieveModelMixin, 

-

                            mixins.UpdateModelMixin, 

-

                            GenericAPIView): 

-

    """ 

-

    Concrete view for retrieving, updating a model instance. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.retrieve(request, *args, **kwargs) 

-

 

-

    def put(self, request, *args, **kwargs): 

-

        return self.update(request, *args, **kwargs) 

-

 

-

    def patch(self, request, *args, **kwargs): 

-

        return self.partial_update(request, *args, **kwargs) 

-

 

-

 

-

class RetrieveDestroyAPIView(mixins.RetrieveModelMixin, 

-

                             mixins.DestroyModelMixin, 

-

                             GenericAPIView): 

-

    """ 

-

    Concrete view for retrieving or deleting a model instance. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.retrieve(request, *args, **kwargs) 

-

 

-

    def delete(self, request, *args, **kwargs): 

-

        return self.destroy(request, *args, **kwargs) 

-

 

-

 

-

class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin, 

-

                                   mixins.UpdateModelMixin, 

-

                                   mixins.DestroyModelMixin, 

-

                                   GenericAPIView): 

-

    """ 

-

    Concrete view for retrieving, updating or deleting a model instance. 

-

    """ 

-

    def get(self, request, *args, **kwargs): 

-

        return self.retrieve(request, *args, **kwargs) 

-

 

-

    def put(self, request, *args, **kwargs): 

-

        return self.update(request, *args, **kwargs) 

-

 

-

    def patch(self, request, *args, **kwargs): 

-

        return self.partial_update(request, *args, **kwargs) 

-

 

-

    def delete(self, request, *args, **kwargs): 

-

        return self.destroy(request, *args, **kwargs) 

-

 

-

 

-

########################## 

-

### Deprecated classes ### 

-

########################## 

-

 

-

class MultipleObjectAPIView(GenericAPIView): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn( 

-

            'Subclassing `MultipleObjectAPIView` is due to be deprecated. ' 

-

            'You should simply subclass `GenericAPIView` instead.', 

-

            PendingDeprecationWarning, stacklevel=2 

-

        ) 

-

        super(MultipleObjectAPIView, self).__init__(*args, **kwargs) 

-

 

-

 

-

class SingleObjectAPIView(GenericAPIView): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn( 

-

            'Subclassing `SingleObjectAPIView` is due to be deprecated. ' 

-

            'You should simply subclass `GenericAPIView` instead.', 

-

            PendingDeprecationWarning, stacklevel=2 

-

        ) 

-

        super(SingleObjectAPIView, self).__init__(*args, **kwargs) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_mixins.html b/htmlcov/rest_framework_mixins.html deleted file mode 100644 index fa62f2ae8..000000000 --- a/htmlcov/rest_framework_mixins.html +++ /dev/null @@ -1,449 +0,0 @@ - - - - - - - - Coverage for rest_framework/mixins: 93% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

- -
-

""" 

-

Basic building blocks for generic class based views. 

-

 

-

We don't bind behaviour to http method handlers yet, 

-

which allows mixin classes to be composed in interesting ways. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from django.http import Http404 

-

from rest_framework import status 

-

from rest_framework.response import Response 

-

from rest_framework.request import clone_request 

-

import warnings 

-

 

-

 

-

def _get_validation_exclusions(obj, pk=None, slug_field=None, lookup_field=None): 

-

    """ 

-

    Given a model instance, and an optional pk and slug field, 

-

    return the full list of all other field names on that model. 

-

 

-

    For use when performing full_clean on a model instance, 

-

    so we only clean the required fields. 

-

    """ 

-

    include = [] 

-

 

-

    if pk: 

-

        # Pending deprecation 

-

        pk_field = obj._meta.pk 

-

        while pk_field.rel: 

-

            pk_field = pk_field.rel.to._meta.pk 

-

        include.append(pk_field.name) 

-

 

-

    if slug_field: 

-

        # Pending deprecation 

-

        include.append(slug_field) 

-

 

-

    if lookup_field and lookup_field != 'pk': 

-

        include.append(lookup_field) 

-

 

-

    return [field.name for field in obj._meta.fields if field.name not in include] 

-

 

-

 

-

class CreateModelMixin(object): 

-

    """ 

-

    Create a model instance. 

-

    """ 

-

    def create(self, request, *args, **kwargs): 

-

        serializer = self.get_serializer(data=request.DATA, files=request.FILES) 

-

 

-

        if serializer.is_valid(): 

-

            self.pre_save(serializer.object) 

-

            self.object = serializer.save(force_insert=True) 

-

            self.post_save(self.object, created=True) 

-

            headers = self.get_success_headers(serializer.data) 

-

            return Response(serializer.data, status=status.HTTP_201_CREATED, 

-

                            headers=headers) 

-

 

-

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

-

 

-

    def get_success_headers(self, data): 

-

        try: 

-

            return {'Location': data['url']} 

-

        except (TypeError, KeyError): 

-

            return {} 

-

 

-

 

-

class ListModelMixin(object): 

-

    """ 

-

    List a queryset. 

-

    """ 

-

    empty_error = "Empty list and '%(class_name)s.allow_empty' is False." 

-

 

-

    def list(self, request, *args, **kwargs): 

-

        self.object_list = self.filter_queryset(self.get_queryset()) 

-

 

-

        # Default is to allow empty querysets.  This can be altered by setting 

-

        # `.allow_empty = False`, to raise 404 errors on empty querysets. 

-

        if not self.allow_empty and not self.object_list: 

-

            warnings.warn( 

-

                'The `allow_empty` parameter is due to be deprecated. ' 

-

                'To use `allow_empty=False` style behavior, You should override ' 

-

                '`get_queryset()` and explicitly raise a 404 on empty querysets.', 

-

                PendingDeprecationWarning 

-

            ) 

-

            class_name = self.__class__.__name__ 

-

            error_msg = self.empty_error % {'class_name': class_name} 

-

            raise Http404(error_msg) 

-

 

-

        # Switch between paginated or standard style responses 

-

        page = self.paginate_queryset(self.object_list) 

-

        if page is not None: 

-

            serializer = self.get_pagination_serializer(page) 

-

        else: 

-

            serializer = self.get_serializer(self.object_list, many=True) 

-

 

-

        return Response(serializer.data) 

-

 

-

 

-

class RetrieveModelMixin(object): 

-

    """ 

-

    Retrieve a model instance. 

-

    """ 

-

    def retrieve(self, request, *args, **kwargs): 

-

        self.object = self.get_object() 

-

        serializer = self.get_serializer(self.object) 

-

        return Response(serializer.data) 

-

 

-

 

-

class UpdateModelMixin(object): 

-

    """ 

-

    Update a model instance. 

-

    """ 

-

    def update(self, request, *args, **kwargs): 

-

        partial = kwargs.pop('partial', False) 

-

        self.object = self.get_object_or_none() 

-

 

-

        if self.object is None: 

-

            created = True 

-

            save_kwargs = {'force_insert': True} 

-

            success_status_code = status.HTTP_201_CREATED 

-

        else: 

-

            created = False 

-

            save_kwargs = {'force_update': True} 

-

            success_status_code = status.HTTP_200_OK 

-

 

-

        serializer = self.get_serializer(self.object, data=request.DATA, 

-

                                         files=request.FILES, partial=partial) 

-

 

-

        if serializer.is_valid(): 

-

            self.pre_save(serializer.object) 

-

            self.object = serializer.save(**save_kwargs) 

-

            self.post_save(self.object, created=created) 

-

            return Response(serializer.data, status=success_status_code) 

-

 

-

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

-

 

-

    def partial_update(self, request, *args, **kwargs): 

-

        kwargs['partial'] = True 

-

        return self.update(request, *args, **kwargs) 

-

 

-

    def get_object_or_none(self): 

-

        try: 

-

            return self.get_object() 

-

        except Http404: 

-

            # If this is a PUT-as-create operation, we need to ensure that 

-

            # we have relevant permissions, as if this was a POST request. 

-

            # This will either raise a PermissionDenied exception, 

-

            # or simply return None 

-

            self.check_permissions(clone_request(self.request, 'POST')) 

-

 

-

    def pre_save(self, obj): 

-

        """ 

-

        Set any attributes on the object that are implicit in the request. 

-

        """ 

-

        # pk and/or slug attributes are implicit in the URL. 

-

        lookup = self.kwargs.get(self.lookup_field, None) 

-

        pk = self.kwargs.get(self.pk_url_kwarg, None) 

-

        slug = self.kwargs.get(self.slug_url_kwarg, None) 

-

        slug_field = slug and self.slug_field or None 

-

 

-

        if lookup: 

-

            setattr(obj, self.lookup_field, lookup) 

-

 

-

        if pk: 

-

            setattr(obj, 'pk', pk) 

-

 

-

        if slug: 

-

            setattr(obj, slug_field, slug) 

-

 

-

        # Ensure we clean the attributes so that we don't eg return integer 

-

        # pk using a string representation, as provided by the url conf kwarg. 

-

        if hasattr(obj, 'full_clean'): 

-

            exclude = _get_validation_exclusions(obj, pk, slug_field, self.lookup_field) 

-

            obj.full_clean(exclude) 

-

 

-

 

-

class DestroyModelMixin(object): 

-

    """ 

-

    Destroy a model instance. 

-

    """ 

-

    def destroy(self, request, *args, **kwargs): 

-

        obj = self.get_object() 

-

        obj.delete() 

-

        return Response(status=status.HTTP_204_NO_CONTENT) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_models.html b/htmlcov/rest_framework_models.html deleted file mode 100644 index 6786c620a..000000000 --- a/htmlcov/rest_framework_models.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - Coverage for rest_framework/models: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

- -
-

# Just to keep things like ./manage.py test happy 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_negotiation.html b/htmlcov/rest_framework_negotiation.html deleted file mode 100644 index 7ed526c97..000000000 --- a/htmlcov/rest_framework_negotiation.html +++ /dev/null @@ -1,259 +0,0 @@ - - - - - - - - Coverage for rest_framework/negotiation: 90% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

- -
-

""" 

-

Content negotiation deals with selecting an appropriate renderer given the 

-

incoming request.  Typically this will be based on the request's Accept header. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.http import Http404 

-

from rest_framework import exceptions 

-

from rest_framework.settings import api_settings 

-

from rest_framework.utils.mediatypes import order_by_precedence, media_type_matches 

-

from rest_framework.utils.mediatypes import _MediaType 

-

 

-

 

-

class BaseContentNegotiation(object): 

-

    def select_parser(self, request, parsers): 

-

        raise NotImplementedError('.select_parser() must be implemented') 

-

 

-

    def select_renderer(self, request, renderers, format_suffix=None): 

-

        raise NotImplementedError('.select_renderer() must be implemented') 

-

 

-

 

-

class DefaultContentNegotiation(BaseContentNegotiation): 

-

    settings = api_settings 

-

 

-

    def select_parser(self, request, parsers): 

-

        """ 

-

        Given a list of parsers and a media type, return the appropriate 

-

        parser to handle the incoming request. 

-

        """ 

-

        for parser in parsers: 

-

            if media_type_matches(parser.media_type, request.content_type): 

-

                return parser 

-

        return None 

-

 

-

    def select_renderer(self, request, renderers, format_suffix=None): 

-

        """ 

-

        Given a request and a list of renderers, return a two-tuple of: 

-

        (renderer, media type). 

-

        """ 

-

        # Allow URL style format override.  eg. "?format=json 

-

        format_query_param = self.settings.URL_FORMAT_OVERRIDE 

-

        format = format_suffix or request.QUERY_PARAMS.get(format_query_param) 

-

 

-

        if format: 

-

            renderers = self.filter_renderers(renderers, format) 

-

 

-

        accepts = self.get_accept_list(request) 

-

 

-

        # Check the acceptable media types against each renderer, 

-

        # attempting more specific media types first 

-

        # NB. The inner loop here isn't as bad as it first looks :) 

-

        #     Worst case is we're looping over len(accept_list) * len(self.renderers) 

-

        for media_type_set in order_by_precedence(accepts): 

-

            for renderer in renderers: 

-

                for media_type in media_type_set: 

-

                    if media_type_matches(renderer.media_type, media_type): 

-

                        # Return the most specific media type as accepted. 

-

                        if (_MediaType(renderer.media_type).precedence > 

-

                            _MediaType(media_type).precedence): 

-

                            # Eg client requests '*/*' 

-

                            # Accepted media type is 'application/json' 

-

                            return renderer, renderer.media_type 

-

                        else: 

-

                            # Eg client requests 'application/json; indent=8' 

-

                            # Accepted media type is 'application/json; indent=8' 

-

                            return renderer, media_type 

-

 

-

        raise exceptions.NotAcceptable(available_renderers=renderers) 

-

 

-

    def filter_renderers(self, renderers, format): 

-

        """ 

-

        If there is a '.json' style format suffix, filter the renderers 

-

        so that we only negotiation against those that accept that format. 

-

        """ 

-

        renderers = [renderer for renderer in renderers 

-

                     if renderer.format == format] 

-

        if not renderers: 

-

            raise Http404 

-

        return renderers 

-

 

-

    def get_accept_list(self, request): 

-

        """ 

-

        Given the incoming request, return a tokenised list of media 

-

        type strings. 

-

 

-

        Allows URL style accept override.  eg. "?accept=application/json" 

-

        """ 

-

        header = request.META.get('HTTP_ACCEPT', '*/*') 

-

        header = request.QUERY_PARAMS.get(self.settings.URL_ACCEPT_OVERRIDE, header) 

-

        return [token.strip() for token in header.split(',')] 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_pagination.html b/htmlcov/rest_framework_pagination.html deleted file mode 100644 index 5a3f76d82..000000000 --- a/htmlcov/rest_framework_pagination.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - Coverage for rest_framework/pagination: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

- -
-

""" 

-

Pagination serializers determine the structure of the output that should 

-

be used for paginated responses. 

-

""" 

-

from __future__ import unicode_literals 

-

from rest_framework import serializers 

-

from rest_framework.templatetags.rest_framework import replace_query_param 

-

 

-

 

-

class NextPageField(serializers.Field): 

-

    """ 

-

    Field that returns a link to the next page in paginated results. 

-

    """ 

-

    page_field = 'page' 

-

 

-

    def to_native(self, value): 

-

        if not value.has_next(): 

-

            return None 

-

        page = value.next_page_number() 

-

        request = self.context.get('request') 

-

        url = request and request.build_absolute_uri() or '' 

-

        return replace_query_param(url, self.page_field, page) 

-

 

-

 

-

class PreviousPageField(serializers.Field): 

-

    """ 

-

    Field that returns a link to the previous page in paginated results. 

-

    """ 

-

    page_field = 'page' 

-

 

-

    def to_native(self, value): 

-

        if not value.has_previous(): 

-

            return None 

-

        page = value.previous_page_number() 

-

        request = self.context.get('request') 

-

        url = request and request.build_absolute_uri() or '' 

-

        return replace_query_param(url, self.page_field, page) 

-

 

-

 

-

class DefaultObjectSerializer(serializers.Field): 

-

    """ 

-

    If no object serializer is specified, then this serializer will be applied 

-

    as the default. 

-

    """ 

-

 

-

    def __init__(self, source=None, context=None): 

-

        # Note: Swallow context kwarg - only required for eg. ModelSerializer. 

-

        super(DefaultObjectSerializer, self).__init__(source=source) 

-

 

-

 

-

class PaginationSerializerOptions(serializers.SerializerOptions): 

-

    """ 

-

    An object that stores the options that may be provided to a 

-

    pagination serializer by using the inner `Meta` class. 

-

 

-

    Accessible on the instance as `serializer.opts`. 

-

    """ 

-

    def __init__(self, meta): 

-

        super(PaginationSerializerOptions, self).__init__(meta) 

-

        self.object_serializer_class = getattr(meta, 'object_serializer_class', 

-

                                               DefaultObjectSerializer) 

-

 

-

 

-

class BasePaginationSerializer(serializers.Serializer): 

-

    """ 

-

    A base class for pagination serializers to inherit from, 

-

    to make implementing custom serializers more easy. 

-

    """ 

-

    _options_class = PaginationSerializerOptions 

-

    results_field = 'results' 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        """ 

-

        Override init to add in the object serializer field on-the-fly. 

-

        """ 

-

        super(BasePaginationSerializer, self).__init__(*args, **kwargs) 

-

        results_field = self.results_field 

-

        object_serializer = self.opts.object_serializer_class 

-

 

-

        if 'context' in kwargs: 

-

            context_kwarg = {'context': kwargs['context']} 

-

        else: 

-

            context_kwarg = {} 

-

 

-

        self.fields[results_field] = object_serializer(source='object_list', **context_kwarg) 

-

 

-

 

-

class PaginationSerializer(BasePaginationSerializer): 

-

    """ 

-

    A default implementation of a pagination serializer. 

-

    """ 

-

    count = serializers.Field(source='paginator.count') 

-

    next = NextPageField(source='*') 

-

    previous = PreviousPageField(source='*') 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_parsers.html b/htmlcov/rest_framework_parsers.html deleted file mode 100644 index 92f1db62d..000000000 --- a/htmlcov/rest_framework_parsers.html +++ /dev/null @@ -1,671 +0,0 @@ - - - - - - - - Coverage for rest_framework/parsers: 92% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

- -
-

""" 

-

Parsers are used to parse the content of incoming HTTP requests. 

-

 

-

They give us a generic way of being able to handle various media types 

-

on the request, such as form content or json encoded data. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.conf import settings 

-

from django.core.files.uploadhandler import StopFutureHandlers 

-

from django.http import QueryDict 

-

from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser 

-

from django.http.multipartparser import MultiPartParserError, parse_header, ChunkIter 

-

from rest_framework.compat import yaml, etree 

-

from rest_framework.exceptions import ParseError 

-

from rest_framework.compat import six 

-

import json 

-

import datetime 

-

import decimal 

-

 

-

 

-

class DataAndFiles(object): 

-

    def __init__(self, data, files): 

-

        self.data = data 

-

        self.files = files 

-

 

-

 

-

class BaseParser(object): 

-

    """ 

-

    All parsers should extend `BaseParser`, specifying a `media_type` 

-

    attribute, and overriding the `.parse()` method. 

-

    """ 

-

 

-

    media_type = None 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Given a stream to read from, return the parsed representation. 

-

        Should return parsed data, or a `DataAndFiles` object consisting of the 

-

        parsed data and files. 

-

        """ 

-

        raise NotImplementedError(".parse() must be overridden.") 

-

 

-

 

-

class JSONParser(BaseParser): 

-

    """ 

-

    Parses JSON-serialized data. 

-

    """ 

-

 

-

    media_type = 'application/json' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Returns a 2-tuple of `(data, files)`. 

-

 

-

        `data` will be an object which is the parsed content of the response. 

-

        `files` will always be `None`. 

-

        """ 

-

        parser_context = parser_context or {} 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

 

-

        try: 

-

            data = stream.read().decode(encoding) 

-

            return json.loads(data) 

-

        except ValueError as exc: 

-

            raise ParseError('JSON parse error - %s' % six.text_type(exc)) 

-

 

-

 

-

class YAMLParser(BaseParser): 

-

    """ 

-

    Parses YAML-serialized data. 

-

    """ 

-

 

-

    media_type = 'application/yaml' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Returns a 2-tuple of `(data, files)`. 

-

 

-

        `data` will be an object which is the parsed content of the response. 

-

        `files` will always be `None`. 

-

        """ 

-

        assert yaml, 'YAMLParser requires pyyaml to be installed' 

-

 

-

        parser_context = parser_context or {} 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

 

-

        try: 

-

            data = stream.read().decode(encoding) 

-

            return yaml.safe_load(data) 

-

        except (ValueError, yaml.parser.ParserError) as exc: 

-

            raise ParseError('YAML parse error - %s' % six.u(exc)) 

-

 

-

 

-

class FormParser(BaseParser): 

-

    """ 

-

    Parser for form data. 

-

    """ 

-

 

-

    media_type = 'application/x-www-form-urlencoded' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Returns a 2-tuple of `(data, files)`. 

-

 

-

        `data` will be a :class:`QueryDict` containing all the form parameters. 

-

        `files` will always be :const:`None`. 

-

        """ 

-

        parser_context = parser_context or {} 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

        data = QueryDict(stream.read(), encoding=encoding) 

-

        return data 

-

 

-

 

-

class MultiPartParser(BaseParser): 

-

    """ 

-

    Parser for multipart form data, which may include file data. 

-

    """ 

-

 

-

    media_type = 'multipart/form-data' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Returns a DataAndFiles object. 

-

 

-

        `.data` will be a `QueryDict` containing all the form parameters. 

-

        `.files` will be a `QueryDict` containing all the form files. 

-

        """ 

-

        parser_context = parser_context or {} 

-

        request = parser_context['request'] 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

        meta = request.META 

-

        upload_handlers = request.upload_handlers 

-

 

-

        try: 

-

            parser = DjangoMultiPartParser(meta, stream, upload_handlers, encoding) 

-

            data, files = parser.parse() 

-

            return DataAndFiles(data, files) 

-

        except MultiPartParserError as exc: 

-

            raise ParseError('Multipart form parse error - %s' % six.u(exc)) 

-

 

-

 

-

class XMLParser(BaseParser): 

-

    """ 

-

    XML parser. 

-

    """ 

-

 

-

    media_type = 'application/xml' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        assert etree, 'XMLParser requires defusedxml to be installed' 

-

 

-

        parser_context = parser_context or {} 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

        parser = etree.DefusedXMLParser(encoding=encoding) 

-

        try: 

-

            tree = etree.parse(stream, parser=parser, forbid_dtd=True) 

-

        except (etree.ParseError, ValueError) as exc: 

-

            raise ParseError('XML parse error - %s' % six.u(exc)) 

-

        data = self._xml_convert(tree.getroot()) 

-

 

-

        return data 

-

 

-

    def _xml_convert(self, element): 

-

        """ 

-

        convert the xml `element` into the corresponding python object 

-

        """ 

-

 

-

        children = list(element) 

-

 

-

        if len(children) == 0: 

-

            return self._type_convert(element.text) 

-

        else: 

-

            # if the fist child tag is list-item means all children are list-item 

-

            if children[0].tag == "list-item": 

-

                data = [] 

-

                for child in children: 

-

                    data.append(self._xml_convert(child)) 

-

            else: 

-

                data = {} 

-

                for child in children: 

-

                    data[child.tag] = self._xml_convert(child) 

-

 

-

            return data 

-

 

-

    def _type_convert(self, value): 

-

        """ 

-

        Converts the value returned by the XMl parse into the equivalent 

-

        Python type 

-

        """ 

-

        if value is None: 

-

            return value 

-

 

-

        try: 

-

            return datetime.datetime.strptime(value, '%Y-%m-%d %H:%M:%S') 

-

        except ValueError: 

-

            pass 

-

 

-

        try: 

-

            return int(value) 

-

        except ValueError: 

-

            pass 

-

 

-

        try: 

-

            return decimal.Decimal(value) 

-

        except decimal.InvalidOperation: 

-

            pass 

-

 

-

        return value 

-

 

-

 

-

class FileUploadParser(BaseParser): 

-

    """ 

-

    Parser for file upload data. 

-

    """ 

-

    media_type = '*/*' 

-

 

-

    def parse(self, stream, media_type=None, parser_context=None): 

-

        """ 

-

        Returns a DataAndFiles object. 

-

 

-

        `.data` will be None (we expect request body to be a file content). 

-

        `.files` will be a `QueryDict` containing one 'file' element. 

-

        """ 

-

 

-

        parser_context = parser_context or {} 

-

        request = parser_context['request'] 

-

        encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET) 

-

        meta = request.META 

-

        upload_handlers = request.upload_handlers 

-

        filename = self.get_filename(stream, media_type, parser_context) 

-

 

-

        # Note that this code is extracted from Django's handling of 

-

        # file uploads in MultiPartParser. 

-

        content_type = meta.get('HTTP_CONTENT_TYPE', 

-

                                meta.get('CONTENT_TYPE', '')) 

-

        try: 

-

            content_length = int(meta.get('HTTP_CONTENT_LENGTH', 

-

                                          meta.get('CONTENT_LENGTH', 0))) 

-

        except (ValueError, TypeError): 

-

            content_length = None 

-

 

-

        # See if the handler will want to take care of the parsing. 

-

        for handler in upload_handlers: 

-

            result = handler.handle_raw_input(None, 

-

                                              meta, 

-

                                              content_length, 

-

                                              None, 

-

                                              encoding) 

-

            if result is not None: 

-

                return DataAndFiles(None, {'file': result[1]}) 

-

 

-

        # This is the standard case. 

-

        possible_sizes = [x.chunk_size for x in upload_handlers if x.chunk_size] 

-

        chunk_size = min([2 ** 31 - 4] + possible_sizes) 

-

        chunks = ChunkIter(stream, chunk_size) 

-

        counters = [0] * len(upload_handlers) 

-

 

-

        for handler in upload_handlers: 

-

            try: 

-

                handler.new_file(None, filename, content_type, 

-

                                 content_length, encoding) 

-

            except StopFutureHandlers: 

-

                break 

-

 

-

        for chunk in chunks: 

-

            for i, handler in enumerate(upload_handlers): 

-

                chunk_length = len(chunk) 

-

                chunk = handler.receive_data_chunk(chunk, counters[i]) 

-

                counters[i] += chunk_length 

-

                if chunk is None: 

-

                    break 

-

 

-

        for i, handler in enumerate(upload_handlers): 

-

            file_obj = handler.file_complete(counters[i]) 

-

            if file_obj: 

-

                return DataAndFiles(None, {'file': file_obj}) 

-

        raise ParseError("FileUpload parse error - " 

-

                         "none of upload handlers can handle the stream") 

-

 

-

    def get_filename(self, stream, media_type, parser_context): 

-

        """ 

-

        Detects the uploaded file name. First searches a 'filename' url kwarg. 

-

        Then tries to parse Content-Disposition header. 

-

        """ 

-

        try: 

-

            return parser_context['kwargs']['filename'] 

-

        except KeyError: 

-

            pass 

-

 

-

        try: 

-

            meta = parser_context['request'].META 

-

            disposition = parse_header(meta['HTTP_CONTENT_DISPOSITION']) 

-

            return disposition[1]['filename'] 

-

        except (AttributeError, KeyError): 

-

            pass 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_permissions.html b/htmlcov/rest_framework_permissions.html deleted file mode 100644 index 20a29522b..000000000 --- a/htmlcov/rest_framework_permissions.html +++ /dev/null @@ -1,429 +0,0 @@ - - - - - - - - Coverage for rest_framework/permissions: 81% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

- -
-

""" 

-

Provides a set of pluggable permission policies. 

-

""" 

-

from __future__ import unicode_literals 

-

import inspect 

-

import warnings 

-

 

-

SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS'] 

-

 

-

from rest_framework.compat import oauth2_provider_scope, oauth2_constants 

-

 

-

 

-

class BasePermission(object): 

-

    """ 

-

    A base class from which all permission classes should inherit. 

-

    """ 

-

 

-

    def has_permission(self, request, view): 

-

        """ 

-

        Return `True` if permission is granted, `False` otherwise. 

-

        """ 

-

        return True 

-

 

-

    def has_object_permission(self, request, view, obj): 

-

        """ 

-

        Return `True` if permission is granted, `False` otherwise. 

-

        """ 

-

        if len(inspect.getargspec(self.has_permission).args) == 4: 

-

            warnings.warn( 

-

                'The `obj` argument in `has_permission` is deprecated. ' 

-

                'Use `has_object_permission()` instead for object permissions.', 

-

                DeprecationWarning, stacklevel=2 

-

            ) 

-

            return self.has_permission(request, view, obj) 

-

        return True 

-

 

-

 

-

class AllowAny(BasePermission): 

-

    """ 

-

    Allow any access. 

-

    This isn't strictly required, since you could use an empty 

-

    permission_classes list, but it's useful because it makes the intention 

-

    more explicit. 

-

    """ 

-

    def has_permission(self, request, view): 

-

        return True 

-

 

-

 

-

class IsAuthenticated(BasePermission): 

-

    """ 

-

    Allows access only to authenticated users. 

-

    """ 

-

 

-

    def has_permission(self, request, view): 

-

        if request.user and request.user.is_authenticated(): 

-

            return True 

-

        return False 

-

 

-

 

-

class IsAdminUser(BasePermission): 

-

    """ 

-

    Allows access only to admin users. 

-

    """ 

-

 

-

    def has_permission(self, request, view): 

-

        if request.user and request.user.is_staff: 

-

            return True 

-

        return False 

-

 

-

 

-

class IsAuthenticatedOrReadOnly(BasePermission): 

-

    """ 

-

    The request is authenticated as a user, or is a read-only request. 

-

    """ 

-

 

-

    def has_permission(self, request, view): 

-

        if (request.method in SAFE_METHODS or 

-

            request.user and 

-

            request.user.is_authenticated()): 

-

            return True 

-

        return False 

-

 

-

 

-

class DjangoModelPermissions(BasePermission): 

-

    """ 

-

    The request is authenticated using `django.contrib.auth` permissions. 

-

    See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions 

-

 

-

    It ensures that the user is authenticated, and has the appropriate 

-

    `add`/`change`/`delete` permissions on the model. 

-

 

-

    This permission can only be applied against view classes that 

-

    provide a `.model` or `.queryset` attribute. 

-

    """ 

-

 

-

    # Map methods into required permission codes. 

-

    # Override this if you need to also provide 'view' permissions, 

-

    # or if you want to provide custom permission codes. 

-

    perms_map = { 

-

        'GET': [], 

-

        'OPTIONS': [], 

-

        'HEAD': [], 

-

        'POST': ['%(app_label)s.add_%(model_name)s'], 

-

        'PUT': ['%(app_label)s.change_%(model_name)s'], 

-

        'PATCH': ['%(app_label)s.change_%(model_name)s'], 

-

        'DELETE': ['%(app_label)s.delete_%(model_name)s'], 

-

    } 

-

 

-

    authenticated_users_only = True 

-

 

-

    def get_required_permissions(self, method, model_cls): 

-

        """ 

-

        Given a model and an HTTP method, return the list of permission 

-

        codes that the user is required to have. 

-

        """ 

-

        kwargs = { 

-

            'app_label': model_cls._meta.app_label, 

-

            'model_name': model_cls._meta.module_name 

-

        } 

-

        return [perm % kwargs for perm in self.perms_map[method]] 

-

 

-

    def has_permission(self, request, view): 

-

        model_cls = getattr(view, 'model', None) 

-

        queryset = getattr(view, 'queryset', None) 

-

 

-

        if model_cls is None and queryset is not None: 

-

            model_cls = queryset.model 

-

 

-

        # Workaround to ensure DjangoModelPermissions are not applied 

-

        # to the root view when using DefaultRouter. 

-

        if model_cls is None and getattr(view, '_ignore_model_permissions', False): 

-

            return True 

-

 

-

        assert model_cls, ('Cannot apply DjangoModelPermissions on a view that' 

-

                           ' does not have `.model` or `.queryset` property.') 

-

 

-

        perms = self.get_required_permissions(request.method, model_cls) 

-

 

-

        if (request.user and 

-

            (request.user.is_authenticated() or not self.authenticated_users_only) and 

-

            request.user.has_perms(perms)): 

-

            return True 

-

        return False 

-

 

-

 

-

class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions): 

-

    """ 

-

    Similar to DjangoModelPermissions, except that anonymous users are 

-

    allowed read-only access. 

-

    """ 

-

    authenticated_users_only = False 

-

 

-

 

-

class TokenHasReadWriteScope(BasePermission): 

-

    """ 

-

    The request is authenticated as a user and the token used has the right scope 

-

    """ 

-

 

-

    def has_permission(self, request, view): 

-

        token = request.auth 

-

        read_only = request.method in SAFE_METHODS 

-

 

-

        if not token: 

-

            return False 

-

 

-

        if hasattr(token, 'resource'):  # OAuth 1 

-

            return read_only or not request.auth.resource.is_readonly 

-

        elif hasattr(token, 'scope'):  # OAuth 2 

-

            required = oauth2_constants.READ if read_only else oauth2_constants.WRITE 

-

            return oauth2_provider_scope.check(required, request.auth.scope) 

-

 

-

        assert False, ('TokenHasReadWriteScope requires either the' 

-

        '`OAuthAuthentication` or `OAuth2Authentication` authentication ' 

-

        'class to be used.') 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_relations.html b/htmlcov/rest_framework_relations.html deleted file mode 100644 index 29ad3cf65..000000000 --- a/htmlcov/rest_framework_relations.html +++ /dev/null @@ -1,1347 +0,0 @@ - - - - - - - - Coverage for rest_framework/relations: 76% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

-

370

-

371

-

372

-

373

-

374

-

375

-

376

-

377

-

378

-

379

-

380

-

381

-

382

-

383

-

384

-

385

-

386

-

387

-

388

-

389

-

390

-

391

-

392

-

393

-

394

-

395

-

396

-

397

-

398

-

399

-

400

-

401

-

402

-

403

-

404

-

405

-

406

-

407

-

408

-

409

-

410

-

411

-

412

-

413

-

414

-

415

-

416

-

417

-

418

-

419

-

420

-

421

-

422

-

423

-

424

-

425

-

426

-

427

-

428

-

429

-

430

-

431

-

432

-

433

-

434

-

435

-

436

-

437

-

438

-

439

-

440

-

441

-

442

-

443

-

444

-

445

-

446

-

447

-

448

-

449

-

450

-

451

-

452

-

453

-

454

-

455

-

456

-

457

-

458

-

459

-

460

-

461

-

462

-

463

-

464

-

465

-

466

-

467

-

468

-

469

-

470

-

471

-

472

-

473

-

474

-

475

-

476

-

477

-

478

-

479

-

480

-

481

-

482

-

483

-

484

-

485

-

486

-

487

-

488

-

489

-

490

-

491

-

492

-

493

-

494

-

495

-

496

-

497

-

498

-

499

-

500

-

501

-

502

-

503

-

504

-

505

-

506

-

507

-

508

-

509

-

510

-

511

-

512

-

513

-

514

-

515

-

516

-

517

-

518

-

519

-

520

-

521

-

522

-

523

-

524

-

525

-

526

-

527

-

528

-

529

-

530

-

531

-

532

-

533

-

534

-

535

-

536

-

537

-

538

-

539

-

540

-

541

-

542

-

543

-

544

-

545

-

546

-

547

-

548

-

549

-

550

-

551

-

552

-

553

-

554

-

555

-

556

-

557

-

558

-

559

-

560

-

561

-

562

-

563

-

564

-

565

-

566

-

567

-

568

-

569

-

570

-

571

-

572

-

573

-

574

-

575

-

576

-

577

-

578

-

579

-

580

-

581

-

582

-

583

-

584

-

585

-

586

-

587

-

588

-

589

-

590

-

591

-

592

-

593

-

594

-

595

-

596

-

597

-

598

-

599

-

600

-

601

-

602

-

603

-

604

-

605

-

606

-

607

-

608

-

609

-

610

-

611

-

612

-

613

-

614

-

615

-

616

-

617

-

618

-

619

-

620

-

621

-

622

-

623

-

624

-

625

-

626

-

627

-

628

-

629

-

630

-

631

-

632

-

633

- -
-

""" 

-

Serializer fields that deal with relationships. 

-

 

-

These fields allow you to specify the style that should be used to represent 

-

model relationships, including hyperlinks, primary keys, or slugs. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.core.exceptions import ObjectDoesNotExist, ValidationError 

-

from django.core.urlresolvers import resolve, get_script_prefix, NoReverseMatch 

-

from django import forms 

-

from django.db.models.fields import BLANK_CHOICE_DASH 

-

from django.forms import widgets 

-

from django.forms.models import ModelChoiceIterator 

-

from django.utils.translation import ugettext_lazy as _ 

-

from rest_framework.fields import Field, WritableField, get_component, is_simple_callable 

-

from rest_framework.reverse import reverse 

-

from rest_framework.compat import urlparse 

-

from rest_framework.compat import smart_text 

-

import warnings 

-

 

-

 

-

##### Relational fields ##### 

-

 

-

 

-

# Not actually Writable, but subclasses may need to be. 

-

class RelatedField(WritableField): 

-

    """ 

-

    Base class for related model fields. 

-

 

-

    This represents a relationship using the unicode representation of the target. 

-

    """ 

-

    widget = widgets.Select 

-

    many_widget = widgets.SelectMultiple 

-

    form_field_class = forms.ChoiceField 

-

    many_form_field_class = forms.MultipleChoiceField 

-

 

-

    cache_choices = False 

-

    empty_label = None 

-

    read_only = True 

-

    many = False 

-

 

-

    def __init__(self, *args, **kwargs): 

-

 

-

        # 'null' is to be deprecated in favor of 'required' 

-

        if 'null' in kwargs: 

-

            warnings.warn('The `null` keyword argument is deprecated. ' 

-

                          'Use the `required` keyword argument instead.', 

-

                          DeprecationWarning, stacklevel=2) 

-

            kwargs['required'] = not kwargs.pop('null') 

-

 

-

        queryset = kwargs.pop('queryset', None) 

-

        self.many = kwargs.pop('many', self.many) 

-

        if self.many: 

-

            self.widget = self.many_widget 

-

            self.form_field_class = self.many_form_field_class 

-

 

-

        kwargs['read_only'] = kwargs.pop('read_only', self.read_only) 

-

        super(RelatedField, self).__init__(*args, **kwargs) 

-

 

-

        if not self.required: 

-

            self.empty_label = BLANK_CHOICE_DASH[0][1] 

-

 

-

        self.queryset = queryset 

-

 

-

    def initialize(self, parent, field_name): 

-

        super(RelatedField, self).initialize(parent, field_name) 

-

        if self.queryset is None and not self.read_only: 

-

            try: 

-

                manager = getattr(self.parent.opts.model, self.source or field_name) 

-

                if hasattr(manager, 'related'):  # Forward 

-

                    self.queryset = manager.related.model._default_manager.all() 

-

                else:  # Reverse 

-

                    self.queryset = manager.field.rel.to._default_manager.all() 

-

            except Exception: 

-

                msg = ('Serializer related fields must include a `queryset`' + 

-

                       ' argument or set `read_only=True') 

-

                raise Exception(msg) 

-

 

-

    ### We need this stuff to make form choices work... 

-

 

-

    def prepare_value(self, obj): 

-

        return self.to_native(obj) 

-

 

-

    def label_from_instance(self, obj): 

-

        """ 

-

        Return a readable representation for use with eg. select widgets. 

-

        """ 

-

        desc = smart_text(obj) 

-

        ident = smart_text(self.to_native(obj)) 

-

        if desc == ident: 

-

            return desc 

-

        return "%s - %s" % (desc, ident) 

-

 

-

    def _get_queryset(self): 

-

        return self._queryset 

-

 

-

    def _set_queryset(self, queryset): 

-

        self._queryset = queryset 

-

        self.widget.choices = self.choices 

-

 

-

    queryset = property(_get_queryset, _set_queryset) 

-

 

-

    def _get_choices(self): 

-

        # If self._choices is set, then somebody must have manually set 

-

        # the property self.choices. In this case, just return self._choices. 

-

        if hasattr(self, '_choices'): 

-

            return self._choices 

-

 

-

        # Otherwise, execute the QuerySet in self.queryset to determine the 

-

        # choices dynamically. Return a fresh ModelChoiceIterator that has not been 

-

        # consumed. Note that we're instantiating a new ModelChoiceIterator *each* 

-

        # time _get_choices() is called (and, thus, each time self.choices is 

-

        # accessed) so that we can ensure the QuerySet has not been consumed. This 

-

        # construct might look complicated but it allows for lazy evaluation of 

-

        # the queryset. 

-

        return ModelChoiceIterator(self) 

-

 

-

    def _set_choices(self, value): 

-

        # Setting choices also sets the choices on the widget. 

-

        # choices can be any iterable, but we call list() on it because 

-

        # it will be consumed more than once. 

-

        self._choices = self.widget.choices = list(value) 

-

 

-

    choices = property(_get_choices, _set_choices) 

-

 

-

    ### Regular serializer stuff... 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        try: 

-

            if self.source == '*': 

-

                return self.to_native(obj) 

-

 

-

            source = self.source or field_name 

-

            value = obj 

-

 

-

            for component in source.split('.'): 

-

                value = get_component(value, component) 

-

                if value is None: 

-

                    break 

-

        except ObjectDoesNotExist: 

-

            return None 

-

 

-

        if value is None: 

-

            return None 

-

 

-

        if self.many: 

-

            if is_simple_callable(getattr(value, 'all', None)): 

-

                return [self.to_native(item) for item in value.all()] 

-

            else: 

-

                # Also support non-queryset iterables. 

-

                # This allows us to also support plain lists of related items. 

-

                return [self.to_native(item) for item in value] 

-

        return self.to_native(value) 

-

 

-

    def field_from_native(self, data, files, field_name, into): 

-

        if self.read_only: 

-

            return 

-

 

-

        try: 

-

            if self.many: 

-

                try: 

-

                    # Form data 

-

                    value = data.getlist(field_name) 

-

                    if value == [''] or value == []: 

-

                        raise KeyError 

-

                except AttributeError: 

-

                    # Non-form data 

-

                    value = data[field_name] 

-

            else: 

-

                value = data[field_name] 

-

        except KeyError: 

-

            if self.partial: 

-

                return 

-

            value = [] if self.many else None 

-

 

-

        if value in (None, '') and self.required: 

-

            raise ValidationError(self.error_messages['required']) 

-

        elif value in (None, ''): 

-

            into[(self.source or field_name)] = None 

-

        elif self.many: 

-

            into[(self.source or field_name)] = [self.from_native(item) for item in value] 

-

        else: 

-

            into[(self.source or field_name)] = self.from_native(value) 

-

 

-

 

-

### PrimaryKey relationships 

-

 

-

class PrimaryKeyRelatedField(RelatedField): 

-

    """ 

-

    Represents a relationship as a pk value. 

-

    """ 

-

    read_only = False 

-

 

-

    default_error_messages = { 

-

        'does_not_exist': _("Invalid pk '%s' - object does not exist."), 

-

        'incorrect_type': _('Incorrect type.  Expected pk value, received %s.'), 

-

    } 

-

 

-

    # TODO: Remove these field hacks... 

-

    def prepare_value(self, obj): 

-

        return self.to_native(obj.pk) 

-

 

-

    def label_from_instance(self, obj): 

-

        """ 

-

        Return a readable representation for use with eg. select widgets. 

-

        """ 

-

        desc = smart_text(obj) 

-

        ident = smart_text(self.to_native(obj.pk)) 

-

        if desc == ident: 

-

            return desc 

-

        return "%s - %s" % (desc, ident) 

-

 

-

    # TODO: Possibly change this to just take `obj`, through prob less performant 

-

    def to_native(self, pk): 

-

        return pk 

-

 

-

    def from_native(self, data): 

-

        if self.queryset is None: 

-

            raise Exception('Writable related fields must include a `queryset` argument') 

-

 

-

        try: 

-

            return self.queryset.get(pk=data) 

-

        except ObjectDoesNotExist: 

-

            msg = self.error_messages['does_not_exist'] % smart_text(data) 

-

            raise ValidationError(msg) 

-

        except (TypeError, ValueError): 

-

            received = type(data).__name__ 

-

            msg = self.error_messages['incorrect_type'] % received 

-

            raise ValidationError(msg) 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        if self.many: 

-

            # To-many relationship 

-

 

-

            queryset = None 

-

            if not self.source: 

-

                # Prefer obj.serializable_value for performance reasons 

-

                try: 

-

                    queryset = obj.serializable_value(field_name) 

-

                except AttributeError: 

-

                    pass 

-

            if queryset is None: 

-

                # RelatedManager (reverse relationship) 

-

                source = self.source or field_name 

-

                queryset = obj 

-

                for component in source.split('.'): 

-

                    queryset = get_component(queryset, component) 

-

 

-

            # Forward relationship 

-

            if is_simple_callable(getattr(queryset, 'all', None)): 

-

                return [self.to_native(item.pk) for item in queryset.all()] 

-

            else: 

-

                # Also support non-queryset iterables. 

-

                # This allows us to also support plain lists of related items. 

-

                return [self.to_native(item.pk) for item in queryset] 

-

 

-

        # To-one relationship 

-

        try: 

-

            # Prefer obj.serializable_value for performance reasons 

-

            pk = obj.serializable_value(self.source or field_name) 

-

        except AttributeError: 

-

            # RelatedObject (reverse relationship) 

-

            try: 

-

                pk = getattr(obj, self.source or field_name).pk 

-

            except ObjectDoesNotExist: 

-

                return None 

-

 

-

        # Forward relationship 

-

        return self.to_native(pk) 

-

 

-

 

-

### Slug relationships 

-

 

-

 

-

class SlugRelatedField(RelatedField): 

-

    """ 

-

    Represents a relationship using a unique field on the target. 

-

    """ 

-

    read_only = False 

-

 

-

    default_error_messages = { 

-

        'does_not_exist': _("Object with %s=%s does not exist."), 

-

        'invalid': _('Invalid value.'), 

-

    } 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        self.slug_field = kwargs.pop('slug_field', None) 

-

        assert self.slug_field, 'slug_field is required' 

-

        super(SlugRelatedField, self).__init__(*args, **kwargs) 

-

 

-

    def to_native(self, obj): 

-

        return getattr(obj, self.slug_field) 

-

 

-

    def from_native(self, data): 

-

        if self.queryset is None: 

-

            raise Exception('Writable related fields must include a `queryset` argument') 

-

 

-

        try: 

-

            return self.queryset.get(**{self.slug_field: data}) 

-

        except ObjectDoesNotExist: 

-

            raise ValidationError(self.error_messages['does_not_exist'] % 

-

                                  (self.slug_field, smart_text(data))) 

-

        except (TypeError, ValueError): 

-

            msg = self.error_messages['invalid'] 

-

            raise ValidationError(msg) 

-

 

-

 

-

### Hyperlinked relationships 

-

 

-

class HyperlinkedRelatedField(RelatedField): 

-

    """ 

-

    Represents a relationship using hyperlinking. 

-

    """ 

-

    read_only = False 

-

    lookup_field = 'pk' 

-

 

-

    default_error_messages = { 

-

        'no_match': _('Invalid hyperlink - No URL match'), 

-

        'incorrect_match': _('Invalid hyperlink - Incorrect URL match'), 

-

        'configuration_error': _('Invalid hyperlink due to configuration error'), 

-

        'does_not_exist': _("Invalid hyperlink - object does not exist."), 

-

        'incorrect_type': _('Incorrect type.  Expected url string, received %s.'), 

-

    } 

-

 

-

    # These are all pending deprecation 

-

    pk_url_kwarg = 'pk' 

-

    slug_field = 'slug' 

-

    slug_url_kwarg = None  # Defaults to same as `slug_field` unless overridden 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        try: 

-

            self.view_name = kwargs.pop('view_name') 

-

        except KeyError: 

-

            raise ValueError("Hyperlinked field requires 'view_name' kwarg") 

-

 

-

        self.lookup_field = kwargs.pop('lookup_field', self.lookup_field) 

-

        self.format = kwargs.pop('format', None) 

-

 

-

        # These are pending deprecation 

-

        if 'pk_url_kwarg' in kwargs: 

-

            msg = 'pk_url_kwarg is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

        if 'slug_url_kwarg' in kwargs: 

-

            msg = 'slug_url_kwarg is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

        if 'slug_field' in kwargs: 

-

            msg = 'slug_field is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

 

-

        self.pk_url_kwarg = kwargs.pop('pk_url_kwarg', self.pk_url_kwarg) 

-

        self.slug_field = kwargs.pop('slug_field', self.slug_field) 

-

        default_slug_kwarg = self.slug_url_kwarg or self.slug_field 

-

        self.slug_url_kwarg = kwargs.pop('slug_url_kwarg', default_slug_kwarg) 

-

 

-

        super(HyperlinkedRelatedField, self).__init__(*args, **kwargs) 

-

 

-

    def get_url(self, obj, view_name, request, format): 

-

        """ 

-

        Given an object, return the URL that hyperlinks to the object. 

-

 

-

        May raise a `NoReverseMatch` if the `view_name` and `lookup_field` 

-

        attributes are not configured to correctly match the URL conf. 

-

        """ 

-

        lookup_field = getattr(obj, self.lookup_field) 

-

        kwargs = {self.lookup_field: lookup_field} 

-

        try: 

-

            return reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

        except NoReverseMatch: 

-

            pass 

-

 

-

        if self.pk_url_kwarg != 'pk': 

-

            # Only try pk if it has been explicitly set. 

-

            # Otherwise, the default `lookup_field = 'pk'` has us covered. 

-

            pk = obj.pk 

-

            kwargs = {self.pk_url_kwarg: pk} 

-

            try: 

-

                return reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

            except NoReverseMatch: 

-

                pass 

-

 

-

        slug = getattr(obj, self.slug_field, None) 

-

        if slug is not None: 

-

            # Only try slug if it corresponds to an attribute on the object. 

-

            kwargs = {self.slug_url_kwarg: slug} 

-

            try: 

-

                ret = reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

                if self.slug_field == 'slug' and self.slug_url_kwarg == 'slug': 

-

                    # If the lookup succeeds using the default slug params, 

-

                    # then `slug_field` is being used implicitly, and we 

-

                    # we need to warn about the pending deprecation. 

-

                    msg = 'Implicit slug field hyperlinked fields are pending deprecation.' \ 

-

                          'You should set `lookup_field=slug` on the HyperlinkedRelatedField.' 

-

                    warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

                return ret 

-

            except NoReverseMatch: 

-

                pass 

-

 

-

        raise NoReverseMatch() 

-

 

-

    def get_object(self, queryset, view_name, view_args, view_kwargs): 

-

        """ 

-

        Return the object corresponding to a matched URL. 

-

 

-

        Takes the matched URL conf arguments, and the queryset, and should 

-

        return an object instance, or raise an `ObjectDoesNotExist` exception. 

-

        """ 

-

        lookup = view_kwargs.get(self.lookup_field, None) 

-

        pk = view_kwargs.get(self.pk_url_kwarg, None) 

-

        slug = view_kwargs.get(self.slug_url_kwarg, None) 

-

 

-

        if lookup is not None: 

-

            filter_kwargs = {self.lookup_field: lookup} 

-

        elif pk is not None: 

-

            filter_kwargs = {'pk': pk} 

-

        elif slug is not None: 

-

            filter_kwargs = {self.slug_field: slug} 

-

        else: 

-

            raise ObjectDoesNotExist() 

-

 

-

        return queryset.get(**filter_kwargs) 

-

 

-

    def to_native(self, obj): 

-

        view_name = self.view_name 

-

        request = self.context.get('request', None) 

-

        format = self.format or self.context.get('format', None) 

-

 

-

        if request is None: 

-

            msg = ( 

-

                "Using `HyperlinkedRelatedField` without including the request " 

-

                "in the serializer context is deprecated. " 

-

                "Add `context={'request': request}` when instantiating " 

-

                "the serializer." 

-

            ) 

-

            warnings.warn(msg, DeprecationWarning, stacklevel=4) 

-

 

-

        # If the object has not yet been saved then we cannot hyperlink to it. 

-

        if getattr(obj, 'pk', None) is None: 

-

            return 

-

 

-

        # Return the hyperlink, or error if incorrectly configured. 

-

        try: 

-

            return self.get_url(obj, view_name, request, format) 

-

        except NoReverseMatch: 

-

            msg = ( 

-

                'Could not resolve URL for hyperlinked relationship using ' 

-

                'view name "%s". You may have failed to include the related ' 

-

                'model in your API, or incorrectly configured the ' 

-

                '`lookup_field` attribute on this field.' 

-

            ) 

-

            raise Exception(msg % view_name) 

-

 

-

    def from_native(self, value): 

-

        # Convert URL -> model instance pk 

-

        # TODO: Use values_list 

-

        queryset = self.queryset 

-

        if queryset is None: 

-

            raise Exception('Writable related fields must include a `queryset` argument') 

-

 

-

        try: 

-

            http_prefix = value.startswith(('http:', 'https:')) 

-

        except AttributeError: 

-

            msg = self.error_messages['incorrect_type'] 

-

            raise ValidationError(msg % type(value).__name__) 

-

 

-

        if http_prefix: 

-

            # If needed convert absolute URLs to relative path 

-

            value = urlparse.urlparse(value).path 

-

            prefix = get_script_prefix() 

-

            if value.startswith(prefix): 

-

                value = '/' + value[len(prefix):] 

-

 

-

        try: 

-

            match = resolve(value) 

-

        except Exception: 

-

            raise ValidationError(self.error_messages['no_match']) 

-

 

-

        if match.view_name != self.view_name: 

-

            raise ValidationError(self.error_messages['incorrect_match']) 

-

 

-

        try: 

-

            return self.get_object(queryset, match.view_name, 

-

                                   match.args, match.kwargs) 

-

        except (ObjectDoesNotExist, TypeError, ValueError): 

-

            raise ValidationError(self.error_messages['does_not_exist']) 

-

 

-

 

-

class HyperlinkedIdentityField(Field): 

-

    """ 

-

    Represents the instance, or a property on the instance, using hyperlinking. 

-

    """ 

-

    lookup_field = 'pk' 

-

    read_only = True 

-

 

-

    # These are all pending deprecation 

-

    pk_url_kwarg = 'pk' 

-

    slug_field = 'slug' 

-

    slug_url_kwarg = None  # Defaults to same as `slug_field` unless overridden 

-

 

-

    def __init__(self, *args, **kwargs): 

-

        try: 

-

            self.view_name = kwargs.pop('view_name') 

-

        except KeyError: 

-

            msg = "HyperlinkedIdentityField requires 'view_name' argument" 

-

            raise ValueError(msg) 

-

 

-

        self.format = kwargs.pop('format', None) 

-

        lookup_field = kwargs.pop('lookup_field', None) 

-

        self.lookup_field = lookup_field or self.lookup_field 

-

 

-

        # These are pending deprecation 

-

        if 'pk_url_kwarg' in kwargs: 

-

            msg = 'pk_url_kwarg is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

        if 'slug_url_kwarg' in kwargs: 

-

            msg = 'slug_url_kwarg is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

        if 'slug_field' in kwargs: 

-

            msg = 'slug_field is pending deprecation. Use lookup_field instead.' 

-

            warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) 

-

 

-

        self.slug_field = kwargs.pop('slug_field', self.slug_field) 

-

        default_slug_kwarg = self.slug_url_kwarg or self.slug_field 

-

        self.pk_url_kwarg = kwargs.pop('pk_url_kwarg', self.pk_url_kwarg) 

-

        self.slug_url_kwarg = kwargs.pop('slug_url_kwarg', default_slug_kwarg) 

-

 

-

        super(HyperlinkedIdentityField, self).__init__(*args, **kwargs) 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        request = self.context.get('request', None) 

-

        format = self.context.get('format', None) 

-

        view_name = self.view_name 

-

 

-

        if request is None: 

-

            warnings.warn("Using `HyperlinkedIdentityField` without including the " 

-

                          "request in the serializer context is deprecated. " 

-

                          "Add `context={'request': request}` when instantiating the serializer.", 

-

                          DeprecationWarning, stacklevel=4) 

-

 

-

        # By default use whatever format is given for the current context 

-

        # unless the target is a different type to the source. 

-

        # 

-

        # Eg. Consider a HyperlinkedIdentityField pointing from a json 

-

        # representation to an html property of that representation... 

-

        # 

-

        # '/snippets/1/' should link to '/snippets/1/highlight/' 

-

        # ...but... 

-

        # '/snippets/1/.json' should link to '/snippets/1/highlight/.html' 

-

        if format and self.format and self.format != format: 

-

            format = self.format 

-

 

-

        # Return the hyperlink, or error if incorrectly configured. 

-

        try: 

-

            return self.get_url(obj, view_name, request, format) 

-

        except NoReverseMatch: 

-

            msg = ( 

-

                'Could not resolve URL for hyperlinked relationship using ' 

-

                'view name "%s". You may have failed to include the related ' 

-

                'model in your API, or incorrectly configured the ' 

-

                '`lookup_field` attribute on this field.' 

-

            ) 

-

            raise Exception(msg % view_name) 

-

 

-

    def get_url(self, obj, view_name, request, format): 

-

        """ 

-

        Given an object, return the URL that hyperlinks to the object. 

-

 

-

        May raise a `NoReverseMatch` if the `view_name` and `lookup_field` 

-

        attributes are not configured to correctly match the URL conf. 

-

        """ 

-

        lookup_field = getattr(obj, self.lookup_field) 

-

        kwargs = {self.lookup_field: lookup_field} 

-

        try: 

-

            return reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

        except NoReverseMatch: 

-

            pass 

-

 

-

        if self.pk_url_kwarg != 'pk': 

-

            # Only try pk lookup if it has been explicitly set. 

-

            # Otherwise, the default `lookup_field = 'pk'` has us covered. 

-

            kwargs = {self.pk_url_kwarg: obj.pk} 

-

            try: 

-

                return reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

            except NoReverseMatch: 

-

                pass 

-

 

-

        slug = getattr(obj, self.slug_field, None) 

-

        if slug: 

-

            # Only use slug lookup if a slug field exists on the model 

-

            kwargs = {self.slug_url_kwarg: slug} 

-

            try: 

-

                return reverse(view_name, kwargs=kwargs, request=request, format=format) 

-

            except NoReverseMatch: 

-

                pass 

-

 

-

        raise NoReverseMatch() 

-

 

-

 

-

### Old-style many classes for backwards compat 

-

 

-

class ManyRelatedField(RelatedField): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn('`ManyRelatedField()` is deprecated. ' 

-

                      'Use `RelatedField(many=True)` instead.', 

-

                       DeprecationWarning, stacklevel=2) 

-

        kwargs['many'] = True 

-

        super(ManyRelatedField, self).__init__(*args, **kwargs) 

-

 

-

 

-

class ManyPrimaryKeyRelatedField(PrimaryKeyRelatedField): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn('`ManyPrimaryKeyRelatedField()` is deprecated. ' 

-

                      'Use `PrimaryKeyRelatedField(many=True)` instead.', 

-

                       DeprecationWarning, stacklevel=2) 

-

        kwargs['many'] = True 

-

        super(ManyPrimaryKeyRelatedField, self).__init__(*args, **kwargs) 

-

 

-

 

-

class ManySlugRelatedField(SlugRelatedField): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn('`ManySlugRelatedField()` is deprecated. ' 

-

                      'Use `SlugRelatedField(many=True)` instead.', 

-

                       DeprecationWarning, stacklevel=2) 

-

        kwargs['many'] = True 

-

        super(ManySlugRelatedField, self).__init__(*args, **kwargs) 

-

 

-

 

-

class ManyHyperlinkedRelatedField(HyperlinkedRelatedField): 

-

    def __init__(self, *args, **kwargs): 

-

        warnings.warn('`ManyHyperlinkedRelatedField()` is deprecated. ' 

-

                      'Use `HyperlinkedRelatedField(many=True)` instead.', 

-

                       DeprecationWarning, stacklevel=2) 

-

        kwargs['many'] = True 

-

        super(ManyHyperlinkedRelatedField, self).__init__(*args, **kwargs) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_renderers.html b/htmlcov/rest_framework_renderers.html deleted file mode 100644 index 58c71b855..000000000 --- a/htmlcov/rest_framework_renderers.html +++ /dev/null @@ -1,1227 +0,0 @@ - - - - - - - - Coverage for rest_framework/renderers: 92% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

-

370

-

371

-

372

-

373

-

374

-

375

-

376

-

377

-

378

-

379

-

380

-

381

-

382

-

383

-

384

-

385

-

386

-

387

-

388

-

389

-

390

-

391

-

392

-

393

-

394

-

395

-

396

-

397

-

398

-

399

-

400

-

401

-

402

-

403

-

404

-

405

-

406

-

407

-

408

-

409

-

410

-

411

-

412

-

413

-

414

-

415

-

416

-

417

-

418

-

419

-

420

-

421

-

422

-

423

-

424

-

425

-

426

-

427

-

428

-

429

-

430

-

431

-

432

-

433

-

434

-

435

-

436

-

437

-

438

-

439

-

440

-

441

-

442

-

443

-

444

-

445

-

446

-

447

-

448

-

449

-

450

-

451

-

452

-

453

-

454

-

455

-

456

-

457

-

458

-

459

-

460

-

461

-

462

-

463

-

464

-

465

-

466

-

467

-

468

-

469

-

470

-

471

-

472

-

473

-

474

-

475

-

476

-

477

-

478

-

479

-

480

-

481

-

482

-

483

-

484

-

485

-

486

-

487

-

488

-

489

-

490

-

491

-

492

-

493

-

494

-

495

-

496

-

497

-

498

-

499

-

500

-

501

-

502

-

503

-

504

-

505

-

506

-

507

-

508

-

509

-

510

-

511

-

512

-

513

-

514

-

515

-

516

-

517

-

518

-

519

-

520

-

521

-

522

-

523

-

524

-

525

-

526

-

527

-

528

-

529

-

530

-

531

-

532

-

533

-

534

-

535

-

536

-

537

-

538

-

539

-

540

-

541

-

542

-

543

-

544

-

545

-

546

-

547

-

548

-

549

-

550

-

551

-

552

-

553

-

554

-

555

-

556

-

557

-

558

-

559

-

560

-

561

-

562

-

563

-

564

-

565

-

566

-

567

-

568

-

569

-

570

-

571

-

572

-

573

- -
-

""" 

-

Renderers are used to serialize a response into specific media types. 

-

 

-

They give us a generic way of being able to handle various media types 

-

on the response, such as JSON encoded data or HTML output. 

-

 

-

REST framework also provides an HTML renderer the renders the browsable API. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

import copy 

-

import json 

-

from django import forms 

-

from django.core.exceptions import ImproperlyConfigured 

-

from django.http.multipartparser import parse_header 

-

from django.template import RequestContext, loader, Template 

-

from django.utils.xmlutils import SimplerXMLGenerator 

-

from rest_framework.compat import StringIO 

-

from rest_framework.compat import six 

-

from rest_framework.compat import smart_text 

-

from rest_framework.compat import yaml 

-

from rest_framework.settings import api_settings 

-

from rest_framework.request import clone_request 

-

from rest_framework.utils import encoders 

-

from rest_framework.utils.breadcrumbs import get_breadcrumbs 

-

from rest_framework.utils.formatting import get_view_name, get_view_description 

-

from rest_framework import exceptions, parsers, status, VERSION 

-

 

-

 

-

class BaseRenderer(object): 

-

    """ 

-

    All renderers should extend this class, setting the `media_type` 

-

    and `format` attributes, and override the `.render()` method. 

-

    """ 

-

 

-

    media_type = None 

-

    format = None 

-

    charset = 'utf-8' 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        raise NotImplemented('Renderer class requires .render() to be implemented') 

-

 

-

 

-

class JSONRenderer(BaseRenderer): 

-

    """ 

-

    Renderer which serializes to JSON. 

-

    Applies JSON's backslash-u character escaping for non-ascii characters. 

-

    """ 

-

 

-

    media_type = 'application/json' 

-

    format = 'json' 

-

    encoder_class = encoders.JSONEncoder 

-

    ensure_ascii = True 

-

    charset = 'utf-8' 

-

    # Note that JSON encodings must be utf-8, utf-16 or utf-32. 

-

    # See: http://www.ietf.org/rfc/rfc4627.txt 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Render `data` into JSON. 

-

        """ 

-

        if data is None: 

-

            return '' 

-

 

-

        # If 'indent' is provided in the context, then pretty print the result. 

-

        # E.g. If we're being called by the BrowsableAPIRenderer. 

-

        renderer_context = renderer_context or {} 

-

        indent = renderer_context.get('indent', None) 

-

 

-

        if accepted_media_type: 

-

            # If the media type looks like 'application/json; indent=4', 

-

            # then pretty print the result. 

-

            base_media_type, params = parse_header(accepted_media_type.encode('ascii')) 

-

            indent = params.get('indent', indent) 

-

            try: 

-

                indent = max(min(int(indent), 8), 0) 

-

            except (ValueError, TypeError): 

-

                indent = None 

-

 

-

        ret = json.dumps(data, cls=self.encoder_class, 

-

            indent=indent, ensure_ascii=self.ensure_ascii) 

-

 

-

        # On python 2.x json.dumps() returns bytestrings if ensure_ascii=True, 

-

        # but if ensure_ascii=False, the return type is underspecified, 

-

        # and may (or may not) be unicode. 

-

        # On python 3.x json.dumps() returns unicode strings. 

-

        if isinstance(ret, six.text_type): 

-

            return bytes(ret.encode(self.charset)) 

-

        return ret 

-

 

-

 

-

class UnicodeJSONRenderer(JSONRenderer): 

-

    ensure_ascii = False 

-

    charset = 'utf-8' 

-

    """ 

-

    Renderer which serializes to JSON. 

-

    Does *not* apply JSON's character escaping for non-ascii characters. 

-

    """ 

-

 

-

 

-

class JSONPRenderer(JSONRenderer): 

-

    """ 

-

    Renderer which serializes to json, 

-

    wrapping the json output in a callback function. 

-

    """ 

-

 

-

    media_type = 'application/javascript' 

-

    format = 'jsonp' 

-

    callback_parameter = 'callback' 

-

    default_callback = 'callback' 

-

 

-

    def get_callback(self, renderer_context): 

-

        """ 

-

        Determine the name of the callback to wrap around the json output. 

-

        """ 

-

        request = renderer_context.get('request', None) 

-

        params = request and request.QUERY_PARAMS or {} 

-

        return params.get(self.callback_parameter, self.default_callback) 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Renders into jsonp, wrapping the json output in a callback function. 

-

 

-

        Clients may set the callback function name using a query parameter 

-

        on the URL, for example: ?callback=exampleCallbackName 

-

        """ 

-

        renderer_context = renderer_context or {} 

-

        callback = self.get_callback(renderer_context) 

-

        json = super(JSONPRenderer, self).render(data, accepted_media_type, 

-

                                                 renderer_context) 

-

        return callback.encode(self.charset) + b'(' + json + b');' 

-

 

-

 

-

class XMLRenderer(BaseRenderer): 

-

    """ 

-

    Renderer which serializes to XML. 

-

    """ 

-

 

-

    media_type = 'application/xml' 

-

    format = 'xml' 

-

    charset = 'utf-8' 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Renders *obj* into serialized XML. 

-

        """ 

-

        if data is None: 

-

            return '' 

-

 

-

        stream = StringIO() 

-

 

-

        xml = SimplerXMLGenerator(stream, self.charset) 

-

        xml.startDocument() 

-

        xml.startElement("root", {}) 

-

 

-

        self._to_xml(xml, data) 

-

 

-

        xml.endElement("root") 

-

        xml.endDocument() 

-

        return stream.getvalue() 

-

 

-

    def _to_xml(self, xml, data): 

-

        if isinstance(data, (list, tuple)): 

-

            for item in data: 

-

                xml.startElement("list-item", {}) 

-

                self._to_xml(xml, item) 

-

                xml.endElement("list-item") 

-

 

-

        elif isinstance(data, dict): 

-

            for key, value in six.iteritems(data): 

-

                xml.startElement(key, {}) 

-

                self._to_xml(xml, value) 

-

                xml.endElement(key) 

-

 

-

        elif data is None: 

-

            # Don't output any value 

-

            pass 

-

 

-

        else: 

-

            xml.characters(smart_text(data)) 

-

 

-

 

-

class YAMLRenderer(BaseRenderer): 

-

    """ 

-

    Renderer which serializes to YAML. 

-

    """ 

-

 

-

    media_type = 'application/yaml' 

-

    format = 'yaml' 

-

    encoder = encoders.SafeDumper 

-

    charset = 'utf-8' 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Renders *obj* into serialized YAML. 

-

        """ 

-

        assert yaml, 'YAMLRenderer requires pyyaml to be installed' 

-

 

-

        if data is None: 

-

            return '' 

-

 

-

        return yaml.dump(data, stream=None, encoding=self.charset, Dumper=self.encoder) 

-

 

-

 

-

class TemplateHTMLRenderer(BaseRenderer): 

-

    """ 

-

    An HTML renderer for use with templates. 

-

 

-

    The data supplied to the Response object should be a dictionary that will 

-

    be used as context for the template. 

-

 

-

    The template name is determined by (in order of preference): 

-

 

-

    1. An explicit `.template_name` attribute set on the response. 

-

    2. An explicit `.template_name` attribute set on this class. 

-

    3. The return result of calling `view.get_template_names()`. 

-

 

-

    For example: 

-

        data = {'users': User.objects.all()} 

-

        return Response(data, template_name='users.html') 

-

 

-

    For pre-rendered HTML, see StaticHTMLRenderer. 

-

    """ 

-

 

-

    media_type = 'text/html' 

-

    format = 'html' 

-

    template_name = None 

-

    exception_template_names = [ 

-

        '%(status_code)s.html', 

-

        'api_exception.html' 

-

    ] 

-

    charset = 'utf-8' 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Renders data to HTML, using Django's standard template rendering. 

-

 

-

        The template name is determined by (in order of preference): 

-

 

-

        1. An explicit .template_name set on the response. 

-

        2. An explicit .template_name set on this class. 

-

        3. The return result of calling view.get_template_names(). 

-

        """ 

-

        renderer_context = renderer_context or {} 

-

        view = renderer_context['view'] 

-

        request = renderer_context['request'] 

-

        response = renderer_context['response'] 

-

 

-

        if response.exception: 

-

            template = self.get_exception_template(response) 

-

        else: 

-

            template_names = self.get_template_names(response, view) 

-

            template = self.resolve_template(template_names) 

-

 

-

        context = self.resolve_context(data, request, response) 

-

        return template.render(context) 

-

 

-

    def resolve_template(self, template_names): 

-

        return loader.select_template(template_names) 

-

 

-

    def resolve_context(self, data, request, response): 

-

        if response.exception: 

-

            data['status_code'] = response.status_code 

-

        return RequestContext(request, data) 

-

 

-

    def get_template_names(self, response, view): 

-

        if response.template_name: 

-

            return [response.template_name] 

-

        elif self.template_name: 

-

            return [self.template_name] 

-

        elif hasattr(view, 'get_template_names'): 

-

            return view.get_template_names() 

-

        raise ImproperlyConfigured('Returned a template response with no template_name') 

-

 

-

    def get_exception_template(self, response): 

-

        template_names = [name % {'status_code': response.status_code} 

-

                          for name in self.exception_template_names] 

-

 

-

        try: 

-

            # Try to find an appropriate error template 

-

            return self.resolve_template(template_names) 

-

        except Exception: 

-

            # Fall back to using eg '404 Not Found' 

-

            return Template('%d %s' % (response.status_code, 

-

                                       response.status_text.title())) 

-

 

-

 

-

# Note, subclass TemplateHTMLRenderer simply for the exception behavior 

-

class StaticHTMLRenderer(TemplateHTMLRenderer): 

-

    """ 

-

    An HTML renderer class that simply returns pre-rendered HTML. 

-

 

-

    The data supplied to the Response object should be a string representing 

-

    the pre-rendered HTML content. 

-

 

-

    For example: 

-

        data = '<html><body>example</body></html>' 

-

        return Response(data) 

-

 

-

    For template rendered HTML, see TemplateHTMLRenderer. 

-

    """ 

-

    media_type = 'text/html' 

-

    format = 'html' 

-

    charset = 'utf-8' 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        renderer_context = renderer_context or {} 

-

        response = renderer_context['response'] 

-

 

-

        if response and response.exception: 

-

            request = renderer_context['request'] 

-

            template = self.get_exception_template(response) 

-

            context = self.resolve_context(data, request, response) 

-

            return template.render(context) 

-

 

-

        return data 

-

 

-

 

-

class BrowsableAPIRenderer(BaseRenderer): 

-

    """ 

-

    HTML renderer used to self-document the API. 

-

    """ 

-

    media_type = 'text/html' 

-

    format = 'api' 

-

    template = 'rest_framework/api.html' 

-

    charset = 'utf-8' 

-

 

-

    def get_default_renderer(self, view): 

-

        """ 

-

        Return an instance of the first valid renderer. 

-

        (Don't use another documenting renderer.) 

-

        """ 

-

        renderers = [renderer for renderer in view.renderer_classes 

-

                     if not issubclass(renderer, BrowsableAPIRenderer)] 

-

        if not renderers: 

-

            return None 

-

        return renderers[0]() 

-

 

-

    def get_content(self, renderer, data, 

-

                    accepted_media_type, renderer_context): 

-

        """ 

-

        Get the content as if it had been rendered by the default 

-

        non-documenting renderer. 

-

        """ 

-

        if not renderer: 

-

            return '[No renderers were found]' 

-

 

-

        renderer_context['indent'] = 4 

-

        content = renderer.render(data, accepted_media_type, renderer_context) 

-

 

-

        if renderer.charset is None: 

-

            return '[%d bytes of binary content]' % len(content) 

-

 

-

        return content 

-

 

-

    def show_form_for_method(self, view, method, request, obj): 

-

        """ 

-

        Returns True if a form should be shown for this method. 

-

        """ 

-

        if not method in view.allowed_methods: 

-

            return  # Not a valid method 

-

 

-

        if not api_settings.FORM_METHOD_OVERRIDE: 

-

            return  # Cannot use form overloading 

-

 

-

        try: 

-

            view.check_permissions(request) 

-

            if obj is not None: 

-

                view.check_object_permissions(request, obj) 

-

        except exceptions.APIException: 

-

            return False  # Doesn't have permissions 

-

        return True 

-

 

-

    def serializer_to_form_fields(self, serializer): 

-

        fields = {} 

-

        for k, v in serializer.get_fields().items(): 

-

            if getattr(v, 'read_only', True): 

-

                continue 

-

 

-

            kwargs = {} 

-

            kwargs['required'] = v.required 

-

 

-

            #if getattr(v, 'queryset', None): 

-

            #    kwargs['queryset'] = v.queryset 

-

 

-

            if getattr(v, 'choices', None) is not None: 

-

                kwargs['choices'] = v.choices 

-

 

-

            if getattr(v, 'regex', None) is not None: 

-

                kwargs['regex'] = v.regex 

-

 

-

            if getattr(v, 'widget', None): 

-

                widget = copy.deepcopy(v.widget) 

-

                kwargs['widget'] = widget 

-

 

-

            if getattr(v, 'default', None) is not None: 

-

                kwargs['initial'] = v.default 

-

 

-

            if getattr(v, 'label', None) is not None: 

-

                kwargs['label'] = v.label 

-

 

-

            if getattr(v, 'help_text', None) is not None: 

-

                kwargs['help_text'] = v.help_text 

-

 

-

            fields[k] = v.form_field_class(**kwargs) 

-

 

-

        return fields 

-

 

-

    def _get_form(self, view, method, request): 

-

        # We need to impersonate a request with the correct method, 

-

        # so that eg. any dynamic get_serializer_class methods return the 

-

        # correct form for each method. 

-

        restore = view.request 

-

        request = clone_request(request, method) 

-

        view.request = request 

-

        try: 

-

            return self.get_form(view, method, request) 

-

        finally: 

-

            view.request = restore 

-

 

-

    def _get_raw_data_form(self, view, method, request, media_types): 

-

        # We need to impersonate a request with the correct method, 

-

        # so that eg. any dynamic get_serializer_class methods return the 

-

        # correct form for each method. 

-

        restore = view.request 

-

        request = clone_request(request, method) 

-

        view.request = request 

-

        try: 

-

            return self.get_raw_data_form(view, method, request, media_types) 

-

        finally: 

-

            view.request = restore 

-

 

-

    def get_form(self, view, method, request): 

-

        """ 

-

        Get a form, possibly bound to either the input or output data. 

-

        In the absence on of the Resource having an associated form then 

-

        provide a form that can be used to submit arbitrary content. 

-

        """ 

-

        obj = getattr(view, 'object', None) 

-

        if not self.show_form_for_method(view, method, request, obj): 

-

            return 

-

 

-

        if method in ('DELETE', 'OPTIONS'): 

-

            return True  # Don't actually need to return a form 

-

 

-

        if not getattr(view, 'get_serializer', None) or not parsers.FormParser in view.parser_classes: 

-

            return 

-

 

-

        serializer = view.get_serializer(instance=obj) 

-

        fields = self.serializer_to_form_fields(serializer) 

-

 

-

        # Creating an on the fly form see: 

-

        # http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python 

-

        OnTheFlyForm = type(str("OnTheFlyForm"), (forms.Form,), fields) 

-

        data = (obj is not None) and serializer.data or None 

-

        form_instance = OnTheFlyForm(data) 

-

        return form_instance 

-

 

-

    def get_raw_data_form(self, view, method, request, media_types): 

-

        """ 

-

        Returns a form that allows for arbitrary content types to be tunneled 

-

        via standard HTML forms. 

-

        (Which are typically application/x-www-form-urlencoded) 

-

        """ 

-

 

-

        # If we're not using content overloading there's no point in supplying a generic form, 

-

        # as the view won't treat the form's value as the content of the request. 

-

        if not (api_settings.FORM_CONTENT_OVERRIDE 

-

                and api_settings.FORM_CONTENTTYPE_OVERRIDE): 

-

            return None 

-

 

-

        # Check permissions 

-

        obj = getattr(view, 'object', None) 

-

        if not self.show_form_for_method(view, method, request, obj): 

-

            return 

-

 

-

        content_type_field = api_settings.FORM_CONTENTTYPE_OVERRIDE 

-

        content_field = api_settings.FORM_CONTENT_OVERRIDE 

-

        choices = [(media_type, media_type) for media_type in media_types] 

-

        initial = media_types[0] 

-

 

-

        # NB. http://jacobian.org/writing/dynamic-form-generation/ 

-

        class GenericContentForm(forms.Form): 

-

            def __init__(self): 

-

                super(GenericContentForm, self).__init__() 

-

 

-

                self.fields[content_type_field] = forms.ChoiceField( 

-

                    label='Media type', 

-

                    choices=choices, 

-

                    initial=initial 

-

                ) 

-

                self.fields[content_field] = forms.CharField( 

-

                    label='Content', 

-

                    widget=forms.Textarea 

-

                ) 

-

 

-

        return GenericContentForm() 

-

 

-

    def get_name(self, view): 

-

        return get_view_name(view.__class__, getattr(view, 'suffix', None)) 

-

 

-

    def get_description(self, view): 

-

        return get_view_description(view.__class__, html=True) 

-

 

-

    def get_breadcrumbs(self, request): 

-

        return get_breadcrumbs(request.path) 

-

 

-

    def render(self, data, accepted_media_type=None, renderer_context=None): 

-

        """ 

-

        Render the HTML for the browsable API representation. 

-

        """ 

-

        accepted_media_type = accepted_media_type or '' 

-

        renderer_context = renderer_context or {} 

-

 

-

        view = renderer_context['view'] 

-

        request = renderer_context['request'] 

-

        response = renderer_context['response'] 

-

        media_types = [parser.media_type for parser in view.parser_classes] 

-

 

-

        renderer = self.get_default_renderer(view) 

-

        content = self.get_content(renderer, data, accepted_media_type, renderer_context) 

-

 

-

        put_form = self._get_form(view, 'PUT', request) 

-

        post_form = self._get_form(view, 'POST', request) 

-

        patch_form = self._get_form(view, 'PATCH', request) 

-

        delete_form = self._get_form(view, 'DELETE', request) 

-

        options_form = self._get_form(view, 'OPTIONS', request) 

-

 

-

        raw_data_put_form = self._get_raw_data_form(view, 'PUT', request, media_types) 

-

        raw_data_post_form = self._get_raw_data_form(view, 'POST', request, media_types) 

-

        raw_data_patch_form = self._get_raw_data_form(view, 'PATCH', request, media_types) 

-

        raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form 

-

 

-

        name = self.get_name(view) 

-

        description = self.get_description(view) 

-

        breadcrumb_list = self.get_breadcrumbs(request) 

-

 

-

        template = loader.get_template(self.template) 

-

        context = RequestContext(request, { 

-

            'content': content, 

-

            'view': view, 

-

            'request': request, 

-

            'response': response, 

-

            'description': description, 

-

            'name': name, 

-

            'version': VERSION, 

-

            'breadcrumblist': breadcrumb_list, 

-

            'allowed_methods': view.allowed_methods, 

-

            'available_formats': [renderer.format for renderer in view.renderer_classes], 

-

 

-

            'put_form': put_form, 

-

            'post_form': post_form, 

-

            'patch_form': patch_form, 

-

            'delete_form': delete_form, 

-

            'options_form': options_form, 

-

 

-

            'raw_data_put_form': raw_data_put_form, 

-

            'raw_data_post_form': raw_data_post_form, 

-

            'raw_data_patch_form': raw_data_patch_form, 

-

            'raw_data_put_or_patch_form': raw_data_put_or_patch_form, 

-

 

-

            'api_settings': api_settings 

-

        }) 

-

 

-

        ret = template.render(context) 

-

 

-

        # Munge DELETE Response code to allow us to return content 

-

        # (Do this *after* we've rendered the template so that we include 

-

        # the normal deletion response code in the output) 

-

        if response.status_code == status.HTTP_204_NO_CONTENT: 

-

            response.status_code = status.HTTP_200_OK 

-

 

-

        return ret 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_request.html b/htmlcov/rest_framework_request.html deleted file mode 100644 index 03f2c3e34..000000000 --- a/htmlcov/rest_framework_request.html +++ /dev/null @@ -1,819 +0,0 @@ - - - - - - - - Coverage for rest_framework/request: 95% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

- -
-

""" 

-

The Request class is used as a wrapper around the standard request object. 

-

 

-

The wrapped request then offers a richer API, in particular : 

-

 

-

    - content automatically parsed according to `Content-Type` header, 

-

      and available as `request.DATA` 

-

    - full support of PUT method, including support for file uploads 

-

    - form overloading of HTTP method, content type and content 

-

""" 

-

from __future__ import unicode_literals 

-

from django.conf import settings 

-

from django.http import QueryDict 

-

from django.http.multipartparser import parse_header 

-

from django.utils.datastructures import MultiValueDict 

-

from rest_framework import HTTP_HEADER_ENCODING 

-

from rest_framework import exceptions 

-

from rest_framework.compat import BytesIO 

-

from rest_framework.settings import api_settings 

-

 

-

 

-

def is_form_media_type(media_type): 

-

    """ 

-

    Return True if the media type is a valid form media type. 

-

    """ 

-

    base_media_type, params = parse_header(media_type.encode(HTTP_HEADER_ENCODING)) 

-

    return (base_media_type == 'application/x-www-form-urlencoded' or 

-

            base_media_type == 'multipart/form-data') 

-

 

-

 

-

class Empty(object): 

-

    """ 

-

    Placeholder for unset attributes. 

-

    Cannot use `None`, as that may be a valid value. 

-

    """ 

-

    pass 

-

 

-

 

-

def _hasattr(obj, name): 

-

    return not getattr(obj, name) is Empty 

-

 

-

 

-

def clone_request(request, method): 

-

    """ 

-

    Internal helper method to clone a request, replacing with a different 

-

    HTTP method.  Used for checking permissions against other methods. 

-

    """ 

-

    ret = Request(request=request._request, 

-

                  parsers=request.parsers, 

-

                  authenticators=request.authenticators, 

-

                  negotiator=request.negotiator, 

-

                  parser_context=request.parser_context) 

-

    ret._data = request._data 

-

    ret._files = request._files 

-

    ret._content_type = request._content_type 

-

    ret._stream = request._stream 

-

    ret._method = method 

-

    if hasattr(request, '_user'): 

-

        ret._user = request._user 

-

    if hasattr(request, '_auth'): 

-

        ret._auth = request._auth 

-

    if hasattr(request, '_authenticator'): 

-

        ret._authenticator = request._authenticator 

-

    return ret 

-

 

-

 

-

class Request(object): 

-

    """ 

-

    Wrapper allowing to enhance a standard `HttpRequest` instance. 

-

 

-

    Kwargs: 

-

        - request(HttpRequest). The original request instance. 

-

        - parsers_classes(list/tuple). The parsers to use for parsing the 

-

          request content. 

-

        - authentication_classes(list/tuple). The authentications used to try 

-

          authenticating the request's user. 

-

    """ 

-

 

-

    _METHOD_PARAM = api_settings.FORM_METHOD_OVERRIDE 

-

    _CONTENT_PARAM = api_settings.FORM_CONTENT_OVERRIDE 

-

    _CONTENTTYPE_PARAM = api_settings.FORM_CONTENTTYPE_OVERRIDE 

-

 

-

    def __init__(self, request, parsers=None, authenticators=None, 

-

                 negotiator=None, parser_context=None): 

-

        self._request = request 

-

        self.parsers = parsers or () 

-

        self.authenticators = authenticators or () 

-

        self.negotiator = negotiator or self._default_negotiator() 

-

        self.parser_context = parser_context 

-

        self._data = Empty 

-

        self._files = Empty 

-

        self._method = Empty 

-

        self._content_type = Empty 

-

        self._stream = Empty 

-

 

-

        if self.parser_context is None: 

-

            self.parser_context = {} 

-

        self.parser_context['request'] = self 

-

        self.parser_context['encoding'] = request.encoding or settings.DEFAULT_CHARSET 

-

 

-

    def _default_negotiator(self): 

-

        return api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS() 

-

 

-

    @property 

-

    def method(self): 

-

        """ 

-

        Returns the HTTP method. 

-

 

-

        This allows the `method` to be overridden by using a hidden `form` 

-

        field on a form POST request. 

-

        """ 

-

        if not _hasattr(self, '_method'): 

-

            self._load_method_and_content_type() 

-

        return self._method 

-

 

-

    @property 

-

    def content_type(self): 

-

        """ 

-

        Returns the content type header. 

-

 

-

        This should be used instead of `request.META.get('HTTP_CONTENT_TYPE')`, 

-

        as it allows the content type to be overridden by using a hidden form 

-

        field on a form POST request. 

-

        """ 

-

        if not _hasattr(self, '_content_type'): 

-

            self._load_method_and_content_type() 

-

        return self._content_type 

-

 

-

    @property 

-

    def stream(self): 

-

        """ 

-

        Returns an object that may be used to stream the request content. 

-

        """ 

-

        if not _hasattr(self, '_stream'): 

-

            self._load_stream() 

-

        return self._stream 

-

 

-

    @property 

-

    def QUERY_PARAMS(self): 

-

        """ 

-

        More semantically correct name for request.GET. 

-

        """ 

-

        return self._request.GET 

-

 

-

    @property 

-

    def DATA(self): 

-

        """ 

-

        Parses the request body and returns the data. 

-

 

-

        Similar to usual behaviour of `request.POST`, except that it handles 

-

        arbitrary parsers, and also works on methods other than POST (eg PUT). 

-

        """ 

-

        if not _hasattr(self, '_data'): 

-

            self._load_data_and_files() 

-

        return self._data 

-

 

-

    @property 

-

    def FILES(self): 

-

        """ 

-

        Parses the request body and returns any files uploaded in the request. 

-

 

-

        Similar to usual behaviour of `request.FILES`, except that it handles 

-

        arbitrary parsers, and also works on methods other than POST (eg PUT). 

-

        """ 

-

        if not _hasattr(self, '_files'): 

-

            self._load_data_and_files() 

-

        return self._files 

-

 

-

    @property 

-

    def user(self): 

-

        """ 

-

        Returns the user associated with the current request, as authenticated 

-

        by the authentication classes provided to the request. 

-

        """ 

-

        if not hasattr(self, '_user'): 

-

            self._authenticate() 

-

        return self._user 

-

 

-

    @user.setter 

-

    def user(self, value): 

-

        """ 

-

        Sets the user on the current request. This is necessary to maintain 

-

        compatilbility with django.contrib.auth where the user proprety is 

-

        set in the login and logout functions. 

-

        """ 

-

        self._user = value 

-

 

-

    @property 

-

    def auth(self): 

-

        """ 

-

        Returns any non-user authentication information associated with the 

-

        request, such as an authentication token. 

-

        """ 

-

        if not hasattr(self, '_auth'): 

-

            self._authenticate() 

-

        return self._auth 

-

 

-

    @auth.setter 

-

    def auth(self, value): 

-

        """ 

-

        Sets any non-user authentication information associated with the 

-

        request, such as an authentication token. 

-

        """ 

-

        self._auth = value 

-

 

-

    @property 

-

    def successful_authenticator(self): 

-

        """ 

-

        Return the instance of the authentication instance class that was used 

-

        to authenticate the request, or `None`. 

-

        """ 

-

        if not hasattr(self, '_authenticator'): 

-

            self._authenticate() 

-

        return self._authenticator 

-

 

-

    def _load_data_and_files(self): 

-

        """ 

-

        Parses the request content into self.DATA and self.FILES. 

-

        """ 

-

        if not _hasattr(self, '_content_type'): 

-

            self._load_method_and_content_type() 

-

 

-

        if not _hasattr(self, '_data'): 

-

            self._data, self._files = self._parse() 

-

 

-

    def _load_method_and_content_type(self): 

-

        """ 

-

        Sets the method and content_type, and then check if they've 

-

        been overridden. 

-

        """ 

-

        self._content_type = self.META.get('HTTP_CONTENT_TYPE', 

-

                                           self.META.get('CONTENT_TYPE', '')) 

-

 

-

        self._perform_form_overloading() 

-

 

-

        if not _hasattr(self, '_method'): 

-

            self._method = self._request.method 

-

 

-

            if self._method == 'POST': 

-

                # Allow X-HTTP-METHOD-OVERRIDE header 

-

                self._method = self.META.get('HTTP_X_HTTP_METHOD_OVERRIDE', 

-

                                             self._method) 

-

 

-

    def _load_stream(self): 

-

        """ 

-

        Return the content body of the request, as a stream. 

-

        """ 

-

        try: 

-

            content_length = int(self.META.get('CONTENT_LENGTH', 

-

                                    self.META.get('HTTP_CONTENT_LENGTH'))) 

-

        except (ValueError, TypeError): 

-

            content_length = 0 

-

 

-

        if content_length == 0: 

-

            self._stream = None 

-

        elif hasattr(self._request, 'read'): 

-

            self._stream = self._request 

-

        else: 

-

            self._stream = BytesIO(self.raw_post_data) 

-

 

-

    def _perform_form_overloading(self): 

-

        """ 

-

        If this is a form POST request, then we need to check if the method and 

-

        content/content_type have been overridden by setting them in hidden 

-

        form fields or not. 

-

        """ 

-

 

-

        USE_FORM_OVERLOADING = ( 

-

            self._METHOD_PARAM or 

-

            (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM) 

-

        ) 

-

 

-

        # We only need to use form overloading on form POST requests. 

-

        if (not USE_FORM_OVERLOADING 

-

            or self._request.method != 'POST' 

-

            or not is_form_media_type(self._content_type)): 

-

            return 

-

 

-

        # At this point we're committed to parsing the request as form data. 

-

        self._data = self._request.POST 

-

        self._files = self._request.FILES 

-

 

-

        # Method overloading - change the method and remove the param from the content. 

-

        if (self._METHOD_PARAM and 

-

            self._METHOD_PARAM in self._data): 

-

            self._method = self._data[self._METHOD_PARAM].upper() 

-

 

-

        # Content overloading - modify the content type, and force re-parse. 

-

        if (self._CONTENT_PARAM and 

-

            self._CONTENTTYPE_PARAM and 

-

            self._CONTENT_PARAM in self._data and 

-

            self._CONTENTTYPE_PARAM in self._data): 

-

            self._content_type = self._data[self._CONTENTTYPE_PARAM] 

-

            self._stream = BytesIO(self._data[self._CONTENT_PARAM].encode(HTTP_HEADER_ENCODING)) 

-

            self._data, self._files = (Empty, Empty) 

-

 

-

    def _parse(self): 

-

        """ 

-

        Parse the request content, returning a two-tuple of (data, files) 

-

 

-

        May raise an `UnsupportedMediaType`, or `ParseError` exception. 

-

        """ 

-

        stream = self.stream 

-

        media_type = self.content_type 

-

 

-

        if stream is None or media_type is None: 

-

            empty_data = QueryDict('', self._request._encoding) 

-

            empty_files = MultiValueDict() 

-

            return (empty_data, empty_files) 

-

 

-

        parser = self.negotiator.select_parser(self, self.parsers) 

-

 

-

        if not parser: 

-

            raise exceptions.UnsupportedMediaType(media_type) 

-

 

-

        parsed = parser.parse(stream, media_type, self.parser_context) 

-

 

-

        # Parser classes may return the raw data, or a 

-

        # DataAndFiles object.  Unpack the result as required. 

-

        try: 

-

            return (parsed.data, parsed.files) 

-

        except AttributeError: 

-

            empty_files = MultiValueDict() 

-

            return (parsed, empty_files) 

-

 

-

    def _authenticate(self): 

-

        """ 

-

        Attempt to authenticate the request using each authentication instance 

-

        in turn. 

-

        Returns a three-tuple of (authenticator, user, authtoken). 

-

        """ 

-

        for authenticator in self.authenticators: 

-

            try: 

-

                user_auth_tuple = authenticator.authenticate(self) 

-

            except exceptions.APIException: 

-

                self._not_authenticated() 

-

                raise 

-

 

-

            if not user_auth_tuple is None: 

-

                self._authenticator = authenticator 

-

                self._user, self._auth = user_auth_tuple 

-

                return 

-

 

-

        self._not_authenticated() 

-

 

-

    def _not_authenticated(self): 

-

        """ 

-

        Return a three-tuple of (authenticator, user, authtoken), representing 

-

        an unauthenticated request. 

-

 

-

        By default this will be (None, AnonymousUser, None). 

-

        """ 

-

        self._authenticator = None 

-

 

-

        if api_settings.UNAUTHENTICATED_USER: 

-

            self._user = api_settings.UNAUTHENTICATED_USER() 

-

        else: 

-

            self._user = None 

-

 

-

        if api_settings.UNAUTHENTICATED_TOKEN: 

-

            self._auth = api_settings.UNAUTHENTICATED_TOKEN() 

-

        else: 

-

            self._auth = None 

-

 

-

    def __getattr__(self, attr): 

-

        """ 

-

        Proxy other attributes to the underlying HttpRequest object. 

-

        """ 

-

        return getattr(self._request, attr) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_response.html b/htmlcov/rest_framework_response.html deleted file mode 100644 index d297ecd0b..000000000 --- a/htmlcov/rest_framework_response.html +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - Coverage for rest_framework/response: 98% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

- -
-

""" 

-

The Response class in REST framework is similar to HTTPResponse, except that 

-

it is initialized with unrendered data, instead of a pre-rendered string. 

-

 

-

The appropriate renderer is called during Django's template response rendering. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.core.handlers.wsgi import STATUS_CODE_TEXT 

-

from django.template.response import SimpleTemplateResponse 

-

from rest_framework.compat import six 

-

 

-

 

-

class Response(SimpleTemplateResponse): 

-

    """ 

-

    An HttpResponse that allows its data to be rendered into 

-

    arbitrary media types. 

-

    """ 

-

 

-

    def __init__(self, data=None, status=200, 

-

                 template_name=None, headers=None, 

-

                 exception=False, content_type=None): 

-

        """ 

-

        Alters the init arguments slightly. 

-

        For example, drop 'template_name', and instead use 'data'. 

-

 

-

        Setting 'renderer' and 'media_type' will typically be deferred, 

-

        For example being set automatically by the `APIView`. 

-

        """ 

-

        super(Response, self).__init__(None, status=status) 

-

        self.data = data 

-

        self.template_name = template_name 

-

        self.exception = exception 

-

        self.content_type = content_type 

-

 

-

        if headers: 

-

            for name, value in six.iteritems(headers): 

-

                self[name] = value 

-

 

-

    @property 

-

    def rendered_content(self): 

-

        renderer = getattr(self, 'accepted_renderer', None) 

-

        media_type = getattr(self, 'accepted_media_type', None) 

-

        context = getattr(self, 'renderer_context', None) 

-

 

-

        assert renderer, ".accepted_renderer not set on Response" 

-

        assert media_type, ".accepted_media_type not set on Response" 

-

        assert context, ".renderer_context not set on Response" 

-

        context['response'] = self 

-

 

-

        charset = renderer.charset 

-

        content_type = self.content_type 

-

 

-

        if content_type is None and charset is not None: 

-

            content_type = "{0}; charset={1}".format(media_type, charset) 

-

        elif content_type is None: 

-

            content_type = media_type 

-

        self['Content-Type'] = content_type 

-

 

-

        ret = renderer.render(self.data, media_type, context) 

-

        if isinstance(ret, six.text_type): 

-

            assert charset, 'renderer returned unicode, and did not specify ' \ 

-

            'a charset value.' 

-

            return bytes(ret.encode(charset)) 

-

        return ret 

-

 

-

    @property 

-

    def status_text(self): 

-

        """ 

-

        Returns reason text corresponding to our HTTP response status code. 

-

        Provided for convenience. 

-

        """ 

-

        # TODO: Deprecate and use a template tag instead 

-

        # TODO: Status code text for RFC 6585 status codes 

-

        return STATUS_CODE_TEXT.get(self.status_code, '') 

-

 

-

    def __getstate__(self): 

-

        """ 

-

        Remove attributes from the response that shouldn't be cached 

-

        """ 

-

        state = super(Response, self).__getstate__() 

-

        for key in ('accepted_renderer', 'renderer_context', 'data'): 

-

            if key in state: 

-

                del state[key] 

-

        return state 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_reverse.html b/htmlcov/rest_framework_reverse.html deleted file mode 100644 index 4e7a8de23..000000000 --- a/htmlcov/rest_framework_reverse.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - Coverage for rest_framework/reverse: 75% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

- -
-

""" 

-

Provide reverse functions that return fully qualified URLs 

-

""" 

-

from __future__ import unicode_literals 

-

from django.core.urlresolvers import reverse as django_reverse 

-

from django.utils.functional import lazy 

-

 

-

 

-

def reverse(viewname, args=None, kwargs=None, request=None, format=None, **extra): 

-

    """ 

-

    Same as `django.core.urlresolvers.reverse`, but optionally takes a request 

-

    and returns a fully qualified URL, using the request to get the base URL. 

-

    """ 

-

    if format is not None: 

-

        kwargs = kwargs or {} 

-

        kwargs['format'] = format 

-

    url = django_reverse(viewname, args=args, kwargs=kwargs, **extra) 

-

    if request: 

-

        return request.build_absolute_uri(url) 

-

    return url 

-

 

-

 

-

reverse_lazy = lazy(reverse, str) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_routers.html b/htmlcov/rest_framework_routers.html deleted file mode 100644 index f08d5007e..000000000 --- a/htmlcov/rest_framework_routers.html +++ /dev/null @@ -1,595 +0,0 @@ - - - - - - - - Coverage for rest_framework/routers: 94% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

- -
-

""" 

-

Routers provide a convenient and consistent way of automatically 

-

determining the URL conf for your API. 

-

 

-

They are used by simply instantiating a Router class, and then registering 

-

all the required ViewSets with that router. 

-

 

-

For example, you might have a `urls.py` that looks something like this: 

-

 

-

    router = routers.DefaultRouter() 

-

    router.register('users', UserViewSet, 'user') 

-

    router.register('accounts', AccountViewSet, 'account') 

-

 

-

    urlpatterns = router.urls 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from collections import namedtuple 

-

from rest_framework import views 

-

from rest_framework.compat import patterns, url 

-

from rest_framework.response import Response 

-

from rest_framework.reverse import reverse 

-

from rest_framework.urlpatterns import format_suffix_patterns 

-

 

-

 

-

Route = namedtuple('Route', ['url', 'mapping', 'name', 'initkwargs']) 

-

 

-

 

-

def replace_methodname(format_string, methodname): 

-

    """ 

-

    Partially format a format_string, swapping out any 

-

    '{methodname}' or '{methodnamehyphen}' components. 

-

    """ 

-

    methodnamehyphen = methodname.replace('_', '-') 

-

    ret = format_string 

-

    ret = ret.replace('{methodname}', methodname) 

-

    ret = ret.replace('{methodnamehyphen}', methodnamehyphen) 

-

    return ret 

-

 

-

 

-

class BaseRouter(object): 

-

    def __init__(self): 

-

        self.registry = [] 

-

 

-

    def register(self, prefix, viewset, base_name=None): 

-

        if base_name is None: 

-

            base_name = self.get_default_base_name(viewset) 

-

        self.registry.append((prefix, viewset, base_name)) 

-

 

-

    def get_default_base_name(self, viewset): 

-

        """ 

-

        If `base_name` is not specified, attempt to automatically determine 

-

        it from the viewset. 

-

        """ 

-

        raise NotImplemented('get_default_base_name must be overridden') 

-

 

-

    def get_urls(self): 

-

        """ 

-

        Return a list of URL patterns, given the registered viewsets. 

-

        """ 

-

        raise NotImplemented('get_urls must be overridden') 

-

 

-

    @property 

-

    def urls(self): 

-

        if not hasattr(self, '_urls'): 

-

            self._urls = patterns('', *self.get_urls()) 

-

        return self._urls 

-

 

-

 

-

class SimpleRouter(BaseRouter): 

-

    routes = [ 

-

        # List route. 

-

        Route( 

-

            url=r'^{prefix}{trailing_slash}$', 

-

            mapping={ 

-

                'get': 'list', 

-

                'post': 'create' 

-

            }, 

-

            name='{basename}-list', 

-

            initkwargs={'suffix': 'List'} 

-

        ), 

-

        # Detail route. 

-

        Route( 

-

            url=r'^{prefix}/{lookup}{trailing_slash}$', 

-

            mapping={ 

-

                'get': 'retrieve', 

-

                'put': 'update', 

-

                'patch': 'partial_update', 

-

                'delete': 'destroy' 

-

            }, 

-

            name='{basename}-detail', 

-

            initkwargs={'suffix': 'Instance'} 

-

        ), 

-

        # Dynamically generated routes. 

-

        # Generated using @action or @link decorators on methods of the viewset. 

-

        Route( 

-

            url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$', 

-

            mapping={ 

-

                '{httpmethod}': '{methodname}', 

-

            }, 

-

            name='{basename}-{methodnamehyphen}', 

-

            initkwargs={} 

-

        ), 

-

    ] 

-

 

-

    def __init__(self, trailing_slash=True): 

-

        self.trailing_slash = trailing_slash and '/' or '' 

-

        super(SimpleRouter, self).__init__() 

-

 

-

    def get_default_base_name(self, viewset): 

-

        """ 

-

        If `base_name` is not specified, attempt to automatically determine 

-

        it from the viewset. 

-

        """ 

-

        model_cls = getattr(viewset, 'model', None) 

-

        queryset = getattr(viewset, 'queryset', None) 

-

        if model_cls is None and queryset is not None: 

-

            model_cls = queryset.model 

-

 

-

        assert model_cls, '`name` not argument not specified, and could ' \ 

-

            'not automatically determine the name from the viewset, as ' \ 

-

            'it does not have a `.model` or `.queryset` attribute.' 

-

 

-

        return model_cls._meta.object_name.lower() 

-

 

-

    def get_routes(self, viewset): 

-

        """ 

-

        Augment `self.routes` with any dynamically generated routes. 

-

 

-

        Returns a list of the Route namedtuple. 

-

        """ 

-

 

-

        # Determine any `@action` or `@link` decorated methods on the viewset 

-

        dynamic_routes = [] 

-

        for methodname in dir(viewset): 

-

            attr = getattr(viewset, methodname) 

-

            httpmethods = getattr(attr, 'bind_to_methods', None) 

-

            if httpmethods: 

-

                dynamic_routes.append((httpmethods, methodname)) 

-

 

-

        ret = [] 

-

        for route in self.routes: 

-

            if route.mapping == {'{httpmethod}': '{methodname}'}: 

-

                # Dynamic routes (@link or @action decorator) 

-

                for httpmethods, methodname in dynamic_routes: 

-

                    initkwargs = route.initkwargs.copy() 

-

                    initkwargs.update(getattr(viewset, methodname).kwargs) 

-

                    ret.append(Route( 

-

                        url=replace_methodname(route.url, methodname), 

-

                        mapping=dict((httpmethod, methodname) for httpmethod in httpmethods), 

-

                        name=replace_methodname(route.name, methodname), 

-

                        initkwargs=initkwargs, 

-

                    )) 

-

            else: 

-

                # Standard route 

-

                ret.append(route) 

-

 

-

        return ret 

-

 

-

    def get_method_map(self, viewset, method_map): 

-

        """ 

-

        Given a viewset, and a mapping of http methods to actions, 

-

        return a new mapping which only includes any mappings that 

-

        are actually implemented by the viewset. 

-

        """ 

-

        bound_methods = {} 

-

        for method, action in method_map.items(): 

-

            if hasattr(viewset, action): 

-

                bound_methods[method] = action 

-

        return bound_methods 

-

 

-

    def get_lookup_regex(self, viewset): 

-

        """ 

-

        Given a viewset, return the portion of URL regex that is used 

-

        to match against a single instance. 

-

        """ 

-

        base_regex = '(?P<{lookup_field}>[^/]+)' 

-

        lookup_field = getattr(viewset, 'lookup_field', 'pk') 

-

        return base_regex.format(lookup_field=lookup_field) 

-

 

-

    def get_urls(self): 

-

        """ 

-

        Use the registered viewsets to generate a list of URL patterns. 

-

        """ 

-

        ret = [] 

-

 

-

        for prefix, viewset, basename in self.registry: 

-

            lookup = self.get_lookup_regex(viewset) 

-

            routes = self.get_routes(viewset) 

-

 

-

            for route in routes: 

-

 

-

                # Only actions which actually exist on the viewset will be bound 

-

                mapping = self.get_method_map(viewset, route.mapping) 

-

                if not mapping: 

-

                    continue 

-

 

-

                # Build the url pattern 

-

                regex = route.url.format( 

-

                    prefix=prefix, 

-

                    lookup=lookup, 

-

                    trailing_slash=self.trailing_slash 

-

                ) 

-

                view = viewset.as_view(mapping, **route.initkwargs) 

-

                name = route.name.format(basename=basename) 

-

                ret.append(url(regex, view, name=name)) 

-

 

-

        return ret 

-

 

-

 

-

class DefaultRouter(SimpleRouter): 

-

    """ 

-

    The default router extends the SimpleRouter, but also adds in a default 

-

    API root view, and adds format suffix patterns to the URLs. 

-

    """ 

-

    include_root_view = True 

-

    include_format_suffixes = True 

-

    root_view_name = 'api-root' 

-

 

-

    def get_api_root_view(self): 

-

        """ 

-

        Return a view to use as the API root. 

-

        """ 

-

        api_root_dict = {} 

-

        list_name = self.routes[0].name 

-

        for prefix, viewset, basename in self.registry: 

-

            api_root_dict[prefix] = list_name.format(basename=basename) 

-

 

-

        class APIRoot(views.APIView): 

-

            _ignore_model_permissions = True 

-

 

-

            def get(self, request, format=None): 

-

                ret = {} 

-

                for key, url_name in api_root_dict.items(): 

-

                    ret[key] = reverse(url_name, request=request, format=format) 

-

                return Response(ret) 

-

 

-

        return APIRoot.as_view() 

-

 

-

    def get_urls(self): 

-

        """ 

-

        Generate the list of URL patterns, including a default root view 

-

        for the API, and appending `.json` style format suffixes. 

-

        """ 

-

        urls = [] 

-

 

-

        if self.include_root_view: 

-

            root_url = url(r'^$', self.get_api_root_view(), name=self.root_view_name) 

-

            urls.append(root_url) 

-

 

-

        default_urls = super(DefaultRouter, self).get_urls() 

-

        urls.extend(default_urls) 

-

 

-

        if self.include_format_suffixes: 

-

            urls = format_suffix_patterns(urls) 

-

 

-

        return urls 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_serializers.html b/htmlcov/rest_framework_serializers.html deleted file mode 100644 index 79dc56474..000000000 --- a/htmlcov/rest_framework_serializers.html +++ /dev/null @@ -1,2011 +0,0 @@ - - - - - - - - Coverage for rest_framework/serializers: 94% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

-

357

-

358

-

359

-

360

-

361

-

362

-

363

-

364

-

365

-

366

-

367

-

368

-

369

-

370

-

371

-

372

-

373

-

374

-

375

-

376

-

377

-

378

-

379

-

380

-

381

-

382

-

383

-

384

-

385

-

386

-

387

-

388

-

389

-

390

-

391

-

392

-

393

-

394

-

395

-

396

-

397

-

398

-

399

-

400

-

401

-

402

-

403

-

404

-

405

-

406

-

407

-

408

-

409

-

410

-

411

-

412

-

413

-

414

-

415

-

416

-

417

-

418

-

419

-

420

-

421

-

422

-

423

-

424

-

425

-

426

-

427

-

428

-

429

-

430

-

431

-

432

-

433

-

434

-

435

-

436

-

437

-

438

-

439

-

440

-

441

-

442

-

443

-

444

-

445

-

446

-

447

-

448

-

449

-

450

-

451

-

452

-

453

-

454

-

455

-

456

-

457

-

458

-

459

-

460

-

461

-

462

-

463

-

464

-

465

-

466

-

467

-

468

-

469

-

470

-

471

-

472

-

473

-

474

-

475

-

476

-

477

-

478

-

479

-

480

-

481

-

482

-

483

-

484

-

485

-

486

-

487

-

488

-

489

-

490

-

491

-

492

-

493

-

494

-

495

-

496

-

497

-

498

-

499

-

500

-

501

-

502

-

503

-

504

-

505

-

506

-

507

-

508

-

509

-

510

-

511

-

512

-

513

-

514

-

515

-

516

-

517

-

518

-

519

-

520

-

521

-

522

-

523

-

524

-

525

-

526

-

527

-

528

-

529

-

530

-

531

-

532

-

533

-

534

-

535

-

536

-

537

-

538

-

539

-

540

-

541

-

542

-

543

-

544

-

545

-

546

-

547

-

548

-

549

-

550

-

551

-

552

-

553

-

554

-

555

-

556

-

557

-

558

-

559

-

560

-

561

-

562

-

563

-

564

-

565

-

566

-

567

-

568

-

569

-

570

-

571

-

572

-

573

-

574

-

575

-

576

-

577

-

578

-

579

-

580

-

581

-

582

-

583

-

584

-

585

-

586

-

587

-

588

-

589

-

590

-

591

-

592

-

593

-

594

-

595

-

596

-

597

-

598

-

599

-

600

-

601

-

602

-

603

-

604

-

605

-

606

-

607

-

608

-

609

-

610

-

611

-

612

-

613

-

614

-

615

-

616

-

617

-

618

-

619

-

620

-

621

-

622

-

623

-

624

-

625

-

626

-

627

-

628

-

629

-

630

-

631

-

632

-

633

-

634

-

635

-

636

-

637

-

638

-

639

-

640

-

641

-

642

-

643

-

644

-

645

-

646

-

647

-

648

-

649

-

650

-

651

-

652

-

653

-

654

-

655

-

656

-

657

-

658

-

659

-

660

-

661

-

662

-

663

-

664

-

665

-

666

-

667

-

668

-

669

-

670

-

671

-

672

-

673

-

674

-

675

-

676

-

677

-

678

-

679

-

680

-

681

-

682

-

683

-

684

-

685

-

686

-

687

-

688

-

689

-

690

-

691

-

692

-

693

-

694

-

695

-

696

-

697

-

698

-

699

-

700

-

701

-

702

-

703

-

704

-

705

-

706

-

707

-

708

-

709

-

710

-

711

-

712

-

713

-

714

-

715

-

716

-

717

-

718

-

719

-

720

-

721

-

722

-

723

-

724

-

725

-

726

-

727

-

728

-

729

-

730

-

731

-

732

-

733

-

734

-

735

-

736

-

737

-

738

-

739

-

740

-

741

-

742

-

743

-

744

-

745

-

746

-

747

-

748

-

749

-

750

-

751

-

752

-

753

-

754

-

755

-

756

-

757

-

758

-

759

-

760

-

761

-

762

-

763

-

764

-

765

-

766

-

767

-

768

-

769

-

770

-

771

-

772

-

773

-

774

-

775

-

776

-

777

-

778

-

779

-

780

-

781

-

782

-

783

-

784

-

785

-

786

-

787

-

788

-

789

-

790

-

791

-

792

-

793

-

794

-

795

-

796

-

797

-

798

-

799

-

800

-

801

-

802

-

803

-

804

-

805

-

806

-

807

-

808

-

809

-

810

-

811

-

812

-

813

-

814

-

815

-

816

-

817

-

818

-

819

-

820

-

821

-

822

-

823

-

824

-

825

-

826

-

827

-

828

-

829

-

830

-

831

-

832

-

833

-

834

-

835

-

836

-

837

-

838

-

839

-

840

-

841

-

842

-

843

-

844

-

845

-

846

-

847

-

848

-

849

-

850

-

851

-

852

-

853

-

854

-

855

-

856

-

857

-

858

-

859

-

860

-

861

-

862

-

863

-

864

-

865

-

866

-

867

-

868

-

869

-

870

-

871

-

872

-

873

-

874

-

875

-

876

-

877

-

878

-

879

-

880

-

881

-

882

-

883

-

884

-

885

-

886

-

887

-

888

-

889

-

890

-

891

-

892

-

893

-

894

-

895

-

896

-

897

-

898

-

899

-

900

-

901

-

902

-

903

-

904

-

905

-

906

-

907

-

908

-

909

-

910

-

911

-

912

-

913

-

914

-

915

-

916

-

917

-

918

-

919

-

920

-

921

-

922

-

923

-

924

-

925

-

926

-

927

-

928

-

929

-

930

-

931

-

932

-

933

-

934

-

935

-

936

-

937

-

938

-

939

-

940

-

941

-

942

-

943

-

944

-

945

-

946

-

947

-

948

-

949

-

950

-

951

-

952

-

953

-

954

-

955

-

956

-

957

-

958

-

959

-

960

-

961

-

962

-

963

-

964

-

965

- -
-

""" 

-

Serializers and ModelSerializers are similar to Forms and ModelForms. 

-

Unlike forms, they are not constrained to dealing with HTML output, and 

-

form encoded input. 

-

 

-

Serialization in REST framework is a two-phase process: 

-

 

-

1. Serializers marshal between complex types like model instances, and 

-

python primatives. 

-

2. The process of marshalling between python primatives and request and 

-

response content is handled by parsers and renderers. 

-

""" 

-

from __future__ import unicode_literals 

-

import copy 

-

import datetime 

-

import types 

-

from decimal import Decimal 

-

from django.core.paginator import Page 

-

from django.db import models 

-

from django.forms import widgets 

-

from django.utils.datastructures import SortedDict 

-

from rest_framework.compat import get_concrete_model, six 

-

 

-

# Note: We do the following so that users of the framework can use this style: 

-

# 

-

#     example_field = serializers.CharField(...) 

-

# 

-

# This helps keep the separation between model fields, form fields, and 

-

# serializer fields more explicit. 

-

 

-

from rest_framework.relations import * 

-

from rest_framework.fields import * 

-

 

-

 

-

class NestedValidationError(ValidationError): 

-

    """ 

-

    The default ValidationError behavior is to stringify each item in the list 

-

    if the messages are a list of error messages. 

-

 

-

    In the case of nested serializers, where the parent has many children, 

-

    then the child's `serializer.errors` will be a list of dicts.  In the case 

-

    of a single child, the `serializer.errors` will be a dict. 

-

 

-

    We need to override the default behavior to get properly nested error dicts. 

-

    """ 

-

 

-

    def __init__(self, message): 

-

        if isinstance(message, dict): 

-

            self.messages = [message] 

-

        else: 

-

            self.messages = message 

-

 

-

 

-

class DictWithMetadata(dict): 

-

    """ 

-

    A dict-like object, that can have additional properties attached. 

-

    """ 

-

    def __getstate__(self): 

-

        """ 

-

        Used by pickle (e.g., caching). 

-

        Overridden to remove the metadata from the dict, since it shouldn't be 

-

        pickled and may in some instances be unpickleable. 

-

        """ 

-

        return dict(self) 

-

 

-

 

-

class SortedDictWithMetadata(SortedDict): 

-

    """ 

-

    A sorted dict-like object, that can have additional properties attached. 

-

    """ 

-

    def __getstate__(self): 

-

        """ 

-

        Used by pickle (e.g., caching). 

-

        Overriden to remove the metadata from the dict, since it shouldn't be 

-

        pickle and may in some instances be unpickleable. 

-

        """ 

-

        return SortedDict(self).__dict__ 

-

 

-

 

-

def _is_protected_type(obj): 

-

    """ 

-

    True if the object is a native datatype that does not need to 

-

    be serialized further. 

-

    """ 

-

    return isinstance(obj, ( 

-

        types.NoneType, 

-

        int, long, 

-

        datetime.datetime, datetime.date, datetime.time, 

-

        float, Decimal, 

-

        basestring) 

-

    ) 

-

 

-

 

-

def _get_declared_fields(bases, attrs): 

-

    """ 

-

    Create a list of serializer field instances from the passed in 'attrs', 

-

    plus any fields on the base classes (in 'bases'). 

-

 

-

    Note that all fields from the base classes are used. 

-

    """ 

-

    fields = [(field_name, attrs.pop(field_name)) 

-

              for field_name, obj in list(six.iteritems(attrs)) 

-

              if isinstance(obj, Field)] 

-

    fields.sort(key=lambda x: x[1].creation_counter) 

-

 

-

    # If this class is subclassing another Serializer, add that Serializer's 

-

    # fields.  Note that we loop over the bases in *reverse*. This is necessary 

-

    # in order to maintain the correct order of fields. 

-

    for base in bases[::-1]: 

-

        if hasattr(base, 'base_fields'): 

-

            fields = list(base.base_fields.items()) + fields 

-

 

-

    return SortedDict(fields) 

-

 

-

 

-

class SerializerMetaclass(type): 

-

    def __new__(cls, name, bases, attrs): 

-

        attrs['base_fields'] = _get_declared_fields(bases, attrs) 

-

        return super(SerializerMetaclass, cls).__new__(cls, name, bases, attrs) 

-

 

-

 

-

class SerializerOptions(object): 

-

    """ 

-

    Meta class options for Serializer 

-

    """ 

-

    def __init__(self, meta): 

-

        self.depth = getattr(meta, 'depth', 0) 

-

        self.fields = getattr(meta, 'fields', ()) 

-

        self.exclude = getattr(meta, 'exclude', ()) 

-

 

-

 

-

class BaseSerializer(WritableField): 

-

    """ 

-

    This is the Serializer implementation. 

-

    We need to implement it as `BaseSerializer` due to metaclass magicks. 

-

    """ 

-

    class Meta(object): 

-

        pass 

-

 

-

    _options_class = SerializerOptions 

-

    _dict_class = SortedDictWithMetadata 

-

 

-

    def __init__(self, instance=None, data=None, files=None, 

-

                 context=None, partial=False, many=None, 

-

                 allow_add_remove=False, **kwargs): 

-

        super(BaseSerializer, self).__init__(**kwargs) 

-

        self.opts = self._options_class(self.Meta) 

-

        self.parent = None 

-

        self.root = None 

-

        self.partial = partial 

-

        self.many = many 

-

        self.allow_add_remove = allow_add_remove 

-

 

-

        self.context = context or {} 

-

 

-

        self.init_data = data 

-

        self.init_files = files 

-

        self.object = instance 

-

        self.fields = self.get_fields() 

-

 

-

        self._data = None 

-

        self._files = None 

-

        self._errors = None 

-

        self._deleted = None 

-

 

-

        if many and instance is not None and not hasattr(instance, '__iter__'): 

-

            raise ValueError('instance should be a queryset or other iterable with many=True') 

-

 

-

        if allow_add_remove and not many: 

-

            raise ValueError('allow_add_remove should only be used for bulk updates, but you have not set many=True') 

-

 

-

    ##### 

-

    # Methods to determine which fields to use when (de)serializing objects. 

-

 

-

    def get_default_fields(self): 

-

        """ 

-

        Return the complete set of default fields for the object, as a dict. 

-

        """ 

-

        return {} 

-

 

-

    def get_fields(self): 

-

        """ 

-

        Returns the complete set of fields for the object as a dict. 

-

 

-

        This will be the set of any explicitly declared fields, 

-

        plus the set of fields returned by get_default_fields(). 

-

        """ 

-

        ret = SortedDict() 

-

 

-

        # Get the explicitly declared fields 

-

        base_fields = copy.deepcopy(self.base_fields) 

-

        for key, field in base_fields.items(): 

-

            ret[key] = field 

-

 

-

        # Add in the default fields 

-

        default_fields = self.get_default_fields() 

-

        for key, val in default_fields.items(): 

-

            if key not in ret: 

-

                ret[key] = val 

-

 

-

        # If 'fields' is specified, use those fields, in that order. 

-

        if self.opts.fields: 

-

            assert isinstance(self.opts.fields, (list, tuple)), '`fields` must be a list or tuple' 

-

            new = SortedDict() 

-

            for key in self.opts.fields: 

-

                new[key] = ret[key] 

-

            ret = new 

-

 

-

        # Remove anything in 'exclude' 

-

        if self.opts.exclude: 

-

            assert isinstance(self.opts.exclude, (list, tuple)), '`exclude` must be a list or tuple' 

-

            for key in self.opts.exclude: 

-

                ret.pop(key, None) 

-

 

-

        for key, field in ret.items(): 

-

            field.initialize(parent=self, field_name=key) 

-

 

-

        return ret 

-

 

-

    ##### 

-

    # Methods to convert or revert from objects <--> primitive representations. 

-

 

-

    def get_field_key(self, field_name): 

-

        """ 

-

        Return the key that should be used for a given field. 

-

        """ 

-

        return field_name 

-

 

-

    def restore_fields(self, data, files): 

-

        """ 

-

        Core of deserialization, together with `restore_object`. 

-

        Converts a dictionary of data into a dictionary of deserialized fields. 

-

        """ 

-

        reverted_data = {} 

-

 

-

        if data is not None and not isinstance(data, dict): 

-

            self._errors['non_field_errors'] = ['Invalid data'] 

-

            return None 

-

 

-

        for field_name, field in self.fields.items(): 

-

            field.initialize(parent=self, field_name=field_name) 

-

            try: 

-

                field.field_from_native(data, files, field_name, reverted_data) 

-

            except ValidationError as err: 

-

                self._errors[field_name] = list(err.messages) 

-

 

-

        return reverted_data 

-

 

-

    def perform_validation(self, attrs): 

-

        """ 

-

        Run `validate_<fieldname>()` and `validate()` methods on the serializer 

-

        """ 

-

        for field_name, field in self.fields.items(): 

-

            if field_name in self._errors: 

-

                continue 

-

            try: 

-

                validate_method = getattr(self, 'validate_%s' % field_name, None) 

-

                if validate_method: 

-

                    source = field.source or field_name 

-

                    attrs = validate_method(attrs, source) 

-

            except ValidationError as err: 

-

                self._errors[field_name] = self._errors.get(field_name, []) + list(err.messages) 

-

 

-

        # If there are already errors, we don't run .validate() because 

-

        # field-validation failed and thus `attrs` may not be complete. 

-

        # which in turn can cause inconsistent validation errors. 

-

        if not self._errors: 

-

            try: 

-

                attrs = self.validate(attrs) 

-

            except ValidationError as err: 

-

                if hasattr(err, 'message_dict'): 

-

                    for field_name, error_messages in err.message_dict.items(): 

-

                        self._errors[field_name] = self._errors.get(field_name, []) + list(error_messages) 

-

                elif hasattr(err, 'messages'): 

-

                    self._errors['non_field_errors'] = err.messages 

-

 

-

        return attrs 

-

 

-

    def validate(self, attrs): 

-

        """ 

-

        Stub method, to be overridden in Serializer subclasses 

-

        """ 

-

        return attrs 

-

 

-

    def restore_object(self, attrs, instance=None): 

-

        """ 

-

        Deserialize a dictionary of attributes into an object instance. 

-

        You should override this method to control how deserialized objects 

-

        are instantiated. 

-

        """ 

-

        if instance is not None: 

-

            instance.update(attrs) 

-

            return instance 

-

        return attrs 

-

 

-

    def to_native(self, obj): 

-

        """ 

-

        Serialize objects -> primitives. 

-

        """ 

-

        ret = self._dict_class() 

-

        ret.fields = {} 

-

 

-

        for field_name, field in self.fields.items(): 

-

            field.initialize(parent=self, field_name=field_name) 

-

            key = self.get_field_key(field_name) 

-

            value = field.field_to_native(obj, field_name) 

-

            ret[key] = value 

-

            ret.fields[key] = field 

-

        return ret 

-

 

-

    def from_native(self, data, files): 

-

        """ 

-

        Deserialize primitives -> objects. 

-

        """ 

-

        self._errors = {} 

-

        if data is not None or files is not None: 

-

            attrs = self.restore_fields(data, files) 

-

            if attrs is not None: 

-

                attrs = self.perform_validation(attrs) 

-

        else: 

-

            self._errors['non_field_errors'] = ['No input provided'] 

-

 

-

        if not self._errors: 

-

            return self.restore_object(attrs, instance=getattr(self, 'object', None)) 

-

 

-

    def field_to_native(self, obj, field_name): 

-

        """ 

-

        Override default so that the serializer can be used as a nested field 

-

        across relationships. 

-

        """ 

-

        if self.source == '*': 

-

            return self.to_native(obj) 

-

 

-

        try: 

-

            source = self.source or field_name 

-

            value = obj 

-

 

-

            for component in source.split('.'): 

-

                value = get_component(value, component) 

-

                if value is None: 

-

                    break 

-

        except ObjectDoesNotExist: 

-

            return None 

-

 

-

        if is_simple_callable(getattr(value, 'all', None)): 

-

            return [self.to_native(item) for item in value.all()] 

-

 

-

        if value is None: 

-

            return None 

-

 

-

        if self.many is not None: 

-

            many = self.many 

-

        else: 

-

            many = hasattr(value, '__iter__') and not isinstance(value, (Page, dict, six.text_type)) 

-

 

-

        if many: 

-

            return [self.to_native(item) for item in value] 

-

        return self.to_native(value) 

-

 

-

    def field_from_native(self, data, files, field_name, into): 

-

        """ 

-

        Override default so that the serializer can be used as a writable 

-

        nested field across relationships. 

-

        """ 

-

        if self.read_only: 

-

            return 

-

 

-

        try: 

-

            value = data[field_name] 

-

        except KeyError: 

-

            if self.default is not None and not self.partial: 

-

                # Note: partial updates shouldn't set defaults 

-

                value = copy.deepcopy(self.default) 

-

            else: 

-

                if self.required: 

-

                    raise ValidationError(self.error_messages['required']) 

-

                return 

-

 

-

        # Set the serializer object if it exists 

-

        obj = getattr(self.parent.object, field_name) if self.parent.object else None 

-

 

-

        if self.source == '*': 

-

            if value: 

-

                into.update(value) 

-

        else: 

-

            if value in (None, ''): 

-

                into[(self.source or field_name)] = None 

-

            else: 

-

                kwargs = { 

-

                    'instance': obj, 

-

                    'data': value, 

-

                    'context': self.context, 

-

                    'partial': self.partial, 

-

                    'many': self.many 

-

                } 

-

                serializer = self.__class__(**kwargs) 

-

 

-

                if serializer.is_valid(): 

-

                    into[self.source or field_name] = serializer.object 

-

                else: 

-

                    # Propagate errors up to our parent 

-

                    raise NestedValidationError(serializer.errors) 

-

 

-

    def get_identity(self, data): 

-

        """ 

-

        This hook is required for bulk update. 

-

        It is used to determine the canonical identity of a given object. 

-

 

-

        Note that the data has not been validated at this point, so we need 

-

        to make sure that we catch any cases of incorrect datatypes being 

-

        passed to this method. 

-

        """ 

-

        try: 

-

            return data.get('id', None) 

-

        except AttributeError: 

-

            return None 

-

 

-

    @property 

-

    def errors(self): 

-

        """ 

-

        Run deserialization and return error data, 

-

        setting self.object if no errors occurred. 

-

        """ 

-

        if self._errors is None: 

-

            data, files = self.init_data, self.init_files 

-

 

-

            if self.many is not None: 

-

                many = self.many 

-

            else: 

-

                many = hasattr(data, '__iter__') and not isinstance(data, (Page, dict, six.text_type)) 

-

                if many: 

-

                    warnings.warn('Implict list/queryset serialization is deprecated. ' 

-

                                  'Use the `many=True` flag when instantiating the serializer.', 

-

                                  DeprecationWarning, stacklevel=3) 

-

 

-

            if many: 

-

                ret = [] 

-

                errors = [] 

-

                update = self.object is not None 

-

 

-

                if update: 

-

                    # If this is a bulk update we need to map all the objects 

-

                    # to a canonical identity so we can determine which 

-

                    # individual object is being updated for each item in the 

-

                    # incoming data 

-

                    objects = self.object 

-

                    identities = [self.get_identity(self.to_native(obj)) for obj in objects] 

-

                    identity_to_objects = dict(zip(identities, objects)) 

-

 

-

                if hasattr(data, '__iter__') and not isinstance(data, (dict, six.text_type)): 

-

                    for item in data: 

-

                        if update: 

-

                            # Determine which object we're updating 

-

                            identity = self.get_identity(item) 

-

                            self.object = identity_to_objects.pop(identity, None) 

-

                            if self.object is None and not self.allow_add_remove: 

-

                                ret.append(None) 

-

                                errors.append({'non_field_errors': ['Cannot create a new item, only existing items may be updated.']}) 

-

                                continue 

-

 

-

                        ret.append(self.from_native(item, None)) 

-

                        errors.append(self._errors) 

-

 

-

                    if update: 

-

                        self._deleted = identity_to_objects.values() 

-

 

-

                    self._errors = any(errors) and errors or [] 

-

                else: 

-

                    self._errors = {'non_field_errors': ['Expected a list of items.']} 

-

            else: 

-

                ret = self.from_native(data, files) 

-

 

-

            if not self._errors: 

-

                self.object = ret 

-

 

-

        return self._errors 

-

 

-

    def is_valid(self): 

-

        return not self.errors 

-

 

-

    @property 

-

    def data(self): 

-

        """ 

-

        Returns the serialized data on the serializer. 

-

        """ 

-

        if self._data is None: 

-

            obj = self.object 

-

 

-

            if self.many is not None: 

-

                many = self.many 

-

            else: 

-

                many = hasattr(obj, '__iter__') and not isinstance(obj, (Page, dict)) 

-

                if many: 

-

                    warnings.warn('Implict list/queryset serialization is deprecated. ' 

-

                                  'Use the `many=True` flag when instantiating the serializer.', 

-

                                  DeprecationWarning, stacklevel=2) 

-

 

-

            if many: 

-

                self._data = [self.to_native(item) for item in obj] 

-

            else: 

-

                self._data = self.to_native(obj) 

-

 

-

        return self._data 

-

 

-

    def save_object(self, obj, **kwargs): 

-

        obj.save(**kwargs) 

-

 

-

    def delete_object(self, obj): 

-

        obj.delete() 

-

 

-

    def save(self, **kwargs): 

-

        """ 

-

        Save the deserialized object and return it. 

-

        """ 

-

        if isinstance(self.object, list): 

-

            [self.save_object(item, **kwargs) for item in self.object] 

-

        else: 

-

            self.save_object(self.object, **kwargs) 

-

 

-

        if self.allow_add_remove and self._deleted: 

-

            [self.delete_object(item) for item in self._deleted] 

-

 

-

        return self.object 

-

 

-

    def metadata(self): 

-

        """ 

-

        Return a dictionary of metadata about the fields on the serializer. 

-

        Useful for things like responding to OPTIONS requests, or generating 

-

        API schemas for auto-documentation. 

-

        """ 

-

        return SortedDict( 

-

            [(field_name, field.metadata()) 

-

            for field_name, field in six.iteritems(self.fields)] 

-

        ) 

-

 

-

 

-

class Serializer(six.with_metaclass(SerializerMetaclass, BaseSerializer)): 

-

    pass 

-

 

-

 

-

class ModelSerializerOptions(SerializerOptions): 

-

    """ 

-

    Meta class options for ModelSerializer 

-

    """ 

-

    def __init__(self, meta): 

-

        super(ModelSerializerOptions, self).__init__(meta) 

-

        self.model = getattr(meta, 'model', None) 

-

        self.read_only_fields = getattr(meta, 'read_only_fields', ()) 

-

 

-

 

-

class ModelSerializer(Serializer): 

-

    """ 

-

    A serializer that deals with model instances and querysets. 

-

    """ 

-

    _options_class = ModelSerializerOptions 

-

 

-

    field_mapping = { 

-

        models.AutoField: IntegerField, 

-

        models.FloatField: FloatField, 

-

        models.IntegerField: IntegerField, 

-

        models.PositiveIntegerField: IntegerField, 

-

        models.SmallIntegerField: IntegerField, 

-

        models.PositiveSmallIntegerField: IntegerField, 

-

        models.DateTimeField: DateTimeField, 

-

        models.DateField: DateField, 

-

        models.TimeField: TimeField, 

-

        models.DecimalField: DecimalField, 

-

        models.EmailField: EmailField, 

-

        models.CharField: CharField, 

-

        models.URLField: URLField, 

-

        models.SlugField: SlugField, 

-

        models.TextField: CharField, 

-

        models.CommaSeparatedIntegerField: CharField, 

-

        models.BooleanField: BooleanField, 

-

        models.FileField: FileField, 

-

        models.ImageField: ImageField, 

-

    } 

-

 

-

    def get_default_fields(self): 

-

        """ 

-

        Return all the fields that should be serialized for the model. 

-

        """ 

-

 

-

        cls = self.opts.model 

-

        assert cls is not None, \ 

-

                "Serializer class '%s' is missing 'model' Meta option" % self.__class__.__name__ 

-

        opts = get_concrete_model(cls)._meta 

-

        ret = SortedDict() 

-

        nested = bool(self.opts.depth) 

-

 

-

        # Deal with adding the primary key field 

-

        pk_field = opts.pk 

-

        while pk_field.rel and pk_field.rel.parent_link: 

-

            # If model is a child via multitable inheritance, use parent's pk 

-

            pk_field = pk_field.rel.to._meta.pk 

-

 

-

        field = self.get_pk_field(pk_field) 

-

        if field: 

-

            ret[pk_field.name] = field 

-

 

-

        # Deal with forward relationships 

-

        forward_rels = [field for field in opts.fields if field.serialize] 

-

        forward_rels += [field for field in opts.many_to_many if field.serialize] 

-

 

-

        for model_field in forward_rels: 

-

            has_through_model = False 

-

 

-

            if model_field.rel: 

-

                to_many = isinstance(model_field, 

-

                                     models.fields.related.ManyToManyField) 

-

                related_model = model_field.rel.to 

-

 

-

                if to_many and not model_field.rel.through._meta.auto_created: 

-

                    has_through_model = True 

-

 

-

            if model_field.rel and nested: 

-

                if len(inspect.getargspec(self.get_nested_field).args) == 2: 

-

                    warnings.warn( 

-

                        'The `get_nested_field(model_field)` call signature ' 

-

                        'is due to be deprecated. ' 

-

                        'Use `get_nested_field(model_field, related_model, ' 

-

                        'to_many) instead', 

-

                        PendingDeprecationWarning 

-

                    ) 

-

                    field = self.get_nested_field(model_field) 

-

                else: 

-

                    field = self.get_nested_field(model_field, related_model, to_many) 

-

            elif model_field.rel: 

-

                if len(inspect.getargspec(self.get_nested_field).args) == 3: 

-

                    warnings.warn( 

-

                        'The `get_related_field(model_field, to_many)` call ' 

-

                        'signature is due to be deprecated. ' 

-

                        'Use `get_related_field(model_field, related_model, ' 

-

                        'to_many) instead', 

-

                        PendingDeprecationWarning 

-

                    ) 

-

                    field = self.get_related_field(model_field, to_many=to_many) 

-

                else: 

-

                    field = self.get_related_field(model_field, related_model, to_many) 

-

            else: 

-

                field = self.get_field(model_field) 

-

 

-

            if field: 

-

                if has_through_model: 

-

                    field.read_only = True 

-

 

-

                ret[model_field.name] = field 

-

 

-

        # Deal with reverse relationships 

-

        if not self.opts.fields: 

-

            reverse_rels = [] 

-

        else: 

-

            # Reverse relationships are only included if they are explicitly 

-

            # present in the `fields` option on the serializer 

-

            reverse_rels = opts.get_all_related_objects() 

-

            reverse_rels += opts.get_all_related_many_to_many_objects() 

-

 

-

        for relation in reverse_rels: 

-

            accessor_name = relation.get_accessor_name() 

-

            if not self.opts.fields or accessor_name not in self.opts.fields: 

-

                continue 

-

            related_model = relation.model 

-

            to_many = relation.field.rel.multiple 

-

            has_through_model = False 

-

            is_m2m = isinstance(relation.field, 

-

                                models.fields.related.ManyToManyField) 

-

 

-

            if is_m2m and not relation.field.rel.through._meta.auto_created: 

-

                has_through_model = True 

-

 

-

            if nested: 

-

                field = self.get_nested_field(None, related_model, to_many) 

-

            else: 

-

                field = self.get_related_field(None, related_model, to_many) 

-

 

-

            if field: 

-

                if has_through_model: 

-

                    field.read_only = True 

-

 

-

                ret[accessor_name] = field 

-

 

-

        # Add the `read_only` flag to any fields that have bee specified 

-

        # in the `read_only_fields` option 

-

        for field_name in self.opts.read_only_fields: 

-

            assert field_name not in self.base_fields.keys(), \ 

-

                "field '%s' on serializer '%s' specfied in " \ 

-

                "`read_only_fields`, but also added " \ 

-

                "as an explict field.  Remove it from `read_only_fields`." % \ 

-

                (field_name, self.__class__.__name__) 

-

            assert field_name in ret, \ 

-

                "Noexistant field '%s' specified in `read_only_fields` " \ 

-

                "on serializer '%s'." % \ 

-

                (self.__class__.__name__, field_name) 

-

            ret[field_name].read_only = True 

-

 

-

        return ret 

-

 

-

    def get_pk_field(self, model_field): 

-

        """ 

-

        Returns a default instance of the pk field. 

-

        """ 

-

        return self.get_field(model_field) 

-

 

-

    def get_nested_field(self, model_field, related_model, to_many): 

-

        """ 

-

        Creates a default instance of a nested relational field. 

-

 

-

        Note that model_field will be `None` for reverse relationships. 

-

        """ 

-

        class NestedModelSerializer(ModelSerializer): 

-

            class Meta: 

-

                model = related_model 

-

                depth = self.opts.depth - 1 

-

 

-

        return NestedModelSerializer(many=to_many) 

-

 

-

    def get_related_field(self, model_field, related_model, to_many): 

-

        """ 

-

        Creates a default instance of a flat relational field. 

-

 

-

        Note that model_field will be `None` for reverse relationships. 

-

        """ 

-

        # TODO: filter queryset using: 

-

        # .using(db).complex_filter(self.rel.limit_choices_to) 

-

 

-

        kwargs = { 

-

            'queryset': related_model._default_manager, 

-

            'many': to_many 

-

        } 

-

 

-

        if model_field: 

-

            kwargs['required'] = not(model_field.null or model_field.blank) 

-

 

-

        return PrimaryKeyRelatedField(**kwargs) 

-

 

-

    def get_field(self, model_field): 

-

        """ 

-

        Creates a default instance of a basic non-relational field. 

-

        """ 

-

        kwargs = {} 

-

 

-

        if model_field.null or model_field.blank: 

-

            kwargs['required'] = False 

-

 

-

        if isinstance(model_field, models.AutoField) or not model_field.editable: 

-

            kwargs['read_only'] = True 

-

 

-

        if model_field.has_default(): 

-

            kwargs['default'] = model_field.get_default() 

-

 

-

        if issubclass(model_field.__class__, models.TextField): 

-

            kwargs['widget'] = widgets.Textarea 

-

 

-

        if model_field.verbose_name is not None: 

-

            kwargs['label'] = model_field.verbose_name 

-

 

-

        if model_field.help_text is not None: 

-

            kwargs['help_text'] = model_field.help_text 

-

 

-

        # TODO: TypedChoiceField? 

-

        if model_field.flatchoices:  # This ModelField contains choices 

-

            kwargs['choices'] = model_field.flatchoices 

-

            return ChoiceField(**kwargs) 

-

 

-

        # put this below the ChoiceField because min_value isn't a valid initializer 

-

        if issubclass(model_field.__class__, models.PositiveIntegerField) or\ 

-

                issubclass(model_field.__class__, models.PositiveSmallIntegerField): 

-

            kwargs['min_value'] = 0 

-

 

-

        attribute_dict = { 

-

            models.CharField: ['max_length'], 

-

            models.CommaSeparatedIntegerField: ['max_length'], 

-

            models.DecimalField: ['max_digits', 'decimal_places'], 

-

            models.EmailField: ['max_length'], 

-

            models.FileField: ['max_length'], 

-

            models.ImageField: ['max_length'], 

-

            models.SlugField: ['max_length'], 

-

            models.URLField: ['max_length'], 

-

        } 

-

 

-

        if model_field.__class__ in attribute_dict: 

-

            attributes = attribute_dict[model_field.__class__] 

-

            for attribute in attributes: 

-

                kwargs.update({attribute: getattr(model_field, attribute)}) 

-

 

-

        try: 

-

            return self.field_mapping[model_field.__class__](**kwargs) 

-

        except KeyError: 

-

            return ModelField(model_field=model_field, **kwargs) 

-

 

-

    def get_validation_exclusions(self): 

-

        """ 

-

        Return a list of field names to exclude from model validation. 

-

        """ 

-

        cls = self.opts.model 

-

        opts = get_concrete_model(cls)._meta 

-

        exclusions = [field.name for field in opts.fields + opts.many_to_many] 

-

        for field_name, field in self.fields.items(): 

-

            field_name = field.source or field_name 

-

            if field_name in exclusions and not field.read_only: 

-

                exclusions.remove(field_name) 

-

        return exclusions 

-

 

-

    def full_clean(self, instance): 

-

        """ 

-

        Perform Django's full_clean, and populate the `errors` dictionary 

-

        if any validation errors occur. 

-

 

-

        Note that we don't perform this inside the `.restore_object()` method, 

-

        so that subclasses can override `.restore_object()`, and still get 

-

        the full_clean validation checking. 

-

        """ 

-

        try: 

-

            instance.full_clean(exclude=self.get_validation_exclusions()) 

-

        except ValidationError as err: 

-

            self._errors = err.message_dict 

-

            return None 

-

        return instance 

-

 

-

    def restore_object(self, attrs, instance=None): 

-

        """ 

-

        Restore the model instance. 

-

        """ 

-

        m2m_data = {} 

-

        related_data = {} 

-

        meta = self.opts.model._meta 

-

 

-

        # Reverse fk or one-to-one relations 

-

        for (obj, model) in meta.get_all_related_objects_with_model(): 

-

            field_name = obj.field.related_query_name() 

-

            if field_name in attrs: 

-

                related_data[field_name] = attrs.pop(field_name) 

-

 

-

        # Reverse m2m relations 

-

        for (obj, model) in meta.get_all_related_m2m_objects_with_model(): 

-

            field_name = obj.field.related_query_name() 

-

            if field_name in attrs: 

-

                m2m_data[field_name] = attrs.pop(field_name) 

-

 

-

        # Forward m2m relations 

-

        for field in meta.many_to_many: 

-

            if field.name in attrs: 

-

                m2m_data[field.name] = attrs.pop(field.name) 

-

 

-

        # Update an existing instance... 

-

        if instance is not None: 

-

            for key, val in attrs.items(): 

-

                setattr(instance, key, val) 

-

 

-

        # ...or create a new instance 

-

        else: 

-

            instance = self.opts.model(**attrs) 

-

 

-

        # Any relations that cannot be set until we've 

-

        # saved the model get hidden away on these 

-

        # private attributes, so we can deal with them 

-

        # at the point of save. 

-

        instance._related_data = related_data 

-

        instance._m2m_data = m2m_data 

-

 

-

        return instance 

-

 

-

    def from_native(self, data, files): 

-

        """ 

-

        Override the default method to also include model field validation. 

-

        """ 

-

        instance = super(ModelSerializer, self).from_native(data, files) 

-

        if not self._errors: 

-

            return self.full_clean(instance) 

-

 

-

    def save_object(self, obj, **kwargs): 

-

        """ 

-

        Save the deserialized object and return it. 

-

        """ 

-

        obj.save(**kwargs) 

-

 

-

        if getattr(obj, '_m2m_data', None): 

-

            for accessor_name, object_list in obj._m2m_data.items(): 

-

                setattr(obj, accessor_name, object_list) 

-

            del(obj._m2m_data) 

-

 

-

        if getattr(obj, '_related_data', None): 

-

            for accessor_name, related in obj._related_data.items(): 

-

                setattr(obj, accessor_name, related) 

-

            del(obj._related_data) 

-

 

-

 

-

class HyperlinkedModelSerializerOptions(ModelSerializerOptions): 

-

    """ 

-

    Options for HyperlinkedModelSerializer 

-

    """ 

-

    def __init__(self, meta): 

-

        super(HyperlinkedModelSerializerOptions, self).__init__(meta) 

-

        self.view_name = getattr(meta, 'view_name', None) 

-

        self.lookup_field = getattr(meta, 'lookup_field', None) 

-

 

-

 

-

class HyperlinkedModelSerializer(ModelSerializer): 

-

    """ 

-

    A subclass of ModelSerializer that uses hyperlinked relationships, 

-

    instead of primary key relationships. 

-

    """ 

-

    _options_class = HyperlinkedModelSerializerOptions 

-

    _default_view_name = '%(model_name)s-detail' 

-

    _hyperlink_field_class = HyperlinkedRelatedField 

-

 

-

    def get_default_fields(self): 

-

        fields = super(HyperlinkedModelSerializer, self).get_default_fields() 

-

 

-

        if self.opts.view_name is None: 

-

            self.opts.view_name = self._get_default_view_name(self.opts.model) 

-

 

-

        if 'url' not in fields: 

-

            url_field = HyperlinkedIdentityField( 

-

                view_name=self.opts.view_name, 

-

                lookup_field=self.opts.lookup_field 

-

            ) 

-

            fields.insert(0, 'url', url_field) 

-

 

-

        return fields 

-

 

-

    def get_pk_field(self, model_field): 

-

        if self.opts.fields and model_field.name in self.opts.fields: 

-

            return self.get_field(model_field) 

-

 

-

    def get_related_field(self, model_field, related_model, to_many): 

-

        """ 

-

        Creates a default instance of a flat relational field. 

-

        """ 

-

        # TODO: filter queryset using: 

-

        # .using(db).complex_filter(self.rel.limit_choices_to) 

-

        kwargs = { 

-

            'queryset': related_model._default_manager, 

-

            'view_name': self._get_default_view_name(related_model), 

-

            'many': to_many 

-

        } 

-

 

-

        if model_field: 

-

            kwargs['required'] = not(model_field.null or model_field.blank) 

-

 

-

        if self.opts.lookup_field: 

-

            kwargs['lookup_field'] = self.opts.lookup_field 

-

 

-

        return self._hyperlink_field_class(**kwargs) 

-

 

-

    def get_identity(self, data): 

-

        """ 

-

        This hook is required for bulk update. 

-

        We need to override the default, to use the url as the identity. 

-

        """ 

-

        try: 

-

            return data.get('url', None) 

-

        except AttributeError: 

-

            return None 

-

 

-

    def _get_default_view_name(self, model): 

-

        """ 

-

        Return the view name to use if 'view_name' is not specified in 'Meta' 

-

        """ 

-

        model_meta = model._meta 

-

        format_kwargs = { 

-

            'app_label': model_meta.app_label, 

-

            'model_name': model_meta.object_name.lower() 

-

        } 

-

        return self._default_view_name % format_kwargs 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_settings.html b/htmlcov/rest_framework_settings.html deleted file mode 100644 index ae47b5bc8..000000000 --- a/htmlcov/rest_framework_settings.html +++ /dev/null @@ -1,465 +0,0 @@ - - - - - - - - Coverage for rest_framework/settings: 95% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

- -
-

""" 

-

Settings for REST framework are all namespaced in the REST_FRAMEWORK setting. 

-

For example your project's `settings.py` file might look like this: 

-

 

-

REST_FRAMEWORK = { 

-

    'DEFAULT_RENDERER_CLASSES': ( 

-

        'rest_framework.renderers.JSONRenderer', 

-

        'rest_framework.renderers.YAMLRenderer', 

-

    ) 

-

    'DEFAULT_PARSER_CLASSES': ( 

-

        'rest_framework.parsers.JSONParser', 

-

        'rest_framework.parsers.YAMLParser', 

-

    ) 

-

} 

-

 

-

This module provides the `api_setting` object, that is used to access 

-

REST framework settings, checking for user settings first, then falling 

-

back to the defaults. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from django.conf import settings 

-

from django.utils import importlib 

-

 

-

from rest_framework import ISO_8601 

-

from rest_framework.compat import six 

-

 

-

 

-

USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None) 

-

 

-

DEFAULTS = { 

-

    # Base API policies 

-

    'DEFAULT_RENDERER_CLASSES': ( 

-

        'rest_framework.renderers.JSONRenderer', 

-

        'rest_framework.renderers.BrowsableAPIRenderer', 

-

    ), 

-

    'DEFAULT_PARSER_CLASSES': ( 

-

        'rest_framework.parsers.JSONParser', 

-

        'rest_framework.parsers.FormParser', 

-

        'rest_framework.parsers.MultiPartParser' 

-

    ), 

-

    'DEFAULT_AUTHENTICATION_CLASSES': ( 

-

        'rest_framework.authentication.SessionAuthentication', 

-

        'rest_framework.authentication.BasicAuthentication' 

-

    ), 

-

    'DEFAULT_PERMISSION_CLASSES': ( 

-

        'rest_framework.permissions.AllowAny', 

-

    ), 

-

    'DEFAULT_THROTTLE_CLASSES': ( 

-

    ), 

-

 

-

    'DEFAULT_CONTENT_NEGOTIATION_CLASS': 

-

        'rest_framework.negotiation.DefaultContentNegotiation', 

-

 

-

    # Genric view behavior 

-

    'DEFAULT_MODEL_SERIALIZER_CLASS': 

-

        'rest_framework.serializers.ModelSerializer', 

-

    'DEFAULT_PAGINATION_SERIALIZER_CLASS': 

-

        'rest_framework.pagination.PaginationSerializer', 

-

    'DEFAULT_FILTER_BACKENDS': (), 

-

 

-

    # Throttling 

-

    'DEFAULT_THROTTLE_RATES': { 

-

        'user': None, 

-

        'anon': None, 

-

    }, 

-

 

-

    # Pagination 

-

    'PAGINATE_BY': None, 

-

    'PAGINATE_BY_PARAM': None, 

-

 

-

    # Authentication 

-

    'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 

-

    'UNAUTHENTICATED_TOKEN': None, 

-

 

-

    # Browser enhancements 

-

    'FORM_METHOD_OVERRIDE': '_method', 

-

    'FORM_CONTENT_OVERRIDE': '_content', 

-

    'FORM_CONTENTTYPE_OVERRIDE': '_content_type', 

-

    'URL_ACCEPT_OVERRIDE': 'accept', 

-

    'URL_FORMAT_OVERRIDE': 'format', 

-

 

-

    'FORMAT_SUFFIX_KWARG': 'format', 

-

 

-

    # Input and output formats 

-

    'DATE_INPUT_FORMATS': ( 

-

        ISO_8601, 

-

    ), 

-

    'DATE_FORMAT': None, 

-

 

-

    'DATETIME_INPUT_FORMATS': ( 

-

        ISO_8601, 

-

    ), 

-

    'DATETIME_FORMAT': None, 

-

 

-

    'TIME_INPUT_FORMATS': ( 

-

        ISO_8601, 

-

    ), 

-

    'TIME_FORMAT': None, 

-

 

-

    # Pending deprecation 

-

    'FILTER_BACKEND': None, 

-

} 

-

 

-

 

-

# List of settings that may be in string import notation. 

-

IMPORT_STRINGS = ( 

-

    'DEFAULT_RENDERER_CLASSES', 

-

    'DEFAULT_PARSER_CLASSES', 

-

    'DEFAULT_AUTHENTICATION_CLASSES', 

-

    'DEFAULT_PERMISSION_CLASSES', 

-

    'DEFAULT_THROTTLE_CLASSES', 

-

    'DEFAULT_CONTENT_NEGOTIATION_CLASS', 

-

    'DEFAULT_MODEL_SERIALIZER_CLASS', 

-

    'DEFAULT_PAGINATION_SERIALIZER_CLASS', 

-

    'DEFAULT_FILTER_BACKENDS', 

-

    'FILTER_BACKEND', 

-

    'UNAUTHENTICATED_USER', 

-

    'UNAUTHENTICATED_TOKEN', 

-

) 

-

 

-

 

-

def perform_import(val, setting_name): 

-

    """ 

-

    If the given setting is a string import notation, 

-

    then perform the necessary import or imports. 

-

    """ 

-

    if isinstance(val, six.string_types): 

-

        return import_from_string(val, setting_name) 

-

    elif isinstance(val, (list, tuple)): 

-

        return [import_from_string(item, setting_name) for item in val] 

-

    return val 

-

 

-

 

-

def import_from_string(val, setting_name): 

-

    """ 

-

    Attempt to import a class from a string representation. 

-

    """ 

-

    try: 

-

        # Nod to tastypie's use of importlib. 

-

        parts = val.split('.') 

-

        module_path, class_name = '.'.join(parts[:-1]), parts[-1] 

-

        module = importlib.import_module(module_path) 

-

        return getattr(module, class_name) 

-

    except ImportError as e: 

-

        msg = "Could not import '%s' for API setting '%s'. %s: %s." % (val, setting_name, e.__class__.__name__, e) 

-

        raise ImportError(msg) 

-

 

-

 

-

class APISettings(object): 

-

    """ 

-

    A settings object, that allows API settings to be accessed as properties. 

-

    For example: 

-

 

-

        from rest_framework.settings import api_settings 

-

        print api_settings.DEFAULT_RENDERER_CLASSES 

-

 

-

    Any setting with string import paths will be automatically resolved 

-

    and return the class, rather than the string literal. 

-

    """ 

-

    def __init__(self, user_settings=None, defaults=None, import_strings=None): 

-

        self.user_settings = user_settings or {} 

-

        self.defaults = defaults or {} 

-

        self.import_strings = import_strings or () 

-

 

-

    def __getattr__(self, attr): 

-

        if attr not in self.defaults.keys(): 

-

            raise AttributeError("Invalid API setting: '%s'" % attr) 

-

 

-

        try: 

-

            # Check if present in user settings 

-

            val = self.user_settings[attr] 

-

        except KeyError: 

-

            # Fall back to defaults 

-

            val = self.defaults[attr] 

-

 

-

        # Coerce import strings into classes 

-

        if val and attr in self.import_strings: 

-

            val = perform_import(val, attr) 

-

 

-

        self.validate_setting(attr, val) 

-

 

-

        # Cache the result 

-

        setattr(self, attr, val) 

-

        return val 

-

 

-

    def validate_setting(self, attr, val): 

-

        if attr == 'FILTER_BACKEND' and val is not None: 

-

            # Make sure we can initialize the class 

-

            val() 

-

 

-

api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_status.html b/htmlcov/rest_framework_status.html deleted file mode 100644 index 85f919f6b..000000000 --- a/htmlcov/rest_framework_status.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - Coverage for rest_framework/status: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

- -
-

""" 

-

Descriptive HTTP status codes, for code readability. 

-

 

-

See RFC 2616 - http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 

-

And RFC 6585 - http://tools.ietf.org/html/rfc6585 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

HTTP_100_CONTINUE = 100 

-

HTTP_101_SWITCHING_PROTOCOLS = 101 

-

HTTP_200_OK = 200 

-

HTTP_201_CREATED = 201 

-

HTTP_202_ACCEPTED = 202 

-

HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203 

-

HTTP_204_NO_CONTENT = 204 

-

HTTP_205_RESET_CONTENT = 205 

-

HTTP_206_PARTIAL_CONTENT = 206 

-

HTTP_300_MULTIPLE_CHOICES = 300 

-

HTTP_301_MOVED_PERMANENTLY = 301 

-

HTTP_302_FOUND = 302 

-

HTTP_303_SEE_OTHER = 303 

-

HTTP_304_NOT_MODIFIED = 304 

-

HTTP_305_USE_PROXY = 305 

-

HTTP_306_RESERVED = 306 

-

HTTP_307_TEMPORARY_REDIRECT = 307 

-

HTTP_400_BAD_REQUEST = 400 

-

HTTP_401_UNAUTHORIZED = 401 

-

HTTP_402_PAYMENT_REQUIRED = 402 

-

HTTP_403_FORBIDDEN = 403 

-

HTTP_404_NOT_FOUND = 404 

-

HTTP_405_METHOD_NOT_ALLOWED = 405 

-

HTTP_406_NOT_ACCEPTABLE = 406 

-

HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407 

-

HTTP_408_REQUEST_TIMEOUT = 408 

-

HTTP_409_CONFLICT = 409 

-

HTTP_410_GONE = 410 

-

HTTP_411_LENGTH_REQUIRED = 411 

-

HTTP_412_PRECONDITION_FAILED = 412 

-

HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413 

-

HTTP_414_REQUEST_URI_TOO_LONG = 414 

-

HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415 

-

HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416 

-

HTTP_417_EXPECTATION_FAILED = 417 

-

HTTP_428_PRECONDITION_REQUIRED = 428 

-

HTTP_429_TOO_MANY_REQUESTS = 429 

-

HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431 

-

HTTP_500_INTERNAL_SERVER_ERROR = 500 

-

HTTP_501_NOT_IMPLEMENTED = 501 

-

HTTP_502_BAD_GATEWAY = 502 

-

HTTP_503_SERVICE_UNAVAILABLE = 503 

-

HTTP_504_GATEWAY_TIMEOUT = 504 

-

HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505 

-

HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_throttling.html b/htmlcov/rest_framework_throttling.html deleted file mode 100644 index 778b0293b..000000000 --- a/htmlcov/rest_framework_throttling.html +++ /dev/null @@ -1,533 +0,0 @@ - - - - - - - - Coverage for rest_framework/throttling: 81% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

- -
-

""" 

-

Provides various throttling policies. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.core.cache import cache 

-

from django.core.exceptions import ImproperlyConfigured 

-

from rest_framework.settings import api_settings 

-

import time 

-

 

-

 

-

class BaseThrottle(object): 

-

    """ 

-

    Rate throttling of requests. 

-

    """ 

-

    def allow_request(self, request, view): 

-

        """ 

-

        Return `True` if the request should be allowed, `False` otherwise. 

-

        """ 

-

        raise NotImplementedError('.allow_request() must be overridden') 

-

 

-

    def wait(self): 

-

        """ 

-

        Optionally, return a recommended number of seconds to wait before 

-

        the next request. 

-

        """ 

-

        return None 

-

 

-

 

-

class SimpleRateThrottle(BaseThrottle): 

-

    """ 

-

    A simple cache implementation, that only requires `.get_cache_key()` 

-

    to be overridden. 

-

 

-

    The rate (requests / seconds) is set by a `throttle` attribute on the View 

-

    class.  The attribute is a string of the form 'number_of_requests/period'. 

-

 

-

    Period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day') 

-

 

-

    Previous request information used for throttling is stored in the cache. 

-

    """ 

-

 

-

    timer = time.time 

-

    cache_format = 'throtte_%(scope)s_%(ident)s' 

-

    scope = None 

-

    THROTTLE_RATES = api_settings.DEFAULT_THROTTLE_RATES 

-

 

-

    def __init__(self): 

-

        if not getattr(self, 'rate', None): 

-

            self.rate = self.get_rate() 

-

        self.num_requests, self.duration = self.parse_rate(self.rate) 

-

 

-

    def get_cache_key(self, request, view): 

-

        """ 

-

        Should return a unique cache-key which can be used for throttling. 

-

        Must be overridden. 

-

 

-

        May return `None` if the request should not be throttled. 

-

        """ 

-

        raise NotImplementedError('.get_cache_key() must be overridden') 

-

 

-

    def get_rate(self): 

-

        """ 

-

        Determine the string representation of the allowed request rate. 

-

        """ 

-

        if not getattr(self, 'scope', None): 

-

            msg = ("You must set either `.scope` or `.rate` for '%s' throttle" % 

-

                   self.__class__.__name__) 

-

            raise ImproperlyConfigured(msg) 

-

 

-

        try: 

-

            return self.THROTTLE_RATES[self.scope] 

-

        except KeyError: 

-

            msg = "No default throttle rate set for '%s' scope" % self.scope 

-

            raise ImproperlyConfigured(msg) 

-

 

-

    def parse_rate(self, rate): 

-

        """ 

-

        Given the request rate string, return a two tuple of: 

-

        <allowed number of requests>, <period of time in seconds> 

-

        """ 

-

        if rate is None: 

-

            return (None, None) 

-

        num, period = rate.split('/') 

-

        num_requests = int(num) 

-

        duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]] 

-

        return (num_requests, duration) 

-

 

-

    def allow_request(self, request, view): 

-

        """ 

-

        Implement the check to see if the request should be throttled. 

-

 

-

        On success calls `throttle_success`. 

-

        On failure calls `throttle_failure`. 

-

        """ 

-

        if self.rate is None: 

-

            return True 

-

 

-

        self.key = self.get_cache_key(request, view) 

-

        self.history = cache.get(self.key, []) 

-

        self.now = self.timer() 

-

 

-

        # Drop any requests from the history which have now passed the 

-

        # throttle duration 

-

        while self.history and self.history[-1] <= self.now - self.duration: 

-

            self.history.pop() 

-

        if len(self.history) >= self.num_requests: 

-

            return self.throttle_failure() 

-

        return self.throttle_success() 

-

 

-

    def throttle_success(self): 

-

        """ 

-

        Inserts the current request's timestamp along with the key 

-

        into the cache. 

-

        """ 

-

        self.history.insert(0, self.now) 

-

        cache.set(self.key, self.history, self.duration) 

-

        return True 

-

 

-

    def throttle_failure(self): 

-

        """ 

-

        Called when a request to the API has failed due to throttling. 

-

        """ 

-

        return False 

-

 

-

    def wait(self): 

-

        """ 

-

        Returns the recommended next request time in seconds. 

-

        """ 

-

        if self.history: 

-

            remaining_duration = self.duration - (self.now - self.history[-1]) 

-

        else: 

-

            remaining_duration = self.duration 

-

 

-

        available_requests = self.num_requests - len(self.history) + 1 

-

 

-

        return remaining_duration / float(available_requests) 

-

 

-

 

-

class AnonRateThrottle(SimpleRateThrottle): 

-

    """ 

-

    Limits the rate of API calls that may be made by a anonymous users. 

-

 

-

    The IP address of the request will be used as the unique cache key. 

-

    """ 

-

    scope = 'anon' 

-

 

-

    def get_cache_key(self, request, view): 

-

        if request.user.is_authenticated(): 

-

            return None  # Only throttle unauthenticated requests. 

-

 

-

        ident = request.META.get('REMOTE_ADDR', None) 

-

 

-

        return self.cache_format % { 

-

            'scope': self.scope, 

-

            'ident': ident 

-

        } 

-

 

-

 

-

class UserRateThrottle(SimpleRateThrottle): 

-

    """ 

-

    Limits the rate of API calls that may be made by a given user. 

-

 

-

    The user id will be used as a unique cache key if the user is 

-

    authenticated.  For anonymous requests, the IP address of the request will 

-

    be used. 

-

    """ 

-

    scope = 'user' 

-

 

-

    def get_cache_key(self, request, view): 

-

        if request.user.is_authenticated(): 

-

            ident = request.user.id 

-

        else: 

-

            ident = request.META.get('REMOTE_ADDR', None) 

-

 

-

        return self.cache_format % { 

-

            'scope': self.scope, 

-

            'ident': ident 

-

        } 

-

 

-

 

-

class ScopedRateThrottle(SimpleRateThrottle): 

-

    """ 

-

    Limits the rate of API calls by different amounts for various parts of 

-

    the API.  Any view that has the `throttle_scope` property set will be 

-

    throttled.  The unique cache key will be generated by concatenating the 

-

    user id of the request, and the scope of the view being accessed. 

-

    """ 

-

    scope_attr = 'throttle_scope' 

-

 

-

    def __init__(self): 

-

        # Override the usual SimpleRateThrottle, because we can't determine 

-

        # the rate until called by the view. 

-

        pass 

-

 

-

    def allow_request(self, request, view): 

-

        # We can only determine the scope once we're called by the view. 

-

        self.scope = getattr(view, self.scope_attr, None) 

-

 

-

        # If a view does not have a `throttle_scope` always allow the request 

-

        if not self.scope: 

-

            return True 

-

 

-

        # Determine the allowed request rate as we normally would during 

-

        # the `__init__` call. 

-

        self.rate = self.get_rate() 

-

        self.num_requests, self.duration = self.parse_rate(self.rate) 

-

 

-

        # We can now proceed as normal. 

-

        return super(ScopedRateThrottle, self).allow_request(request, view) 

-

 

-

    def get_cache_key(self, request, view): 

-

        """ 

-

        If `view.throttle_scope` is not set, don't apply this throttle. 

-

 

-

        Otherwise generate the unique cache key by concatenating the user id 

-

        with the '.throttle_scope` property of the view. 

-

        """ 

-

        if request.user.is_authenticated(): 

-

            ident = request.user.id 

-

        else: 

-

            ident = request.META.get('REMOTE_ADDR', None) 

-

 

-

        return self.cache_format % { 

-

            'scope': self.scope, 

-

            'ident': ident 

-

        } 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_urlpatterns.html b/htmlcov/rest_framework_urlpatterns.html deleted file mode 100644 index 4c824a770..000000000 --- a/htmlcov/rest_framework_urlpatterns.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - Coverage for rest_framework/urlpatterns: 87% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

- -
-

from __future__ import unicode_literals 

-

from django.core.urlresolvers import RegexURLResolver 

-

from rest_framework.compat import url, include 

-

from rest_framework.settings import api_settings 

-

 

-

 

-

def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required): 

-

    ret = [] 

-

    for urlpattern in urlpatterns: 

-

        if isinstance(urlpattern, RegexURLResolver): 

-

            # Set of included URL patterns 

-

            regex = urlpattern.regex.pattern 

-

            namespace = urlpattern.namespace 

-

            app_name = urlpattern.app_name 

-

            kwargs = urlpattern.default_kwargs 

-

            # Add in the included patterns, after applying the suffixes 

-

            patterns = apply_suffix_patterns(urlpattern.url_patterns, 

-

                                             suffix_pattern, 

-

                                             suffix_required) 

-

            ret.append(url(regex, include(patterns, namespace, app_name), kwargs)) 

-

 

-

        else: 

-

            # Regular URL pattern 

-

            regex = urlpattern.regex.pattern.rstrip('$') + suffix_pattern 

-

            view = urlpattern._callback or urlpattern._callback_str 

-

            kwargs = urlpattern.default_args 

-

            name = urlpattern.name 

-

            # Add in both the existing and the new urlpattern 

-

            if not suffix_required: 

-

                ret.append(urlpattern) 

-

            ret.append(url(regex, view, kwargs, name)) 

-

 

-

    return ret 

-

 

-

 

-

def format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None): 

-

    """ 

-

    Supplement existing urlpatterns with corresponding patterns that also 

-

    include a '.format' suffix.  Retains urlpattern ordering. 

-

 

-

    urlpatterns: 

-

        A list of URL patterns. 

-

 

-

    suffix_required: 

-

        If `True`, only suffixed URLs will be generated, and non-suffixed 

-

        URLs will not be used.  Defaults to `False`. 

-

 

-

    allowed: 

-

        An optional tuple/list of allowed suffixes.  eg ['json', 'api'] 

-

        Defaults to `None`, which allows any suffix. 

-

    """ 

-

    suffix_kwarg = api_settings.FORMAT_SUFFIX_KWARG 

-

    if allowed: 

-

        if len(allowed) == 1: 

-

            allowed_pattern = allowed[0] 

-

        else: 

-

            allowed_pattern = '(%s)' % '|'.join(allowed) 

-

        suffix_pattern = r'\.(?P<%s>%s)$' % (suffix_kwarg, allowed_pattern) 

-

    else: 

-

        suffix_pattern = r'\.(?P<%s>[a-z]+)$' % suffix_kwarg 

-

 

-

    return apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_urls.html b/htmlcov/rest_framework_urls.html deleted file mode 100644 index 7720a6d40..000000000 --- a/htmlcov/rest_framework_urls.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - Coverage for rest_framework/urls: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

- -
-

""" 

-

Login and logout views for the browsable API. 

-

 

-

Add these to your root URLconf if you're using the browsable API and 

-

your API requires authentication. 

-

 

-

The urls must be namespaced as 'rest_framework', and you should make sure 

-

your authentication settings include `SessionAuthentication`. 

-

 

-

    urlpatterns = patterns('', 

-

        ... 

-

        url(r'^auth', include('rest_framework.urls', namespace='rest_framework')) 

-

    ) 

-

""" 

-

from __future__ import unicode_literals 

-

from rest_framework.compat import patterns, url 

-

 

-

 

-

template_name = {'template_name': 'rest_framework/login.html'} 

-

 

-

urlpatterns = patterns('django.contrib.auth.views', 

-

    url(r'^login/$', 'login', template_name, name='login'), 

-

    url(r'^logout/$', 'logout', template_name, name='logout'), 

-

) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_utils___init__.html b/htmlcov/rest_framework_utils___init__.html deleted file mode 100644 index 99eb18c4f..000000000 --- a/htmlcov/rest_framework_utils___init__.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - Coverage for rest_framework/utils/__init__: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
- - - -
-
- - - - - diff --git a/htmlcov/rest_framework_utils_breadcrumbs.html b/htmlcov/rest_framework_utils_breadcrumbs.html deleted file mode 100644 index 14fb8955d..000000000 --- a/htmlcov/rest_framework_utils_breadcrumbs.html +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - Coverage for rest_framework/utils/breadcrumbs: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

- -
-

from __future__ import unicode_literals 

-

from django.core.urlresolvers import resolve, get_script_prefix 

-

from rest_framework.utils.formatting import get_view_name 

-

 

-

 

-

def get_breadcrumbs(url): 

-

    """ 

-

    Given a url returns a list of breadcrumbs, which are each a 

-

    tuple of (name, url). 

-

    """ 

-

 

-

    from rest_framework.views import APIView 

-

 

-

    def breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen): 

-

        """ 

-

        Add tuples of (name, url) to the breadcrumbs list, 

-

        progressively chomping off parts of the url. 

-

        """ 

-

 

-

        try: 

-

            (view, unused_args, unused_kwargs) = resolve(url) 

-

        except Exception: 

-

            pass 

-

        else: 

-

            # Check if this is a REST framework view, 

-

            # and if so add it to the breadcrumbs 

-

            cls = getattr(view, 'cls', None) 

-

            if cls is not None and issubclass(cls, APIView): 

-

                # Don't list the same view twice in a row. 

-

                # Probably an optional trailing slash. 

-

                if not seen or seen[-1] != view: 

-

                    suffix = getattr(view, 'suffix', None) 

-

                    name = get_view_name(view.cls, suffix) 

-

                    breadcrumbs_list.insert(0, (name, prefix + url)) 

-

                    seen.append(view) 

-

 

-

        if url == '': 

-

            # All done 

-

            return breadcrumbs_list 

-

 

-

        elif url.endswith('/'): 

-

            # Drop trailing slash off the end and continue to try to 

-

            # resolve more breadcrumbs 

-

            url = url.rstrip('/') 

-

            return breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen) 

-

 

-

        # Drop trailing non-slash off the end and continue to try to 

-

        # resolve more breadcrumbs 

-

        url = url[:url.rfind('/') + 1] 

-

        return breadcrumbs_recursive(url, breadcrumbs_list, prefix, seen) 

-

 

-

    prefix = get_script_prefix().rstrip('/') 

-

    url = url[len(prefix):] 

-

    return breadcrumbs_recursive(url, [], prefix, []) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_utils_encoders.html b/htmlcov/rest_framework_utils_encoders.html deleted file mode 100644 index 9f0ca343a..000000000 --- a/htmlcov/rest_framework_utils_encoders.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - - - - Coverage for rest_framework/utils/encoders: 73% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

- -
-

""" 

-

Helper classes for parsers. 

-

""" 

-

from __future__ import unicode_literals 

-

from django.utils.datastructures import SortedDict 

-

from django.utils.functional import Promise 

-

from rest_framework.compat import timezone, force_text 

-

from rest_framework.serializers import DictWithMetadata, SortedDictWithMetadata 

-

import datetime 

-

import decimal 

-

import types 

-

import json 

-

 

-

 

-

class JSONEncoder(json.JSONEncoder): 

-

    """ 

-

    JSONEncoder subclass that knows how to encode date/time/timedelta, 

-

    decimal types, and generators. 

-

    """ 

-

    def default(self, o): 

-

        # For Date Time string spec, see ECMA 262 

-

        # http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 

-

        if isinstance(o, Promise): 

-

            return force_text(o) 

-

        elif isinstance(o, datetime.datetime): 

-

            r = o.isoformat() 

-

            if o.microsecond: 

-

                r = r[:23] + r[26:] 

-

            if r.endswith('+00:00'): 

-

                r = r[:-6] + 'Z' 

-

            return r 

-

        elif isinstance(o, datetime.date): 

-

            return o.isoformat() 

-

        elif isinstance(o, datetime.time): 

-

            if timezone and timezone.is_aware(o): 

-

                raise ValueError("JSON can't represent timezone-aware times.") 

-

            r = o.isoformat() 

-

            if o.microsecond: 

-

                r = r[:12] 

-

            return r 

-

        elif isinstance(o, datetime.timedelta): 

-

            return str(o.total_seconds()) 

-

        elif isinstance(o, decimal.Decimal): 

-

            return str(o) 

-

        elif hasattr(o, '__iter__'): 

-

            return [i for i in o] 

-

        return super(JSONEncoder, self).default(o) 

-

 

-

 

-

try: 

-

    import yaml 

-

except ImportError: 

-

    SafeDumper = None 

-

else: 

-

    # Adapted from http://pyyaml.org/attachment/ticket/161/use_ordered_dict.py 

-

    class SafeDumper(yaml.SafeDumper): 

-

        """ 

-

        Handles decimals as strings. 

-

        Handles SortedDicts as usual dicts, but preserves field order, rather 

-

        than the usual behaviour of sorting the keys. 

-

        """ 

-

        def represent_decimal(self, data): 

-

            return self.represent_scalar('tag:yaml.org,2002:str', str(data)) 

-

 

-

        def represent_mapping(self, tag, mapping, flow_style=None): 

-

            value = [] 

-

            node = yaml.MappingNode(tag, value, flow_style=flow_style) 

-

            if self.alias_key is not None: 

-

                self.represented_objects[self.alias_key] = node 

-

            best_style = True 

-

            if hasattr(mapping, 'items'): 

-

                mapping = list(mapping.items()) 

-

                if not isinstance(mapping, SortedDict): 

-

                    mapping.sort() 

-

            for item_key, item_value in mapping: 

-

                node_key = self.represent_data(item_key) 

-

                node_value = self.represent_data(item_value) 

-

                if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style): 

-

                    best_style = False 

-

                if not (isinstance(node_value, yaml.ScalarNode) and not node_value.style): 

-

                    best_style = False 

-

                value.append((node_key, node_value)) 

-

            if flow_style is None: 

-

                if self.default_flow_style is not None: 

-

                    node.flow_style = self.default_flow_style 

-

                else: 

-

                    node.flow_style = best_style 

-

            return node 

-

 

-

    SafeDumper.add_representer(SortedDict, 

-

            yaml.representer.SafeRepresenter.represent_dict) 

-

    SafeDumper.add_representer(DictWithMetadata, 

-

            yaml.representer.SafeRepresenter.represent_dict) 

-

    SafeDumper.add_representer(SortedDictWithMetadata, 

-

            yaml.representer.SafeRepresenter.represent_dict) 

-

    SafeDumper.add_representer(types.GeneratorType, 

-

            yaml.representer.SafeRepresenter.represent_list) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_utils_formatting.html b/htmlcov/rest_framework_utils_formatting.html deleted file mode 100644 index 54e1570f7..000000000 --- a/htmlcov/rest_framework_utils_formatting.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - - - Coverage for rest_framework/utils/formatting: 97% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

- -
-

""" 

-

Utility functions to return a formatted name and description for a given view. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from django.utils.html import escape 

-

from django.utils.safestring import mark_safe 

-

from rest_framework.compat import apply_markdown 

-

import re 

-

 

-

 

-

def _remove_trailing_string(content, trailing): 

-

    """ 

-

    Strip trailing component `trailing` from `content` if it exists. 

-

    Used when generating names from view classes. 

-

    """ 

-

    if content.endswith(trailing) and content != trailing: 

-

        return content[:-len(trailing)] 

-

    return content 

-

 

-

 

-

def _remove_leading_indent(content): 

-

    """ 

-

    Remove leading indent from a block of text. 

-

    Used when generating descriptions from docstrings. 

-

    """ 

-

    whitespace_counts = [len(line) - len(line.lstrip(' ')) 

-

                         for line in content.splitlines()[1:] if line.lstrip()] 

-

 

-

    # unindent the content if needed 

-

    if whitespace_counts: 

-

        whitespace_pattern = '^' + (' ' * min(whitespace_counts)) 

-

        content = re.sub(re.compile(whitespace_pattern, re.MULTILINE), '', content) 

-

    content = content.strip('\n') 

-

    return content 

-

 

-

 

-

def _camelcase_to_spaces(content): 

-

    """ 

-

    Translate 'CamelCaseNames' to 'Camel Case Names'. 

-

    Used when generating names from view classes. 

-

    """ 

-

    camelcase_boundry = '(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))' 

-

    content = re.sub(camelcase_boundry, ' \\1', content).strip() 

-

    return ' '.join(content.split('_')).title() 

-

 

-

 

-

def get_view_name(cls, suffix=None): 

-

    """ 

-

    Return a formatted name for an `APIView` class or `@api_view` function. 

-

    """ 

-

    name = cls.__name__ 

-

    name = _remove_trailing_string(name, 'View') 

-

    name = _remove_trailing_string(name, 'ViewSet') 

-

    name = _camelcase_to_spaces(name) 

-

    if suffix: 

-

        name += ' ' + suffix 

-

    return name 

-

 

-

 

-

def get_view_description(cls, html=False): 

-

    """ 

-

    Return a description for an `APIView` class or `@api_view` function. 

-

    """ 

-

    description = cls.__doc__ or '' 

-

    description = _remove_leading_indent(description) 

-

    if html: 

-

        return markup_description(description) 

-

    return description 

-

 

-

 

-

def markup_description(description): 

-

    """ 

-

    Apply HTML markup to the given description. 

-

    """ 

-

    if apply_markdown: 

-

        description = apply_markdown(description) 

-

    else: 

-

        description = escape(description).replace('\n', '<br />') 

-

    return mark_safe(description) 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_utils_mediatypes.html b/htmlcov/rest_framework_utils_mediatypes.html deleted file mode 100644 index 2ce44ab59..000000000 --- a/htmlcov/rest_framework_utils_mediatypes.html +++ /dev/null @@ -1,257 +0,0 @@ - - - - - - - - Coverage for rest_framework/utils/mediatypes: 77% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

- -
-

""" 

-

Handling of media types, as found in HTTP Content-Type and Accept headers. 

-

 

-

See http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 

-

""" 

-

from __future__ import unicode_literals 

-

from django.http.multipartparser import parse_header 

-

from rest_framework import HTTP_HEADER_ENCODING 

-

 

-

 

-

def media_type_matches(lhs, rhs): 

-

    """ 

-

    Returns ``True`` if the media type in the first argument <= the 

-

    media type in the second argument.  The media types are strings 

-

    as described by the HTTP spec. 

-

 

-

    Valid media type strings include: 

-

 

-

    'application/json; indent=4' 

-

    'application/json' 

-

    'text/*' 

-

    '*/*' 

-

    """ 

-

    lhs = _MediaType(lhs) 

-

    rhs = _MediaType(rhs) 

-

    return lhs.match(rhs) 

-

 

-

 

-

def order_by_precedence(media_type_lst): 

-

    """ 

-

    Returns a list of sets of media type strings, ordered by precedence. 

-

    Precedence is determined by how specific a media type is: 

-

 

-

    3. 'type/subtype; param=val' 

-

    2. 'type/subtype' 

-

    1. 'type/*' 

-

    0. '*/*' 

-

    """ 

-

    ret = [set(), set(), set(), set()] 

-

    for media_type in media_type_lst: 

-

        precedence = _MediaType(media_type).precedence 

-

        ret[3 - precedence].add(media_type) 

-

    return [media_types for media_types in ret if media_types] 

-

 

-

 

-

class _MediaType(object): 

-

    def __init__(self, media_type_str): 

-

        if media_type_str is None: 

-

            media_type_str = '' 

-

        self.orig = media_type_str 

-

        self.full_type, self.params = parse_header(media_type_str.encode(HTTP_HEADER_ENCODING)) 

-

        self.main_type, sep, self.sub_type = self.full_type.partition('/') 

-

 

-

    def match(self, other): 

-

        """Return true if this MediaType satisfies the given MediaType.""" 

-

        for key in self.params.keys(): 

-

            if key != 'q' and other.params.get(key, None) != self.params.get(key, None): 

-

                return False 

-

 

-

        if self.sub_type != '*' and other.sub_type != '*'  and other.sub_type != self.sub_type: 

-

            return False 

-

 

-

        if self.main_type != '*' and other.main_type != '*' and other.main_type != self.main_type: 

-

            return False 

-

 

-

        return True 

-

 

-

    @property 

-

    def precedence(self): 

-

        """ 

-

        Return a precedence level from 0-3 for the media type given how specific it is. 

-

        """ 

-

        if self.main_type == '*': 

-

            return 0 

-

        elif self.sub_type == '*': 

-

            return 1 

-

        elif not self.params or self.params.keys() == ['q']: 

-

            return 2 

-

        return 3 

-

 

-

    def __str__(self): 

-

        return unicode(self).encode('utf-8') 

-

 

-

    def __unicode__(self): 

-

        ret = "%s/%s" % (self.main_type, self.sub_type) 

-

        for key, val in self.params.items(): 

-

            ret += "; %s=%s" % (key, val) 

-

        return ret 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_views.html b/htmlcov/rest_framework_views.html deleted file mode 100644 index f836e71fb..000000000 --- a/htmlcov/rest_framework_views.html +++ /dev/null @@ -1,793 +0,0 @@ - - - - - - - - Coverage for rest_framework/views: 100% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

-

140

-

141

-

142

-

143

-

144

-

145

-

146

-

147

-

148

-

149

-

150

-

151

-

152

-

153

-

154

-

155

-

156

-

157

-

158

-

159

-

160

-

161

-

162

-

163

-

164

-

165

-

166

-

167

-

168

-

169

-

170

-

171

-

172

-

173

-

174

-

175

-

176

-

177

-

178

-

179

-

180

-

181

-

182

-

183

-

184

-

185

-

186

-

187

-

188

-

189

-

190

-

191

-

192

-

193

-

194

-

195

-

196

-

197

-

198

-

199

-

200

-

201

-

202

-

203

-

204

-

205

-

206

-

207

-

208

-

209

-

210

-

211

-

212

-

213

-

214

-

215

-

216

-

217

-

218

-

219

-

220

-

221

-

222

-

223

-

224

-

225

-

226

-

227

-

228

-

229

-

230

-

231

-

232

-

233

-

234

-

235

-

236

-

237

-

238

-

239

-

240

-

241

-

242

-

243

-

244

-

245

-

246

-

247

-

248

-

249

-

250

-

251

-

252

-

253

-

254

-

255

-

256

-

257

-

258

-

259

-

260

-

261

-

262

-

263

-

264

-

265

-

266

-

267

-

268

-

269

-

270

-

271

-

272

-

273

-

274

-

275

-

276

-

277

-

278

-

279

-

280

-

281

-

282

-

283

-

284

-

285

-

286

-

287

-

288

-

289

-

290

-

291

-

292

-

293

-

294

-

295

-

296

-

297

-

298

-

299

-

300

-

301

-

302

-

303

-

304

-

305

-

306

-

307

-

308

-

309

-

310

-

311

-

312

-

313

-

314

-

315

-

316

-

317

-

318

-

319

-

320

-

321

-

322

-

323

-

324

-

325

-

326

-

327

-

328

-

329

-

330

-

331

-

332

-

333

-

334

-

335

-

336

-

337

-

338

-

339

-

340

-

341

-

342

-

343

-

344

-

345

-

346

-

347

-

348

-

349

-

350

-

351

-

352

-

353

-

354

-

355

-

356

- -
-

""" 

-

Provides an APIView class that is the base of all views in REST framework. 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from django.core.exceptions import PermissionDenied 

-

from django.http import Http404, HttpResponse 

-

from django.utils.datastructures import SortedDict 

-

from django.views.decorators.csrf import csrf_exempt 

-

from rest_framework import status, exceptions 

-

from rest_framework.compat import View 

-

from rest_framework.request import Request 

-

from rest_framework.response import Response 

-

from rest_framework.settings import api_settings 

-

from rest_framework.utils.formatting import get_view_name, get_view_description 

-

 

-

 

-

class APIView(View): 

-

    settings = api_settings 

-

 

-

    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES 

-

    parser_classes = api_settings.DEFAULT_PARSER_CLASSES 

-

    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES 

-

    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES 

-

    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES 

-

    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS 

-

 

-

    @classmethod 

-

    def as_view(cls, **initkwargs): 

-

        """ 

-

        Store the original class on the view function. 

-

 

-

        This allows us to discover information about the view when we do URL 

-

        reverse lookups.  Used for breadcrumb generation. 

-

        """ 

-

        view = super(APIView, cls).as_view(**initkwargs) 

-

        view.cls = cls 

-

        return view 

-

 

-

    @property 

-

    def allowed_methods(self): 

-

        """ 

-

        Wrap Django's private `_allowed_methods` interface in a public property. 

-

        """ 

-

        return self._allowed_methods() 

-

 

-

    @property 

-

    def default_response_headers(self): 

-

        # TODO: deprecate? 

-

        # TODO: Only vary by accept if multiple renderers 

-

        return { 

-

            'Allow': ', '.join(self.allowed_methods), 

-

            'Vary': 'Accept' 

-

        } 

-

 

-

    def http_method_not_allowed(self, request, *args, **kwargs): 

-

        """ 

-

        If `request.method` does not correspond to a handler method, 

-

        determine what kind of exception to raise. 

-

        """ 

-

        raise exceptions.MethodNotAllowed(request.method) 

-

 

-

    def permission_denied(self, request): 

-

        """ 

-

        If request is not permitted, determine what kind of exception to raise. 

-

        """ 

-

        if not self.request.successful_authenticator: 

-

            raise exceptions.NotAuthenticated() 

-

        raise exceptions.PermissionDenied() 

-

 

-

    def throttled(self, request, wait): 

-

        """ 

-

        If request is throttled, determine what kind of exception to raise. 

-

        """ 

-

        raise exceptions.Throttled(wait) 

-

 

-

    def get_authenticate_header(self, request): 

-

        """ 

-

        If a request is unauthenticated, determine the WWW-Authenticate 

-

        header to use for 401 responses, if any. 

-

        """ 

-

        authenticators = self.get_authenticators() 

-

        if authenticators: 

-

            return authenticators[0].authenticate_header(request) 

-

 

-

    def get_parser_context(self, http_request): 

-

        """ 

-

        Returns a dict that is passed through to Parser.parse(), 

-

        as the `parser_context` keyword argument. 

-

        """ 

-

        # Note: Additionally `request` will also be added to the context 

-

        #       by the Request object. 

-

        return { 

-

            'view': self, 

-

            'args': getattr(self, 'args', ()), 

-

            'kwargs': getattr(self, 'kwargs', {}) 

-

        } 

-

 

-

    def get_renderer_context(self): 

-

        """ 

-

        Returns a dict that is passed through to Renderer.render(), 

-

        as the `renderer_context` keyword argument. 

-

        """ 

-

        # Note: Additionally 'response' will also be added to the context, 

-

        #       by the Response object. 

-

        return { 

-

            'view': self, 

-

            'args': getattr(self, 'args', ()), 

-

            'kwargs': getattr(self, 'kwargs', {}), 

-

            'request': getattr(self, 'request', None) 

-

        } 

-

 

-

    # API policy instantiation methods 

-

 

-

    def get_format_suffix(self, **kwargs): 

-

        """ 

-

        Determine if the request includes a '.json' style format suffix 

-

        """ 

-

        if self.settings.FORMAT_SUFFIX_KWARG: 

-

            return kwargs.get(self.settings.FORMAT_SUFFIX_KWARG) 

-

 

-

    def get_renderers(self): 

-

        """ 

-

        Instantiates and returns the list of renderers that this view can use. 

-

        """ 

-

        return [renderer() for renderer in self.renderer_classes] 

-

 

-

    def get_parsers(self): 

-

        """ 

-

        Instantiates and returns the list of parsers that this view can use. 

-

        """ 

-

        return [parser() for parser in self.parser_classes] 

-

 

-

    def get_authenticators(self): 

-

        """ 

-

        Instantiates and returns the list of authenticators that this view can use. 

-

        """ 

-

        return [auth() for auth in self.authentication_classes] 

-

 

-

    def get_permissions(self): 

-

        """ 

-

        Instantiates and returns the list of permissions that this view requires. 

-

        """ 

-

        return [permission() for permission in self.permission_classes] 

-

 

-

    def get_throttles(self): 

-

        """ 

-

        Instantiates and returns the list of throttles that this view uses. 

-

        """ 

-

        return [throttle() for throttle in self.throttle_classes] 

-

 

-

    def get_content_negotiator(self): 

-

        """ 

-

        Instantiate and return the content negotiation class to use. 

-

        """ 

-

        if not getattr(self, '_negotiator', None): 

-

            self._negotiator = self.content_negotiation_class() 

-

        return self._negotiator 

-

 

-

    # API policy implementation methods 

-

 

-

    def perform_content_negotiation(self, request, force=False): 

-

        """ 

-

        Determine which renderer and media type to use render the response. 

-

        """ 

-

        renderers = self.get_renderers() 

-

        conneg = self.get_content_negotiator() 

-

 

-

        try: 

-

            return conneg.select_renderer(request, renderers, self.format_kwarg) 

-

        except Exception: 

-

            if force: 

-

                return (renderers[0], renderers[0].media_type) 

-

            raise 

-

 

-

    def perform_authentication(self, request): 

-

        """ 

-

        Perform authentication on the incoming request. 

-

 

-

        Note that if you override this and simply 'pass', then authentication 

-

        will instead be performed lazily, the first time either 

-

        `request.user` or `request.auth` is accessed. 

-

        """ 

-

        request.user 

-

 

-

    def check_permissions(self, request): 

-

        """ 

-

        Check if the request should be permitted. 

-

        Raises an appropriate exception if the request is not permitted. 

-

        """ 

-

        for permission in self.get_permissions(): 

-

            if not permission.has_permission(request, self): 

-

                self.permission_denied(request) 

-

 

-

    def check_object_permissions(self, request, obj): 

-

        """ 

-

        Check if the request should be permitted for a given object. 

-

        Raises an appropriate exception if the request is not permitted. 

-

        """ 

-

        for permission in self.get_permissions(): 

-

            if not permission.has_object_permission(request, self, obj): 

-

                self.permission_denied(request) 

-

 

-

    def check_throttles(self, request): 

-

        """ 

-

        Check if request should be throttled. 

-

        Raises an appropriate exception if the request is throttled. 

-

        """ 

-

        for throttle in self.get_throttles(): 

-

            if not throttle.allow_request(request, self): 

-

                self.throttled(request, throttle.wait()) 

-

 

-

    # Dispatch methods 

-

 

-

    def initialize_request(self, request, *args, **kargs): 

-

        """ 

-

        Returns the initial request object. 

-

        """ 

-

        parser_context = self.get_parser_context(request) 

-

 

-

        return Request(request, 

-

                       parsers=self.get_parsers(), 

-

                       authenticators=self.get_authenticators(), 

-

                       negotiator=self.get_content_negotiator(), 

-

                       parser_context=parser_context) 

-

 

-

    def initial(self, request, *args, **kwargs): 

-

        """ 

-

        Runs anything that needs to occur prior to calling the method handler. 

-

        """ 

-

        self.format_kwarg = self.get_format_suffix(**kwargs) 

-

 

-

        # Ensure that the incoming request is permitted 

-

        self.perform_authentication(request) 

-

        self.check_permissions(request) 

-

        self.check_throttles(request) 

-

 

-

        # Perform content negotiation and store the accepted info on the request 

-

        neg = self.perform_content_negotiation(request) 

-

        request.accepted_renderer, request.accepted_media_type = neg 

-

 

-

    def finalize_response(self, request, response, *args, **kwargs): 

-

        """ 

-

        Returns the final response object. 

-

        """ 

-

        # Make the error obvious if a proper response is not returned 

-

        assert isinstance(response, HttpResponse), ( 

-

            'Expected a `Response` to be returned from the view, ' 

-

            'but received a `%s`' % type(response) 

-

        ) 

-

 

-

        if isinstance(response, Response): 

-

            if not getattr(request, 'accepted_renderer', None): 

-

                neg = self.perform_content_negotiation(request, force=True) 

-

                request.accepted_renderer, request.accepted_media_type = neg 

-

 

-

            response.accepted_renderer = request.accepted_renderer 

-

            response.accepted_media_type = request.accepted_media_type 

-

            response.renderer_context = self.get_renderer_context() 

-

 

-

        for key, value in self.headers.items(): 

-

            response[key] = value 

-

 

-

        return response 

-

 

-

    def handle_exception(self, exc): 

-

        """ 

-

        Handle any exception that occurs, by returning an appropriate response, 

-

        or re-raising the error. 

-

        """ 

-

        if isinstance(exc, exceptions.Throttled): 

-

            # Throttle wait header 

-

            self.headers['X-Throttle-Wait-Seconds'] = '%d' % exc.wait 

-

 

-

        if isinstance(exc, (exceptions.NotAuthenticated, 

-

                            exceptions.AuthenticationFailed)): 

-

            # WWW-Authenticate header for 401 responses, else coerce to 403 

-

            auth_header = self.get_authenticate_header(self.request) 

-

 

-

            if auth_header: 

-

                self.headers['WWW-Authenticate'] = auth_header 

-

            else: 

-

                exc.status_code = status.HTTP_403_FORBIDDEN 

-

 

-

        if isinstance(exc, exceptions.APIException): 

-

            return Response({'detail': exc.detail}, 

-

                            status=exc.status_code, 

-

                            exception=True) 

-

        elif isinstance(exc, Http404): 

-

            return Response({'detail': 'Not found'}, 

-

                            status=status.HTTP_404_NOT_FOUND, 

-

                            exception=True) 

-

        elif isinstance(exc, PermissionDenied): 

-

            return Response({'detail': 'Permission denied'}, 

-

                            status=status.HTTP_403_FORBIDDEN, 

-

                            exception=True) 

-

        raise 

-

 

-

    # Note: session based authentication is explicitly CSRF validated, 

-

    # all other authentication is CSRF exempt. 

-

    @csrf_exempt 

-

    def dispatch(self, request, *args, **kwargs): 

-

        """ 

-

        `.dispatch()` is pretty much the same as Django's regular dispatch, 

-

        but with extra hooks for startup, finalize, and exception handling. 

-

        """ 

-

        self.args = args 

-

        self.kwargs = kwargs 

-

        request = self.initialize_request(request, *args, **kwargs) 

-

        self.request = request 

-

        self.headers = self.default_response_headers  # deprecate? 

-

 

-

        try: 

-

            self.initial(request, *args, **kwargs) 

-

 

-

            # Get the appropriate handler method 

-

            if request.method.lower() in self.http_method_names: 

-

                handler = getattr(self, request.method.lower(), 

-

                                  self.http_method_not_allowed) 

-

            else: 

-

                handler = self.http_method_not_allowed 

-

 

-

            response = handler(request, *args, **kwargs) 

-

 

-

        except Exception as exc: 

-

            response = self.handle_exception(exc) 

-

 

-

        self.response = self.finalize_response(request, response, *args, **kwargs) 

-

        return self.response 

-

 

-

    def options(self, request, *args, **kwargs): 

-

        """ 

-

        Handler method for HTTP 'OPTIONS' request. 

-

        We may as well implement this as Django will otherwise provide 

-

        a less useful default implementation. 

-

        """ 

-

        return Response(self.metadata(request), status=status.HTTP_200_OK) 

-

 

-

    def metadata(self, request): 

-

        """ 

-

        Return a dictionary of metadata about the view. 

-

        Used to return responses for OPTIONS requests. 

-

        """ 

-

 

-

        # This is used by ViewSets to disambiguate instance vs list views 

-

        view_name_suffix = getattr(self, 'suffix', None) 

-

 

-

        # By default we can't provide any form-like information, however the 

-

        # generic views override this implementation and add additional 

-

        # information for POST and PUT methods, based on the serializer. 

-

        ret = SortedDict() 

-

        ret['name'] = get_view_name(self.__class__, view_name_suffix) 

-

        ret['description'] = get_view_description(self.__class__) 

-

        ret['renders'] = [renderer.media_type for renderer in self.renderer_classes] 

-

        ret['parses'] = [parser.media_type for parser in self.parser_classes] 

-

        return ret 

- -
-
- - - - - diff --git a/htmlcov/rest_framework_viewsets.html b/htmlcov/rest_framework_viewsets.html deleted file mode 100644 index 8264ddc0c..000000000 --- a/htmlcov/rest_framework_viewsets.html +++ /dev/null @@ -1,359 +0,0 @@ - - - - - - - - Coverage for rest_framework/viewsets: 95% - - - - - - - - - - - -
- -

Hot-keys on this page

-
-

- r - m - x - p   toggle line displays -

-

- j - k   next/prev highlighted chunk -

-

- 0   (zero) top of page -

-

- 1   (one) first highlighted chunk -

-
-
- -
- - - - - -
-

1

-

2

-

3

-

4

-

5

-

6

-

7

-

8

-

9

-

10

-

11

-

12

-

13

-

14

-

15

-

16

-

17

-

18

-

19

-

20

-

21

-

22

-

23

-

24

-

25

-

26

-

27

-

28

-

29

-

30

-

31

-

32

-

33

-

34

-

35

-

36

-

37

-

38

-

39

-

40

-

41

-

42

-

43

-

44

-

45

-

46

-

47

-

48

-

49

-

50

-

51

-

52

-

53

-

54

-

55

-

56

-

57

-

58

-

59

-

60

-

61

-

62

-

63

-

64

-

65

-

66

-

67

-

68

-

69

-

70

-

71

-

72

-

73

-

74

-

75

-

76

-

77

-

78

-

79

-

80

-

81

-

82

-

83

-

84

-

85

-

86

-

87

-

88

-

89

-

90

-

91

-

92

-

93

-

94

-

95

-

96

-

97

-

98

-

99

-

100

-

101

-

102

-

103

-

104

-

105

-

106

-

107

-

108

-

109

-

110

-

111

-

112

-

113

-

114

-

115

-

116

-

117

-

118

-

119

-

120

-

121

-

122

-

123

-

124

-

125

-

126

-

127

-

128

-

129

-

130

-

131

-

132

-

133

-

134

-

135

-

136

-

137

-

138

-

139

- -
-

""" 

-

ViewSets are essentially just a type of class based view, that doesn't provide 

-

any method handlers, such as `get()`, `post()`, etc... but instead has actions, 

-

such as `list()`, `retrieve()`, `create()`, etc... 

-

 

-

Actions are only bound to methods at the point of instantiating the views. 

-

 

-

    user_list = UserViewSet.as_view({'get': 'list'}) 

-

    user_detail = UserViewSet.as_view({'get': 'retrieve'}) 

-

 

-

Typically, rather than instantiate views from viewsets directly, you'll 

-

regsiter the viewset with a router and let the URL conf be determined 

-

automatically. 

-

 

-

    router = DefaultRouter() 

-

    router.register(r'users', UserViewSet, 'user') 

-

    urlpatterns = router.urls 

-

""" 

-

from __future__ import unicode_literals 

-

 

-

from functools import update_wrapper 

-

from django.utils.decorators import classonlymethod 

-

from rest_framework import views, generics, mixins 

-

 

-

 

-

class ViewSetMixin(object): 

-

    """ 

-

    This is the magic. 

-

 

-

    Overrides `.as_view()` so that it takes an `actions` keyword that performs 

-

    the binding of HTTP methods to actions on the Resource. 

-

 

-

    For example, to create a concrete view binding the 'GET' and 'POST' methods 

-

    to the 'list' and 'create' actions... 

-

 

-

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'}) 

-

    """ 

-

 

-

    @classonlymethod 

-

    def as_view(cls, actions=None, **initkwargs): 

-

        """ 

-

        Because of the way class based views create a closure around the 

-

        instantiated view, we need to totally reimplement `.as_view`, 

-

        and slightly modify the view function that is created and returned. 

-

        """ 

-

        # The suffix initkwarg is reserved for identifing the viewset type 

-

        # eg. 'List' or 'Instance'. 

-

        cls.suffix = None 

-

 

-

        # sanitize keyword arguments 

-

        for key in initkwargs: 

-

            if key in cls.http_method_names: 

-

                raise TypeError("You tried to pass in the %s method name as a " 

-

                                "keyword argument to %s(). Don't do that." 

-

                                % (key, cls.__name__)) 

-

            if not hasattr(cls, key): 

-

                raise TypeError("%s() received an invalid keyword %r" % ( 

-

                    cls.__name__, key)) 

-

 

-

        def view(request, *args, **kwargs): 

-

            self = cls(**initkwargs) 

-

            # We also store the mapping of request methods to actions, 

-

            # so that we can later set the action attribute. 

-

            # eg. `self.action = 'list'` on an incoming GET request. 

-

            self.action_map = actions 

-

 

-

            # Bind methods to actions 

-

            # This is the bit that's different to a standard view 

-

            for method, action in actions.items(): 

-

                handler = getattr(self, action) 

-

                setattr(self, method, handler) 

-

 

-

            # Patch this in as it's otherwise only present from 1.5 onwards 

-

            if hasattr(self, 'get') and not hasattr(self, 'head'): 

-

                self.head = self.get 

-

 

-

            # And continue as usual 

-

            return self.dispatch(request, *args, **kwargs) 

-

 

-

        # take name and docstring from class 

-

        update_wrapper(view, cls, updated=()) 

-

 

-

        # and possible attributes set by decorators 

-

        # like csrf_exempt from dispatch 

-

        update_wrapper(view, cls.dispatch, assigned=()) 

-

 

-

        # We need to set these on the view function, so that breadcrumb 

-

        # generation can pick out these bits of information from a 

-

        # resolved URL. 

-

        view.cls = cls 

-

        view.suffix = initkwargs.get('suffix', None) 

-

        return view 

-

 

-

    def initialize_request(self, request, *args, **kargs): 

-

        """ 

-

        Set the `.action` attribute on the view, 

-

        depending on the request method. 

-

        """ 

-

        request = super(ViewSetMixin, self).initialize_request(request, *args, **kargs) 

-

        self.action = self.action_map.get(request.method.lower()) 

-

        return request 

-

 

-

 

-

class ViewSet(ViewSetMixin, views.APIView): 

-

    """ 

-

    The base ViewSet class does not provide any actions by default. 

-

    """ 

-

    pass 

-

 

-

 

-

class GenericViewSet(ViewSetMixin, generics.GenericAPIView): 

-

    """ 

-

    The GenericViewSet class does not provide any actions by default, 

-

    but does include the base set of generic view behavior, such as 

-

    the `get_object` and `get_queryset` methods. 

-

    """ 

-

    pass 

-

 

-

 

-

class ReadOnlyModelViewSet(mixins.RetrieveModelMixin, 

-

                           mixins.ListModelMixin, 

-

                           GenericViewSet): 

-

    """ 

-

    A viewset that provides default `list()` and `retrieve()` actions. 

-

    """ 

-

    pass 

-

 

-

 

-

class ModelViewSet(mixins.CreateModelMixin, 

-

                    mixins.RetrieveModelMixin, 

-

                    mixins.UpdateModelMixin, 

-

                    mixins.DestroyModelMixin, 

-

                    mixins.ListModelMixin, 

-

                    GenericViewSet): 

-

    """ 

-

    A viewset that provides default `create()`, `retrieve()`, `update()`, 

-

    `partial_update()`, `destroy()` and `list()` actions. 

-

    """ 

-

    pass 

- -
-
- - - - - diff --git a/htmlcov/status.dat b/htmlcov/status.dat deleted file mode 100644 index 9e448e377..000000000 --- a/htmlcov/status.dat +++ /dev/null @@ -1,1258 +0,0 @@ -(dp1 -S'files' -p2 -(dp3 -S'rest_framework_utils_encoders' -p4 -(dp5 -S'index' -p6 -(dp7 -S'par' -p8 -I0 -sS'html_filename' -p9 -S'rest_framework_utils_encoders.html' -p10 -sS'name' -p11 -S'rest_framework/utils/encoders' -p12 -sS'nums' -p13 -ccopy_reg -_reconstructor -p14 -(ccoverage.results -Numbers -p15 -c__builtin__ -object -p16 -NtRp17 -(dp18 -S'n_files' -p19 -I1 -sS'n_branches' -p20 -I0 -sS'n_statements' -p21 -I70 -sS'n_excluded' -p22 -I0 -sS'n_missing' -p23 -I19 -sS'n_missing_branches' -p24 -I0 -sbssS'hash' -p25 -S'\x9d|\xea|-p\x0c#\xef\x82\x8c\x91\xf1\xcd}f' -p26 -ssS'rest_framework___init__' -p27 -(dp28 -g6 -(dp29 -g8 -I0 -sg9 -S'rest_framework___init__.html' -p30 -sg11 -S'rest_framework/__init__' -p31 -sg13 -g14 -(g15 -g16 -NtRp32 -(dp33 -g19 -I1 -sg20 -I0 -sg21 -I4 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\xbc\xf1f\xd9[\xd4\xcf\x9cQ\x94H\xfd3)\xea[' -p34 -ssS'rest_framework_urlpatterns' -p35 -(dp36 -g6 -(dp37 -g8 -I0 -sg9 -S'rest_framework_urlpatterns.html' -p38 -sg11 -S'rest_framework/urlpatterns' -p39 -sg13 -g14 -(g15 -g16 -NtRp40 -(dp41 -g19 -I1 -sg20 -I0 -sg21 -I31 -sg22 -I0 -sg23 -I4 -sg24 -I0 -sbssg25 -S"\x84\xb0-\xc6Y\x7f\xebA'\x8c5+\xcf\xf6\xcf\xda" -p42 -ssS'rest_framework_permissions' -p43 -(dp44 -g6 -(dp45 -g8 -I0 -sg9 -S'rest_framework_permissions.html' -p46 -sg11 -S'rest_framework/permissions' -p47 -sg13 -g14 -(g15 -g16 -NtRp48 -(dp49 -g19 -I1 -sg20 -I0 -sg21 -I63 -sg22 -I0 -sg23 -I12 -sg24 -I0 -sbssg25 -S",\xc4,\xda\x05\x86\x17\xe8u2~ls*'\xc1" -p50 -ssS'rest_framework_fields' -p51 -(dp52 -g6 -(dp53 -g8 -I0 -sg9 -S'rest_framework_fields.html' -p54 -sg11 -S'rest_framework/fields' -p55 -sg13 -g14 -(g15 -g16 -NtRp56 -(dp57 -g19 -I1 -sg20 -I0 -sg21 -I594 -sg22 -I0 -sg23 -I80 -sg24 -I0 -sbssg25 -S'\x08\x1b\xd2m\x91l\x14e\x97CDA\x1c&k\xf9' -p58 -ssS'rest_framework_models' -p59 -(dp60 -g6 -(dp61 -g8 -I0 -sg9 -S'rest_framework_models.html' -p62 -sg11 -S'rest_framework/models' -p63 -sg13 -g14 -(g15 -g16 -NtRp64 -(dp65 -g19 -I1 -sg20 -I0 -sg21 -I0 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S' E\xaf\xdd\xe7\xbb\xc4\x11z\xf8\x80\x18v.\xec\xf6' -p66 -ssS'rest_framework_utils_breadcrumbs' -p67 -(dp68 -g6 -(dp69 -g8 -I0 -sg9 -S'rest_framework_utils_breadcrumbs.html' -p70 -sg11 -S'rest_framework/utils/breadcrumbs' -p71 -sg13 -g14 -(g15 -g16 -NtRp72 -(dp73 -g19 -I1 -sg20 -I0 -sg21 -I27 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'V"\xf6\xbc\\m)\x12R4>c\xff\xea\xde\x8b' -p74 -ssS'rest_framework_urls' -p75 -(dp76 -g6 -(dp77 -g8 -I0 -sg9 -S'rest_framework_urls.html' -p78 -sg11 -S'rest_framework/urls' -p79 -sg13 -g14 -(g15 -g16 -NtRp80 -(dp81 -g19 -I1 -sg20 -I0 -sg21 -I4 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\xba\x9b\xdaeu\x17\x8b\xe0e\xc6-\xc5R\xba\xa2\xd5' -p82 -ssS'rest_framework_serializers' -p83 -(dp84 -g6 -(dp85 -g8 -I0 -sg9 -S'rest_framework_serializers.html' -p86 -sg11 -S'rest_framework/serializers' -p87 -sg13 -g14 -(g15 -g16 -NtRp88 -(dp89 -g19 -I1 -sg20 -I0 -sg21 -I464 -sg22 -I0 -sg23 -I27 -sg24 -I0 -sbssg25 -S'O\\\xf6\x81y\x95\xae\x9a)\xe9~\xb8\xab\t\x88#' -p90 -ssS'rest_framework_exceptions' -p91 -(dp92 -g6 -(dp93 -g8 -I0 -sg9 -S'rest_framework_exceptions.html' -p94 -sg11 -S'rest_framework/exceptions' -p95 -sg13 -g14 -(g15 -g16 -NtRp96 -(dp97 -g19 -I1 -sg20 -I0 -sg21 -I51 -sg22 -I0 -sg23 -I2 -sg24 -I0 -sbssg25 -S'\xdd\xcaE\x12\x1f4V\xe6\x91\x11\xef:T\xe1r\xca' -p98 -ssS'rest_framework_status' -p99 -(dp100 -g6 -(dp101 -g8 -I0 -sg9 -S'rest_framework_status.html' -p102 -sg11 -S'rest_framework/status' -p103 -sg13 -g14 -(g15 -g16 -NtRp104 -(dp105 -g19 -I1 -sg20 -I0 -sg21 -I46 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\x97z\xcd\xfd\xdc\x0c\xe3\xa9j\x04\xab\x13]\x98\xbf\x80' -p106 -ssS'rest_framework_relations' -p107 -(dp108 -g6 -(dp109 -g8 -I0 -sg9 -S'rest_framework_relations.html' -p110 -sg11 -S'rest_framework/relations' -p111 -sg13 -g14 -(g15 -g16 -NtRp112 -(dp113 -g19 -I1 -sg20 -I0 -sg21 -I365 -sg22 -I0 -sg23 -I88 -sg24 -I0 -sbssg25 -S'\xdb"\xfe\xc2\xb3\x8a\xe2(\xbeoNk\x1b\xd3H9' -p114 -ssS'rest_framework_authtoken_views' -p115 -(dp116 -g6 -(dp117 -g8 -I0 -sg9 -S'rest_framework_authtoken_views.html' -p118 -sg11 -S'rest_framework/authtoken/views' -p119 -sg13 -g14 -(g15 -g16 -NtRp120 -(dp121 -g19 -I1 -sg20 -I0 -sg21 -I21 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\xb8A\x13\xee\xfc9\x8b\x1eY-\xad\x00\xa7\x9dH]' -p122 -ssS'rest_framework_mixins' -p123 -(dp124 -g6 -(dp125 -g8 -I0 -sg9 -S'rest_framework_mixins.html' -p126 -sg11 -S'rest_framework/mixins' -p127 -sg13 -g14 -(g15 -g16 -NtRp128 -(dp129 -g19 -I1 -sg20 -I0 -sg21 -I97 -sg22 -I0 -sg23 -I7 -sg24 -I0 -sbssg25 -S'\xcd\xe5\x9f\xc2\xbb\xd9\xcb\x14*\x88\x99\xe8\xdf\xd2\xa8\xd6' -p130 -ssS'rest_framework_views' -p131 -(dp132 -g6 -(dp133 -g8 -I0 -sg9 -S'rest_framework_views.html' -p134 -sg11 -S'rest_framework/views' -p135 -sg13 -g14 -(g15 -g16 -NtRp136 -(dp137 -g19 -I1 -sg20 -I0 -sg21 -I146 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'ZBo\x84oh^\x1f\x8c\x94Mp$\xf3\xd2\xa1' -p138 -ssS'rest_framework_generics' -p139 -(dp140 -g6 -(dp141 -g8 -I0 -sg9 -S'rest_framework_generics.html' -p142 -sg11 -S'rest_framework/generics' -p143 -sg13 -g14 -(g15 -g16 -NtRp144 -(dp145 -g19 -I1 -sg20 -I0 -sg21 -I196 -sg22 -I0 -sg23 -I34 -sg24 -I0 -sbssg25 -S'@\x1c\x97\x176\x18\x9c\xfc"| |\xb8^\xbb\x83' -p146 -ssS'rest_framework_utils___init__' -p147 -(dp148 -g6 -(dp149 -g8 -I0 -sg9 -S'rest_framework_utils___init__.html' -p150 -sg11 -S'rest_framework/utils/__init__' -p151 -sg13 -g14 -(g15 -g16 -NtRp152 -(dp153 -g19 -I1 -sg20 -I0 -sg21 -I0 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\xb0\xc8pN\xaf>\xa0\xbaz\x144\xe0A9\xb8?' -p154 -ssS'rest_framework_renderers' -p155 -(dp156 -g6 -(dp157 -g8 -I0 -sg9 -S'rest_framework_renderers.html' -p158 -sg11 -S'rest_framework/renderers' -p159 -sg13 -g14 -(g15 -g16 -NtRp160 -(dp161 -g19 -I1 -sg20 -I0 -sg21 -I282 -sg22 -I0 -sg23 -I23 -sg24 -I0 -sbssg25 -S'\t\x11\xd4\xafO\xae\\*\x8d\xaf\xa4f\xde\x86\xe8N' -p162 -ssS'rest_framework_negotiation' -p163 -(dp164 -g6 -(dp165 -g8 -I0 -sg9 -S'rest_framework_negotiation.html' -p166 -sg11 -S'rest_framework/negotiation' -p167 -sg13 -g14 -(g15 -g16 -NtRp168 -(dp169 -g19 -I1 -sg20 -I0 -sg21 -I41 -sg22 -I0 -sg23 -I4 -sg24 -I0 -sbssg25 -S'\xd2\xa2\x94\xc8}y\xba\x9eZE\xe5M\xa5>\x9f\x8d' -p170 -ssS'rest_framework_throttling' -p171 -(dp172 -g6 -(dp173 -g8 -I0 -sg9 -S'rest_framework_throttling.html' -p174 -sg11 -S'rest_framework/throttling' -p175 -sg13 -g14 -(g15 -g16 -NtRp176 -(dp177 -g19 -I1 -sg20 -I0 -sg21 -I90 -sg22 -I0 -sg23 -I17 -sg24 -I0 -sbssg25 -S'a\xbcT\xe7\xff\x1an\xb5\x886\xa3\xa2e\x90PZ' -p178 -ssS'rest_framework_reverse' -p179 -(dp180 -g6 -(dp181 -g8 -I0 -sg9 -S'rest_framework_reverse.html' -p182 -sg11 -S'rest_framework/reverse' -p183 -sg13 -g14 -(g15 -g16 -NtRp184 -(dp185 -g19 -I1 -sg20 -I0 -sg21 -I12 -sg22 -I0 -sg23 -I3 -sg24 -I0 -sbssg25 -S"#\xe7D\x01\x10\xe8'1\x9c\xc9yX4\xb4\xef\x19" -p186 -ssS'rest_framework_request' -p187 -(dp188 -g6 -(dp189 -g8 -I0 -sg9 -S'rest_framework_request.html' -p190 -sg11 -S'rest_framework/request' -p191 -sg13 -g14 -(g15 -g16 -NtRp192 -(dp193 -g19 -I1 -sg20 -I0 -sg21 -I161 -sg22 -I0 -sg23 -I8 -sg24 -I0 -sbssg25 -S'C\xd4v\x9b\xf2Z\xe47\xe8\xc8\x03\xf4\xf8\xac\xefs' -p194 -ssS'rest_framework_parsers' -p195 -(dp196 -g6 -(dp197 -g8 -I0 -sg9 -S'rest_framework_parsers.html' -p198 -sg11 -S'rest_framework/parsers' -p199 -sg13 -g14 -(g15 -g16 -NtRp200 -(dp201 -g19 -I1 -sg20 -I0 -sg21 -I153 -sg22 -I0 -sg23 -I13 -sg24 -I0 -sbssg25 -S'\x11o\x05[\x99{\x9c\x8bj\xa8\xd0t\xe8\x16\\\xae' -p202 -ssS'rest_framework_settings' -p203 -(dp204 -g6 -(dp205 -g8 -I0 -sg9 -S'rest_framework_settings.html' -p206 -sg11 -S'rest_framework/settings' -p207 -sg13 -g14 -(g15 -g16 -NtRp208 -(dp209 -g19 -I1 -sg20 -I0 -sg21 -I44 -sg22 -I0 -sg23 -I2 -sg24 -I0 -sbssg25 -S'\n\xb8|\x03\xa7d|\xfc9\xda\xb5\xb9\x1a\x00@\xc3' -p210 -ssS'rest_framework_authtoken_models' -p211 -(dp212 -g6 -(dp213 -g8 -I0 -sg9 -S'rest_framework_authtoken_models.html' -p214 -sg11 -S'rest_framework/authtoken/models' -p215 -sg13 -g14 -(g15 -g16 -NtRp216 -(dp217 -g19 -I1 -sg20 -I0 -sg21 -I21 -sg22 -I0 -sg23 -I1 -sg24 -I0 -sbssg25 -S'U;\xc7\xf5{\xf6r\xc7]\x95\xffF\xde\x8caE' -p218 -ssS'rest_framework_decorators' -p219 -(dp220 -g6 -(dp221 -g8 -I0 -sg9 -S'rest_framework_decorators.html' -p222 -sg11 -S'rest_framework/decorators' -p223 -sg13 -g14 -(g15 -g16 -NtRp224 -(dp225 -g19 -I1 -sg20 -I0 -sg21 -I60 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S"\xd4\x88\xa2\x16\xf4#X\xb4X\xe97Lj\xeb\x16'" -p226 -ssS'rest_framework_authentication' -p227 -(dp228 -g6 -(dp229 -g8 -I0 -sg9 -S'rest_framework_authentication.html' -p230 -sg11 -S'rest_framework/authentication' -p231 -sg13 -g14 -(g15 -g16 -NtRp232 -(dp233 -g19 -I1 -sg20 -I0 -sg21 -I169 -sg22 -I0 -sg23 -I33 -sg24 -I0 -sbssg25 -S'^\x80:,\x1cL\xde\t\xc1\x93\xe0\x8b\x11\xf4\xb8\x06' -p234 -ssS'rest_framework_utils_formatting' -p235 -(dp236 -g6 -(dp237 -g8 -I0 -sg9 -S'rest_framework_utils_formatting.html' -p238 -sg11 -S'rest_framework/utils/formatting' -p239 -sg13 -g14 -(g15 -g16 -NtRp240 -(dp241 -g19 -I1 -sg20 -I0 -sg21 -I39 -sg22 -I0 -sg23 -I1 -sg24 -I0 -sbssg25 -S'\xdd\x05M\xeb\xfe\tl\xe6\xdd\xc5k\xae\xa8\xf9um' -p242 -ssS'rest_framework_pagination' -p243 -(dp244 -g6 -(dp245 -g8 -I0 -sg9 -S'rest_framework_pagination.html' -p246 -sg11 -S'rest_framework/pagination' -p247 -sg13 -g14 -(g15 -g16 -NtRp248 -(dp249 -g19 -I1 -sg20 -I0 -sg21 -I43 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'y\xa8f\rv\x8c\x9b\x9a:9\xdc\x89\t>\x0c' -p282 -ssS'rest_framework_viewsets' -p283 -(dp284 -g6 -(dp285 -g8 -I0 -sg9 -S'rest_framework_viewsets.html' -p286 -sg11 -S'rest_framework/viewsets' -p287 -sg13 -g14 -(g15 -g16 -NtRp288 -(dp289 -g19 -I1 -sg20 -I0 -sg21 -I39 -sg22 -I0 -sg23 -I2 -sg24 -I0 -sbssg25 -S'ic\x82\xc6e\x93$\x1b\x0c\x8bK\x10\x0f9\xe8\n' -p290 -ssS'rest_framework_authtoken___init__' -p291 -(dp292 -g6 -(dp293 -g8 -I0 -sg9 -S'rest_framework_authtoken___init__.html' -p294 -sg11 -S'rest_framework/authtoken/__init__' -p295 -sg13 -g14 -(g15 -g16 -NtRp296 -(dp297 -g19 -I1 -sg20 -I0 -sg21 -I0 -sg22 -I0 -sg23 -I0 -sg24 -I0 -sbssg25 -S'\xb0\xc8pN\xaf>\xa0\xbaz\x144\xe0A9\xb8?' -p298 -ssS'rest_framework_routers' -p299 -(dp300 -g6 -(dp301 -g8 -I0 -sg9 -S'rest_framework_routers.html' -p302 -sg11 -S'rest_framework/routers' -p303 -sg13 -g14 -(g15 -g16 -NtRp304 -(dp305 -g19 -I1 -sg20 -I0 -sg21 -I108 -sg22 -I0 -sg23 -I7 -sg24 -I0 -sbssg25 -S'i\xa8[\x1f\x0f|\xd6\xa0R\x98\xa9\xecs\xe53\xb3' -p306 -sssS'version' -p307 -S'3.5.1' -p308 -sS'settings' -p309 -S'\xfe\xa4\x01e\x06\x8a\x97H\x97\xaf\xbf\xcd\xfez\xe4\xbf' -p310 -sS'format' -p311 -I1 -s. \ No newline at end of file diff --git a/htmlcov/style.css b/htmlcov/style.css deleted file mode 100644 index c40357b8b..000000000 --- a/htmlcov/style.css +++ /dev/null @@ -1,275 +0,0 @@ -/* CSS styles for Coverage. */ -/* Page-wide styles */ -html, body, h1, h2, h3, p, td, th { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-weight: inherit; - font-style: inherit; - font-size: 100%; - font-family: inherit; - vertical-align: baseline; - } - -/* Set baseline grid to 16 pt. */ -body { - font-family: georgia, serif; - font-size: 1em; - } - -html>body { - font-size: 16px; - } - -/* Set base font size to 12/16 */ -p { - font-size: .75em; /* 12/16 */ - line-height: 1.3333em; /* 16/12 */ - } - -table { - border-collapse: collapse; - } - -a.nav { - text-decoration: none; - color: inherit; - } -a.nav:hover { - text-decoration: underline; - color: inherit; - } - -/* Page structure */ -#header { - background: #f8f8f8; - width: 100%; - border-bottom: 1px solid #eee; - } - -#source { - padding: 1em; - font-family: "courier new", monospace; - } - -#indexfile #footer { - margin: 1em 3em; - } - -#pyfile #footer { - margin: 1em 1em; - } - -#footer .content { - padding: 0; - font-size: 85%; - font-family: verdana, sans-serif; - color: #666666; - font-style: italic; - } - -#index { - margin: 1em 0 0 3em; - } - -/* Header styles */ -#header .content { - padding: 1em 3em; - } - -h1 { - font-size: 1.25em; -} - -h2.stats { - margin-top: .5em; - font-size: 1em; -} -.stats span { - border: 1px solid; - padding: .1em .25em; - margin: 0 .1em; - cursor: pointer; - border-color: #999 #ccc #ccc #999; -} -.stats span.hide_run, .stats span.hide_exc, -.stats span.hide_mis, .stats span.hide_par, -.stats span.par.hide_run.hide_par { - border-color: #ccc #999 #999 #ccc; -} -.stats span.par.hide_run { - border-color: #999 #ccc #ccc #999; -} - -/* Help panel */ -#keyboard_icon { - float: right; - cursor: pointer; -} - -.help_panel { - position: absolute; - background: #ffc; - padding: .5em; - border: 1px solid #883; - display: none; -} - -#indexfile .help_panel { - width: 20em; height: 4em; -} - -#pyfile .help_panel { - width: 16em; height: 8em; -} - -.help_panel .legend { - font-style: italic; - margin-bottom: 1em; -} - -#panel_icon { - float: right; - cursor: pointer; -} - -.keyhelp { - margin: .75em; -} - -.keyhelp .key { - border: 1px solid black; - border-color: #888 #333 #333 #888; - padding: .1em .35em; - font-family: monospace; - font-weight: bold; - background: #eee; -} - -/* Source file styles */ -.linenos p { - text-align: right; - margin: 0; - padding: 0 .5em; - color: #999999; - font-family: verdana, sans-serif; - font-size: .625em; /* 10/16 */ - line-height: 1.6em; /* 16/10 */ - } -.linenos p.highlight { - background: #ffdd00; - } -.linenos p a { - text-decoration: none; - color: #999999; - } -.linenos p a:hover { - text-decoration: underline; - color: #999999; - } - -td.text { - width: 100%; - } -.text p { - margin: 0; - padding: 0 0 0 .5em; - border-left: 2px solid #ffffff; - white-space: nowrap; - } - -.text p.mis { - background: #ffdddd; - border-left: 2px solid #ff0000; - } -.text p.run, .text p.run.hide_par { - background: #ddffdd; - border-left: 2px solid #00ff00; - } -.text p.exc { - background: #eeeeee; - border-left: 2px solid #808080; - } -.text p.par, .text p.par.hide_run { - background: #ffffaa; - border-left: 2px solid #eeee99; - } -.text p.hide_run, .text p.hide_exc, .text p.hide_mis, .text p.hide_par, -.text p.hide_run.hide_par { - background: inherit; - } - -.text span.annotate { - font-family: georgia; - font-style: italic; - color: #666; - float: right; - padding-right: .5em; - } -.text p.hide_par span.annotate { - display: none; - } - -/* Syntax coloring */ -.text .com { - color: green; - font-style: italic; - line-height: 1px; - } -.text .key { - font-weight: bold; - line-height: 1px; - } -.text .str { - color: #000080; - } - -/* index styles */ -#index td, #index th { - text-align: right; - width: 5em; - padding: .25em .5em; - border-bottom: 1px solid #eee; - } -#index th { - font-style: italic; - color: #333; - border-bottom: 1px solid #ccc; - cursor: pointer; - } -#index th:hover { - background: #eee; - border-bottom: 1px solid #999; - } -#index td.left, #index th.left { - padding-left: 0; - } -#index td.right, #index th.right { - padding-right: 0; - } -#index th.headerSortDown, #index th.headerSortUp { - border-bottom: 1px solid #000; - } -#index td.name, #index th.name { - text-align: left; - width: auto; - } -#index td.name a { - text-decoration: none; - color: #000; - } -#index td.name a:hover { - text-decoration: underline; - color: #000; - } -#index tr.total { - } -#index tr.total td { - font-weight: bold; - border-top: 1px solid #ccc; - border-bottom: none; - } -#index tr.file:hover { - background: #eeeeee; - }