<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang=""> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>django.db.models.fields.files — Django 1.8.19 documentation</title> <link rel="stylesheet" href="../../../../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../../../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../../../../', VERSION: '1.8.19', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../../../../_static/jquery.js"></script> <script type="text/javascript" src="../../../../../_static/underscore.js"></script> <script type="text/javascript" src="../../../../../_static/doctools.js"></script> <link rel="index" title="Index" href="../../../../../genindex.html" /> <link rel="search" title="Search" href="../../../../../search.html" /> <link rel="top" title="Django 1.8.19 documentation" href="../../../../../contents.html" /> <link rel="up" title="django.db.models.fields" href="../fields.html" /> <script type="text/javascript" src="../../../../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../../../../../ref/templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head> <body role="document"> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../../../../index.html">Django 1.8.19 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../../../../index.html">Home</a> | <a title="Table of contents" href="../../../../../contents.html">Table of contents</a> | <a title="Global index" href="../../../../../genindex.html">Index</a> | <a title="Module index" href="../../../../../py-modindex.html">Modules</a> </div> <div class="nav"> <a href="../../../../index.html" title="Module code" accesskey="U">up</a></div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="_modules-django-db-models-fields-files"> <h1>Source code for django.db.models.fields.files</h1><div class="highlight"><pre> <span></span><span class="kn">import</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">warnings</span> <span class="kn">from</span> <span class="nn">django</span> <span class="k">import</span> <span class="n">forms</span> <span class="kn">from</span> <span class="nn">django.core</span> <span class="k">import</span> <span class="n">checks</span> <span class="kn">from</span> <span class="nn">django.core.files.base</span> <span class="k">import</span> <span class="n">File</span> <span class="kn">from</span> <span class="nn">django.core.files.images</span> <span class="k">import</span> <span class="n">ImageFile</span> <span class="kn">from</span> <span class="nn">django.core.files.storage</span> <span class="k">import</span> <span class="n">default_storage</span> <span class="kn">from</span> <span class="nn">django.db.models</span> <span class="k">import</span> <span class="n">signals</span> <span class="kn">from</span> <span class="nn">django.db.models.fields</span> <span class="k">import</span> <span class="n">Field</span> <span class="kn">from</span> <span class="nn">django.utils</span> <span class="k">import</span> <span class="n">six</span> <span class="kn">from</span> <span class="nn">django.utils.deprecation</span> <span class="k">import</span> <span class="n">RemovedInDjango110Warning</span> <span class="kn">from</span> <span class="nn">django.utils.encoding</span> <span class="k">import</span> <span class="n">force_str</span><span class="p">,</span> <span class="n">force_text</span> <span class="kn">from</span> <span class="nn">django.utils.inspect</span> <span class="k">import</span> <span class="n">func_supports_parameter</span> <span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="k">import</span> <span class="n">ugettext_lazy</span> <span class="k">as</span> <span class="n">_</span> <div class="viewcode-block" id="FieldFile"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FieldFile">[docs]</a><span class="k">class</span> <span class="nc">FieldFile</span><span class="p">(</span><span class="n">File</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span> <span class="nb">super</span><span class="p">(</span><span class="n">FieldFile</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="n">instance</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span> <span class="o">=</span> <span class="n">field</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">storage</span> <span class="bp">self</span><span class="o">.</span><span class="n">_committed</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> <span class="c1"># Older code may be expecting FileField values to be simple strings.</span> <span class="c1"># By overriding the == operator, it can remain backwards compatibility.</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="s1">'name'</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">name</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">other</span> <span class="k">def</span> <span class="nf">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span> <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span> <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="c1"># The standard File contains most of the necessary properties, but</span> <span class="c1"># FieldFiles can be instantiated without a name, so that needs to</span> <span class="c1"># be checked for here.</span> <span class="k">def</span> <span class="nf">_require_file</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"The '</span><span class="si">%s</span><span class="s2">' attribute has no file associated with it."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_get_file</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_require_file</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_file'</span><span class="p">)</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="k">def</span> <span class="nf">_set_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="o">=</span> <span class="n">file</span> <span class="k">def</span> <span class="nf">_del_file</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_file</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_file</span><span class="p">,</span> <span class="n">_set_file</span><span class="p">,</span> <span class="n">_del_file</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_get_path</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_require_file</span><span class="p">()</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="n">path</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_path</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_get_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_require_file</span><span class="p">()</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">url</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="n">url</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_url</span><span class="p">)</span> <span class="k">def</span> <span class="nf">_get_size</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_require_file</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_committed</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">size</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="n">size</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_size</span><span class="p">)</span> <div class="viewcode-block" id="FieldFile.open"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FieldFile.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">'rb'</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_require_file</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">mode</span><span class="p">)</span></div> <span class="c1"># open() doesn't alter the file's contents, but it does reset the pointer</span> <span class="nb">open</span><span class="o">.</span><span class="n">alters_data</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># In addition to the standard File API, FieldFiles have extra methods</span> <span class="c1"># to further manipulate the underlying file, as well as update the</span> <span class="c1"># associated model instance.</span> <div class="viewcode-block" id="FieldFile.save"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FieldFile.save">[docs]</a> <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">generate_filename</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="k">if</span> <span class="n">func_supports_parameter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">save</span><span class="p">,</span> <span class="s1">'max_length'</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">max_length</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span> <span class="s1">'Backwards compatibility for storage backends without '</span> <span class="s1">'support for the `max_length` argument in '</span> <span class="s1">'Storage.save() will be removed in Django 1.10.'</span><span class="p">,</span> <span class="n">RemovedInDjango110Warning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span> <span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="c1"># Update the filesize cache</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="o">=</span> <span class="n">content</span><span class="o">.</span><span class="n">size</span> <span class="bp">self</span><span class="o">.</span><span class="n">_committed</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># Save the object because it has changed, unless save is False</span> <span class="k">if</span> <span class="n">save</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">save</span><span class="p">()</span></div> <span class="n">save</span><span class="o">.</span><span class="n">alters_data</span> <span class="o">=</span> <span class="kc">True</span> <div class="viewcode-block" id="FieldFile.delete"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FieldFile.delete">[docs]</a> <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># Only close the file if it's already open, which we know by the</span> <span class="c1"># presence of self._file</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_file'</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="kc">None</span> <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="c1"># Delete the filesize cache</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_size'</span><span class="p">):</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="bp">self</span><span class="o">.</span><span class="n">_committed</span> <span class="o">=</span> <span class="kc">False</span> <span class="k">if</span> <span class="n">save</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">save</span><span class="p">()</span></div> <span class="n">delete</span><span class="o">.</span><span class="n">alters_data</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">def</span> <span class="nf">_get_closed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_file'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">return</span> <span class="n">file</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">file</span><span class="o">.</span><span class="n">closed</span> <span class="n">closed</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_closed</span><span class="p">)</span> <div class="viewcode-block" id="FieldFile.close"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FieldFile.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_file'</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="n">file</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">file</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></div> <span class="k">def</span> <span class="nf">__getstate__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c1"># FieldFile needs access to its associated model field and an instance</span> <span class="c1"># it's attached to in order to work properly, but the only necessary</span> <span class="c1"># data to be pickled is the file's name itself. Everything else will</span> <span class="c1"># be restored later, by FileDescriptor below.</span> <span class="k">return</span> <span class="p">{</span><span class="s1">'name'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s1">'closed'</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="s1">'_committed'</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s1">'_file'</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span></div> <span class="k">class</span> <span class="nc">FileDescriptor</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> The descriptor for the file attribute on the model instance. Returns a</span> <span class="sd"> FieldFile when accessed so you can do stuff like::</span> <span class="sd"> >>> from myapp.models import MyModel</span> <span class="sd"> >>> instance = MyModel.objects.get(pk=1)</span> <span class="sd"> >>> instance.file.size</span> <span class="sd"> Assigns a file object on assignment so you can do::</span> <span class="sd"> >>> with open('/path/to/hello.world', 'r') as f:</span> <span class="sd"> ... instance.file = File(f)</span> <span class="sd"> """</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span> <span class="o">=</span> <span class="n">field</span> <span class="k">def</span> <span class="nf">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">owner</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="k">if</span> <span class="n">instance</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span> <span class="s2">"The '</span><span class="si">%s</span><span class="s2">' attribute can only be accessed from </span><span class="si">%s</span><span class="s2"> instances."</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">owner</span><span class="o">.</span><span class="n">__name__</span><span class="p">))</span> <span class="c1"># This is slightly complicated, so worth an explanation.</span> <span class="c1"># instance.file`needs to ultimately return some instance of `File`,</span> <span class="c1"># probably a subclass. Additionally, this returned object needs to have</span> <span class="c1"># the FieldFile API so that users can easily do things like</span> <span class="c1"># instance.file.path and have that delegated to the file storage engine.</span> <span class="c1"># Easy enough if we're strict about assignment in __set__, but if you</span> <span class="c1"># peek below you can see that we're not. So depending on the current</span> <span class="c1"># value of the field we have to dynamically construct some sort of</span> <span class="c1"># "thing" to return.</span> <span class="c1"># The instance dict contains whatever was originally assigned</span> <span class="c1"># in __set__.</span> <span class="n">file</span> <span class="o">=</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="c1"># If this value is a string (instance.file = "path/to/file") or None</span> <span class="c1"># then we simply wrap it with the appropriate attribute class according</span> <span class="c1"># to the file field. [This is FieldFile for FileFields and</span> <span class="c1"># ImageFieldFile for ImageFields; it's also conceivable that user</span> <span class="c1"># subclasses might also want to subclass the attribute class]. This</span> <span class="c1"># object understands how to convert a path to a file, and also how to</span> <span class="c1"># handle None.</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">six</span><span class="o">.</span><span class="n">string_types</span><span class="p">)</span> <span class="ow">or</span> <span class="n">file</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">attr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">attr_class</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="p">,</span> <span class="n">file</span><span class="p">)</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">attr</span> <span class="c1"># Other types of files may be assigned as well, but they need to have</span> <span class="c1"># the FieldFile interface added to them. Thus, we wrap any other type of</span> <span class="c1"># File inside a FieldFile (well, the field's attr_class, which is</span> <span class="c1"># usually FieldFile).</span> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">File</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">FieldFile</span><span class="p">):</span> <span class="n">file_copy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">attr_class</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="p">,</span> <span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="n">file_copy</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="n">file</span> <span class="n">file_copy</span><span class="o">.</span><span class="n">_committed</span> <span class="o">=</span> <span class="kc">False</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">file_copy</span> <span class="c1"># Finally, because of the (some would say boneheaded) way pickle works,</span> <span class="c1"># the underlying FieldFile might not actually itself have an associated</span> <span class="c1"># file. So we need to reset the details of the FieldFile in those cases.</span> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">FieldFile</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">'field'</span><span class="p">):</span> <span class="n">file</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="n">instance</span> <span class="n">file</span><span class="o">.</span><span class="n">field</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span> <span class="n">file</span><span class="o">.</span><span class="n">storage</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">storage</span> <span class="c1"># That was fun, wasn't it?</span> <span class="k">return</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="k">def</span> <span class="nf">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> <div class="viewcode-block" id="FileField"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.FileField">[docs]</a><span class="k">class</span> <span class="nc">FileField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span> <span class="c1"># The class to wrap instance attributes in. Accessing the file object off</span> <span class="c1"># the instance will always return an instance of attr_class.</span> <span class="n">attr_class</span> <span class="o">=</span> <span class="n">FieldFile</span> <span class="c1"># The descriptor to use for accessing the attribute off of the class.</span> <span class="n">descriptor_class</span> <span class="o">=</span> <span class="n">FileDescriptor</span> <span class="n">description</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">"File"</span><span class="p">)</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">upload_to</span><span class="o">=</span><span class="s1">''</span><span class="p">,</span> <span class="n">storage</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">_primary_key_set_explicitly</span> <span class="o">=</span> <span class="s1">'primary_key'</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="bp">self</span><span class="o">.</span><span class="n">_unique_set_explicitly</span> <span class="o">=</span> <span class="s1">'unique'</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span> <span class="o">=</span> <span class="n">storage</span> <span class="ow">or</span> <span class="n">default_storage</span> <span class="bp">self</span><span class="o">.</span><span class="n">upload_to</span> <span class="o">=</span> <span class="n">upload_to</span> <span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">upload_to</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">generate_filename</span> <span class="o">=</span> <span class="n">upload_to</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'max_length'</span><span class="p">]</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'max_length'</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">errors</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_check_unique</span><span class="p">())</span> <span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_check_primary_key</span><span class="p">())</span> <span class="k">return</span> <span class="n">errors</span> <span class="k">def</span> <span class="nf">_check_unique</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_unique_set_explicitly</span><span class="p">:</span> <span class="k">return</span> <span class="p">[</span> <span class="n">checks</span><span class="o">.</span><span class="n">Error</span><span class="p">(</span> <span class="s2">"'unique' is not a valid argument for a </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">hint</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">obj</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="s1">'fields.E200'</span><span class="p">,</span> <span class="p">)</span> <span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span> <span class="k">def</span> <span class="nf">_check_primary_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_primary_key_set_explicitly</span><span class="p">:</span> <span class="k">return</span> <span class="p">[</span> <span class="n">checks</span><span class="o">.</span><span class="n">Error</span><span class="p">(</span> <span class="s2">"'primary_key' is not a valid argument for a </span><span class="si">%s</span><span class="s2">."</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">hint</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">obj</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="s1">'fields.E201'</span><span class="p">,</span> <span class="p">)</span> <span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span> <span class="k">def</span> <span class="nf">deconstruct</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">deconstruct</span><span class="p">()</span> <span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"max_length"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="o">==</span> <span class="mi">100</span><span class="p">:</span> <span class="k">del</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">"max_length"</span><span class="p">]</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'upload_to'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">upload_to</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">default_storage</span><span class="p">:</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'storage'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">storage</span> <span class="k">return</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="k">def</span> <span class="nf">get_internal_type</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="s2">"FileField"</span> <span class="k">def</span> <span class="nf">get_prep_lookup</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lookup_type</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="s1">'name'</span><span class="p">):</span> <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">name</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_prep_lookup</span><span class="p">(</span><span class="n">lookup_type</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_prep_value</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="s2">"Returns field's value prepared for saving into a database."</span> <span class="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_prep_value</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="c1"># Need to convert File objects provided via a form to unicode for database insertion</span> <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="k">return</span> <span class="kc">None</span> <span class="k">return</span> <span class="n">six</span><span class="o">.</span><span class="n">text_type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">def</span> <span class="nf">pre_save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">model_instance</span><span class="p">,</span> <span class="n">add</span><span class="p">):</span> <span class="s2">"Returns field's value just before saving."</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">pre_save</span><span class="p">(</span><span class="n">model_instance</span><span class="p">,</span> <span class="n">add</span><span class="p">)</span> <span class="k">if</span> <span class="n">file</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">file</span><span class="o">.</span><span class="n">_committed</span><span class="p">:</span> <span class="c1"># Commit the file to storage prior to saving the model</span> <span class="n">file</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="k">return</span> <span class="n">file</span> <span class="k">def</span> <span class="nf">contribute_to_class</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">contribute_to_class</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">descriptor_class</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span> <span class="k">def</span> <span class="nf">get_directory_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="n">force_text</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">force_str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">upload_to</span><span class="p">))))</span> <span class="k">def</span> <span class="nf">get_filename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span> <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normpath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">storage</span><span class="o">.</span><span class="n">get_valid_name</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">filename</span><span class="p">)))</span> <span class="k">def</span> <span class="nf">generate_filename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span> <span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">get_directory_name</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_filename</span><span class="p">(</span><span class="n">filename</span><span class="p">))</span> <span class="k">def</span> <span class="nf">save_form_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> <span class="c1"># Important: None means "no change", other false value means "clear"</span> <span class="c1"># This subtle distinction (rather than a more explicit marker) is</span> <span class="c1"># needed because we need to consume values that are also sane for a</span> <span class="c1"># regular (non Model-) Form to find in its cleaned_data dictionary.</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># This value will be converted to unicode and stored in the</span> <span class="c1"># database, so leaving False as-is is not acceptable.</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span><span class="p">:</span> <span class="n">data</span> <span class="o">=</span> <span class="s1">''</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="k">def</span> <span class="nf">formfield</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">defaults</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'form_class'</span><span class="p">:</span> <span class="n">forms</span><span class="o">.</span><span class="n">FileField</span><span class="p">,</span> <span class="s1">'max_length'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">}</span> <span class="c1"># If a file has been provided previously, then the form doesn't require</span> <span class="c1"># that a new file is provided this time.</span> <span class="c1"># The code to mark the form field as not required is used by</span> <span class="c1"># form_for_instance, but can probably be removed once form_for_instance</span> <span class="c1"># is gone. ModelForm uses a different method to check for an existing file.</span> <span class="k">if</span> <span class="s1">'initial'</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span> <span class="n">defaults</span><span class="p">[</span><span class="s1">'required'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span> <span class="n">defaults</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">formfield</span><span class="p">(</span><span class="o">**</span><span class="n">defaults</span><span class="p">)</span></div> <span class="k">class</span> <span class="nc">ImageFileDescriptor</span><span class="p">(</span><span class="n">FileDescriptor</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Just like the FileDescriptor, but for ImageFields. The only difference is</span> <span class="sd"> assigning the width/height to the width_field/height_field, if appropriate.</span> <span class="sd"> """</span> <span class="k">def</span> <span class="nf">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> <span class="n">previous_file</span> <span class="o">=</span> <span class="n">instance</span><span class="o">.</span><span class="n">__dict__</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageFileDescriptor</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__set__</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="c1"># To prevent recalculating image dimensions when we are instantiating</span> <span class="c1"># an object from the database (bug #11084), only update dimensions if</span> <span class="c1"># the field had a value before this assignment. Since the default</span> <span class="c1"># value for FileField subclasses is an instance of field.attr_class,</span> <span class="c1"># previous_file will only be None when we are called from</span> <span class="c1"># Model.__init__(). The ImageField.update_dimension_fields method</span> <span class="c1"># hooked up to the post_init signal handles the Model.__init__() cases.</span> <span class="c1"># Assignment happening outside of Model.__init__() will trigger the</span> <span class="c1"># update right here.</span> <span class="k">if</span> <span class="n">previous_file</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">field</span><span class="o">.</span><span class="n">update_dimension_fields</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="k">class</span> <span class="nc">ImageFieldFile</span><span class="p">(</span><span class="n">ImageFile</span><span class="p">,</span> <span class="n">FieldFile</span><span class="p">):</span> <span class="k">def</span> <span class="nf">delete</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">save</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span> <span class="c1"># Clear the image dimensions cache</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'_dimensions_cache'</span><span class="p">):</span> <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dimensions_cache</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageFieldFile</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span><span class="n">save</span><span class="p">)</span> <div class="viewcode-block" id="ImageField"><a class="viewcode-back" href="../../../../../ref/models/fields.html#django.db.models.ImageField">[docs]</a><span class="k">class</span> <span class="nc">ImageField</span><span class="p">(</span><span class="n">FileField</span><span class="p">):</span> <span class="n">attr_class</span> <span class="o">=</span> <span class="n">ImageFieldFile</span> <span class="n">descriptor_class</span> <span class="o">=</span> <span class="n">ImageFileDescriptor</span> <span class="n">description</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">"Image"</span><span class="p">)</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">verbose_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">width_field</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">height_field</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span> <span class="o">=</span> <span class="n">width_field</span><span class="p">,</span> <span class="n">height_field</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">verbose_name</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">errors</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_check_image_library_installed</span><span class="p">())</span> <span class="k">return</span> <span class="n">errors</span> <span class="k">def</span> <span class="nf">_check_image_library_installed</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">try</span><span class="p">:</span> <span class="kn">from</span> <span class="nn">PIL</span> <span class="k">import</span> <span class="n">Image</span> <span class="c1"># NOQA</span> <span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> <span class="k">return</span> <span class="p">[</span> <span class="n">checks</span><span class="o">.</span><span class="n">Error</span><span class="p">(</span> <span class="s1">'Cannot use ImageField because Pillow is not installed.'</span><span class="p">,</span> <span class="n">hint</span><span class="o">=</span><span class="p">(</span><span class="s1">'Get Pillow at https://pypi.python.org/pypi/Pillow '</span> <span class="s1">'or run command "pip install Pillow".'</span><span class="p">),</span> <span class="n">obj</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="o">=</span><span class="s1">'fields.E210'</span><span class="p">,</span> <span class="p">)</span> <span class="p">]</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="p">[]</span> <span class="k">def</span> <span class="nf">deconstruct</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">deconstruct</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span><span class="p">:</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'width_field'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span><span class="p">:</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'height_field'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span> <span class="k">return</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="k">def</span> <span class="nf">contribute_to_class</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">contribute_to_class</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="c1"># Attach update_dimension_fields so that dimension fields declared</span> <span class="c1"># after their corresponding image field don't stay cleared by</span> <span class="c1"># Model.__init__, see bug #11196.</span> <span class="c1"># Only run post-initialization dimension update on non-abstract models</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">cls</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">abstract</span><span class="p">:</span> <span class="n">signals</span><span class="o">.</span><span class="n">post_init</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">update_dimension_fields</span><span class="p">,</span> <span class="n">sender</span><span class="o">=</span><span class="n">cls</span><span class="p">)</span> <span class="k">def</span> <span class="nf">update_dimension_fields</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">force</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Updates field's width and height fields, if defined.</span> <span class="sd"> This method is hooked up to model's post_init signal to update</span> <span class="sd"> dimensions after instantiating a model instance. However, dimensions</span> <span class="sd"> won't be updated if the dimensions fields are already populated. This</span> <span class="sd"> avoids unnecessary recalculation when loading an object from the</span> <span class="sd"> database.</span> <span class="sd"> Dimensions can be forced to update with force=True, which is how</span> <span class="sd"> ImageFileDescriptor.__set__ calls this method.</span> <span class="sd"> """</span> <span class="c1"># Nothing to update if the field doesn't have dimension fields.</span> <span class="n">has_dimension_fields</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">has_dimension_fields</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># getattr will call the ImageFileDescriptor's __get__ method, which</span> <span class="c1"># coerces the assigned value into an instance of self.attr_class</span> <span class="c1"># (ImageFieldFile in this case).</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">attname</span><span class="p">)</span> <span class="c1"># Nothing to update if we have no file and not being forced to update.</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">file</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">force</span><span class="p">:</span> <span class="k">return</span> <span class="n">dimension_fields_filled</span> <span class="o">=</span> <span class="ow">not</span><span class="p">(</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">width_field</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span><span class="p">))</span> <span class="ow">or</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">height_field</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span><span class="p">))</span> <span class="p">)</span> <span class="c1"># When both dimension fields have values, we are most likely loading</span> <span class="c1"># data from the database or updating an image field that already had</span> <span class="c1"># an image stored. In the first case, we don't want to update the</span> <span class="c1"># dimension fields because we are already getting their values from the</span> <span class="c1"># database. In the second case, we do want to update the dimensions</span> <span class="c1"># fields and will skip this return because force will be True since we</span> <span class="c1"># were called from ImageFileDescriptor.__set__.</span> <span class="k">if</span> <span class="n">dimension_fields_filled</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">force</span><span class="p">:</span> <span class="k">return</span> <span class="c1"># file should be an instance of ImageFieldFile or should be None.</span> <span class="k">if</span> <span class="n">file</span><span class="p">:</span> <span class="n">width</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">width</span> <span class="n">height</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span><span class="p">:</span> <span class="c1"># No file, so clear dimensions fields.</span> <span class="n">width</span> <span class="o">=</span> <span class="kc">None</span> <span class="n">height</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Update the width and height fields.</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span><span class="p">:</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">width_field</span><span class="p">,</span> <span class="n">width</span><span class="p">)</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span><span class="p">:</span> <span class="nb">setattr</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">height_field</span><span class="p">,</span> <span class="n">height</span><span class="p">)</span> <span class="k">def</span> <span class="nf">formfield</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">defaults</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'form_class'</span><span class="p">:</span> <span class="n">forms</span><span class="o">.</span><span class="n">ImageField</span><span class="p">}</span> <span class="n">defaults</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">ImageField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">formfield</span><span class="p">(</span><span class="o">**</span><span class="n">defaults</span><span class="p">)</span></div> </pre></div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> <div class="sphinxsidebarwrapper"> <h3>Browse</h3> <ul> </ul> <h3>You are here:</h3> <ul> <li> <a href="../../../../../index.html">Django 1.8.19 documentation</a> <ul><li><a href="../../../../index.html">Module code</a> <ul><li><a href="../../../../django.html">django</a> <ul><li><a href="../fields.html">django.db.models.fields</a> <ul><li>django.db.models.fields.files</li></ul> </li></ul></li></ul></li></ul> </li> </ul> <div id="searchbox" style="display: none" role="search"> <h3>Quick search</h3> <form class="search" action="../../../../../search.html" method="get"> <div><input type="text" name="q" /></div> <div><input type="submit" value="Go" /></div> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">Mar 10, 2018</p> </div> </div> <div id="ft"> <div class="nav"> <a href="../../../../index.html" title="Module code" accesskey="U">up</a></div> </div> </div> <div class="clearer"></div> </div> </body> </html>