evennia/docs/5.x/_modules/django/forms/fields.html
2025-07-01 10:01:48 +02:00

1525 lines
No EOL
202 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>django.forms.fields &#8212; Evennia latest documentation</title>
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../../../_static/nature.css?v=245aff17" />
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/documentation_options.js?v=c6e86fd7"></script>
<script src="../../../_static/doctools.js?v=9bcbadda"></script>
<script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" accesskey="U">Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">django.forms.fields</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for django.forms.fields</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Field classes.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">copy</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">datetime</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">math</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">operator</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">re</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">uuid</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">decimal</span><span class="w"> </span><span class="kn">import</span> <span class="n">Decimal</span><span class="p">,</span> <span class="n">DecimalException</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">io</span><span class="w"> </span><span class="kn">import</span> <span class="n">BytesIO</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">urllib.parse</span><span class="w"> </span><span class="kn">import</span> <span class="n">urlsplit</span><span class="p">,</span> <span class="n">urlunsplit</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.conf</span><span class="w"> </span><span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core</span><span class="w"> </span><span class="kn">import</span> <span class="n">validators</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.exceptions</span><span class="w"> </span><span class="kn">import</span> <span class="n">ValidationError</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.forms.boundfield</span><span class="w"> </span><span class="kn">import</span> <span class="n">BoundField</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.forms.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">from_current_timezone</span><span class="p">,</span> <span class="n">to_current_timezone</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.forms.widgets</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
<span class="n">FILE_INPUT_CONTRADICTION</span><span class="p">,</span>
<span class="n">CheckboxInput</span><span class="p">,</span>
<span class="n">ClearableFileInput</span><span class="p">,</span>
<span class="n">DateInput</span><span class="p">,</span>
<span class="n">DateTimeInput</span><span class="p">,</span>
<span class="n">EmailInput</span><span class="p">,</span>
<span class="n">FileInput</span><span class="p">,</span>
<span class="n">HiddenInput</span><span class="p">,</span>
<span class="n">MultipleHiddenInput</span><span class="p">,</span>
<span class="n">NullBooleanSelect</span><span class="p">,</span>
<span class="n">NumberInput</span><span class="p">,</span>
<span class="n">Select</span><span class="p">,</span>
<span class="n">SelectMultiple</span><span class="p">,</span>
<span class="n">SplitDateTimeWidget</span><span class="p">,</span>
<span class="n">SplitHiddenDateTimeWidget</span><span class="p">,</span>
<span class="n">Textarea</span><span class="p">,</span>
<span class="n">TextInput</span><span class="p">,</span>
<span class="n">TimeInput</span><span class="p">,</span>
<span class="n">URLInput</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">formats</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.choices</span><span class="w"> </span><span class="kn">import</span> <span class="n">normalize_choices</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.dateparse</span><span class="w"> </span><span class="kn">import</span> <span class="n">parse_datetime</span><span class="p">,</span> <span class="n">parse_duration</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.deprecation</span><span class="w"> </span><span class="kn">import</span> <span class="n">RemovedInDjango60Warning</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.duration</span><span class="w"> </span><span class="kn">import</span> <span class="n">duration_string</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.ipv6</span><span class="w"> </span><span class="kn">import</span> <span class="n">MAX_IPV6_ADDRESS_LENGTH</span><span class="p">,</span> <span class="n">clean_ipv6_address</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.regex_helper</span><span class="w"> </span><span class="kn">import</span> <span class="n">_lazy_re_compile</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.translation</span><span class="w"> </span><span class="kn">import</span> <span class="n">gettext_lazy</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.translation</span><span class="w"> </span><span class="kn">import</span> <span class="n">ngettext_lazy</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;Field&quot;</span><span class="p">,</span>
<span class="s2">&quot;CharField&quot;</span><span class="p">,</span>
<span class="s2">&quot;IntegerField&quot;</span><span class="p">,</span>
<span class="s2">&quot;DateField&quot;</span><span class="p">,</span>
<span class="s2">&quot;TimeField&quot;</span><span class="p">,</span>
<span class="s2">&quot;DateTimeField&quot;</span><span class="p">,</span>
<span class="s2">&quot;DurationField&quot;</span><span class="p">,</span>
<span class="s2">&quot;RegexField&quot;</span><span class="p">,</span>
<span class="s2">&quot;EmailField&quot;</span><span class="p">,</span>
<span class="s2">&quot;FileField&quot;</span><span class="p">,</span>
<span class="s2">&quot;ImageField&quot;</span><span class="p">,</span>
<span class="s2">&quot;URLField&quot;</span><span class="p">,</span>
<span class="s2">&quot;BooleanField&quot;</span><span class="p">,</span>
<span class="s2">&quot;NullBooleanField&quot;</span><span class="p">,</span>
<span class="s2">&quot;ChoiceField&quot;</span><span class="p">,</span>
<span class="s2">&quot;MultipleChoiceField&quot;</span><span class="p">,</span>
<span class="s2">&quot;ComboField&quot;</span><span class="p">,</span>
<span class="s2">&quot;MultiValueField&quot;</span><span class="p">,</span>
<span class="s2">&quot;FloatField&quot;</span><span class="p">,</span>
<span class="s2">&quot;DecimalField&quot;</span><span class="p">,</span>
<span class="s2">&quot;SplitDateTimeField&quot;</span><span class="p">,</span>
<span class="s2">&quot;GenericIPAddressField&quot;</span><span class="p">,</span>
<span class="s2">&quot;FilePathField&quot;</span><span class="p">,</span>
<span class="s2">&quot;JSONField&quot;</span><span class="p">,</span>
<span class="s2">&quot;SlugField&quot;</span><span class="p">,</span>
<span class="s2">&quot;TypedChoiceField&quot;</span><span class="p">,</span>
<span class="s2">&quot;TypedMultipleChoiceField&quot;</span><span class="p">,</span>
<span class="s2">&quot;UUIDField&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">Field</span><span class="p">:</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">TextInput</span> <span class="c1"># Default widget to use when rendering this type of Field.</span>
<span class="n">hidden_widget</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">HiddenInput</span> <span class="c1"># Default widget to use when rendering this as &quot;hidden&quot;.</span>
<span class="p">)</span>
<span class="n">default_validators</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Default set of validators</span>
<span class="c1"># Add an &#39;invalid&#39; entry to default_error_message if you want a specific</span>
<span class="c1"># field error message not raised by the field validators.</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;required&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;This field is required.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="n">empty_values</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">EMPTY_VALUES</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">required</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">widget</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">initial</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">help_text</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">error_messages</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">show_hidden_initial</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">validators</span><span class="o">=</span><span class="p">(),</span>
<span class="n">localize</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">disabled</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">label_suffix</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">template_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="p">):</span>
<span class="c1"># required -- Boolean that specifies whether the field is required.</span>
<span class="c1"># True by default.</span>
<span class="c1"># widget -- A Widget class, or instance of a Widget class, that should</span>
<span class="c1"># be used for this Field when displaying it. Each Field has a</span>
<span class="c1"># default Widget that it&#39;ll use if you don&#39;t specify this. In</span>
<span class="c1"># most cases, the default widget is TextInput.</span>
<span class="c1"># label -- A verbose name for this field, for use in displaying this</span>
<span class="c1"># field in a form. By default, Django will use a &quot;pretty&quot;</span>
<span class="c1"># version of the form field name, if the Field is part of a</span>
<span class="c1"># Form.</span>
<span class="c1"># initial -- A value to use in this Field&#39;s initial display. This value</span>
<span class="c1"># is *not* used as a fallback if data isn&#39;t given.</span>
<span class="c1"># help_text -- An optional string to use as &quot;help text&quot; for this Field.</span>
<span class="c1"># error_messages -- An optional dictionary to override the default</span>
<span class="c1"># messages that the field will raise.</span>
<span class="c1"># show_hidden_initial -- Boolean that specifies if it is needed to render a</span>
<span class="c1"># hidden widget with initial value after widget.</span>
<span class="c1"># validators -- List of additional validators to use</span>
<span class="c1"># localize -- Boolean that specifies if the field should be localized.</span>
<span class="c1"># disabled -- Boolean that specifies whether the field is disabled, that</span>
<span class="c1"># is its widget is shown in the form but not editable.</span>
<span class="c1"># label_suffix -- Suffix to be added to the label. Overrides</span>
<span class="c1"># form&#39;s label_suffix.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">initial</span> <span class="o">=</span> <span class="n">required</span><span class="p">,</span> <span class="n">label</span><span class="p">,</span> <span class="n">initial</span>
<span class="bp">self</span><span class="o">.</span><span class="n">show_hidden_initial</span> <span class="o">=</span> <span class="n">show_hidden_initial</span>
<span class="bp">self</span><span class="o">.</span><span class="n">help_text</span> <span class="o">=</span> <span class="n">help_text</span>
<span class="bp">self</span><span class="o">.</span><span class="n">disabled</span> <span class="o">=</span> <span class="n">disabled</span>
<span class="bp">self</span><span class="o">.</span><span class="n">label_suffix</span> <span class="o">=</span> <span class="n">label_suffix</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">widget</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="nb">type</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">widget</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="c1"># Trigger the localization machinery if needed.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">localize</span> <span class="o">=</span> <span class="n">localize</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">localize</span><span class="p">:</span>
<span class="n">widget</span><span class="o">.</span><span class="n">is_localized</span> <span class="o">=</span> <span class="kc">True</span>
<span class="c1"># Let the widget know whether it should display as required.</span>
<span class="n">widget</span><span class="o">.</span><span class="n">is_required</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span>
<span class="c1"># Hook into self.widget_attrs() for any Field-specific HTML attributes.</span>
<span class="n">extra_attrs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="n">extra_attrs</span><span class="p">:</span>
<span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">extra_attrs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">widget</span> <span class="o">=</span> <span class="n">widget</span>
<span class="n">messages</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__mro__</span><span class="p">):</span>
<span class="n">messages</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">getattr</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="s2">&quot;default_error_messages&quot;</span><span class="p">,</span> <span class="p">{}))</span>
<span class="n">messages</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">error_messages</span> <span class="ow">or</span> <span class="p">{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span> <span class="o">=</span> <span class="n">messages</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validators</span> <span class="o">=</span> <span class="p">[</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">default_validators</span><span class="p">,</span> <span class="o">*</span><span class="n">validators</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">template_name</span> <span class="o">=</span> <span class="n">template_name</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">prepare_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="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">run_validators</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="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">validators</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">v</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ValidationError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="s2">&quot;code&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">e</span><span class="o">.</span><span class="n">code</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">:</span>
<span class="n">e</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="n">e</span><span class="o">.</span><span class="n">code</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="n">e</span><span class="o">.</span><span class="n">error_list</span><span class="p">)</span>
<span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate the given value and return its &quot;cleaned&quot; value as an</span>
<span class="sd"> appropriate Python object. Raise ValidationError for any errors.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">run_validators</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">bound_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">initial</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return the value that should be shown for this field on render of a</span>
<span class="sd"> bound form, given the submitted POST data for the field and the initial</span>
<span class="sd"> data, if any.</span>
<span class="sd"> For most fields, this will simply be data; FileFields need to handle it</span>
<span class="sd"> a bit differently.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="n">initial</span>
<span class="k">return</span> <span class="n">data</span>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Given a Widget instance (*not* a Widget class), return a dictionary of</span>
<span class="sd"> any HTML attributes that should be added to the Widget, based on this</span>
<span class="sd"> Field.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return True if data differs from initial.&quot;&quot;&quot;</span>
<span class="c1"># Always return False if the field is disabled since self.bound_data</span>
<span class="c1"># always uses the initial value in this case.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">data</span><span class="p">)</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="s2">&quot;_coerce&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coerce</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coerce</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ValidationError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># For purposes of seeing whether something has changed, None is</span>
<span class="c1"># the same as an empty string, if the data or initial value we get</span>
<span class="c1"># is None, replace it with &#39;&#39;.</span>
<span class="n">initial_value</span> <span class="o">=</span> <span class="n">initial</span> <span class="k">if</span> <span class="n">initial</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">data_value</span> <span class="o">=</span> <span class="n">data</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="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="n">initial_value</span> <span class="o">!=</span> <span class="n">data_value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">get_bound_field</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">form</span><span class="p">,</span> <span class="n">field_name</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a BoundField instance that will be used when accessing the form</span>
<span class="sd"> field in a template.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">BoundField</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="n">field_name</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">memo</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">memo</span><span class="p">[</span><span class="nb">id</span><span class="p">(</span><span class="bp">self</span><span class="p">)]</span> <span class="o">=</span> <span class="n">result</span>
<span class="n">result</span><span class="o">.</span><span class="n">widget</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">widget</span><span class="p">,</span> <span class="n">memo</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">error_messages</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="n">result</span><span class="o">.</span><span class="n">validators</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">validators</span><span class="p">[:]</span>
<span class="k">return</span> <span class="n">result</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_clean_bound_field</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bf</span><span class="p">):</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">bf</span><span class="o">.</span><span class="n">initial</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span> <span class="k">else</span> <span class="n">bf</span><span class="o">.</span><span class="n">data</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<div class="viewcode-block" id="CharField">
<a class="viewcode-back" href="../../../api/evennia.utils.picklefield.html#evennia.utils.picklefield.CharField">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">CharField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<div class="viewcode-block" id="CharField.__init__">
<a class="viewcode-back" href="../../../api/evennia.utils.picklefield.html#evennia.utils.picklefield.CharField.__init__">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">min_length</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">strip</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">empty_value</span><span class="o">=</span><span class="s2">&quot;&quot;</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">max_length</span> <span class="o">=</span> <span class="n">max_length</span>
<span class="bp">self</span><span class="o">.</span><span class="n">min_length</span> <span class="o">=</span> <span class="n">min_length</span>
<span class="bp">self</span><span class="o">.</span><span class="n">strip</span> <span class="o">=</span> <span class="n">strip</span>
<span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span> <span class="o">=</span> <span class="n">empty_value</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">min_length</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">MinLengthValidator</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">min_length</span><span class="p">)))</span>
<span class="k">if</span> <span class="n">max_length</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">MaxLengthValidator</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">max_length</span><span class="p">)))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">ProhibitNullCharactersValidator</span><span class="p">())</span></div>
<div class="viewcode-block" id="CharField.to_python">
<a class="viewcode-back" href="../../../api/evennia.utils.picklefield.html#evennia.utils.picklefield.CharField.to_python">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;Return a string.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">strip</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">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span>
<span class="k">return</span> <span class="n">value</span></div>
<div class="viewcode-block" id="CharField.widget_attrs">
<a class="viewcode-back" href="../../../api/evennia.utils.picklefield.html#evennia.utils.picklefield.CharField.widget_attrs">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">widget</span><span class="o">.</span><span class="n">is_hidden</span><span class="p">:</span>
<span class="c1"># The HTML attribute is maxlength, not max_length.</span>
<span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;maxlength&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min_length</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">widget</span><span class="o">.</span><span class="n">is_hidden</span><span class="p">:</span>
<span class="c1"># The HTML attribute is minlength, not min_length.</span>
<span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;minlength&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min_length</span><span class="p">)</span>
<span class="k">return</span> <span class="n">attrs</span></div>
</div>
<span class="k">class</span><span class="w"> </span><span class="nc">IntegerField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">NumberInput</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a whole number.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="n">re_decimal</span> <span class="o">=</span> <span class="n">_lazy_re_compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\.0*\s*$&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">max_value</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">min_value</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">step_size</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">max_value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">min_value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">step_size</span> <span class="o">=</span> <span class="n">max_value</span><span class="p">,</span> <span class="n">min_value</span><span class="p">,</span> <span class="n">step_size</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">&quot;localize&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget</span> <span class="o">==</span> <span class="n">NumberInput</span><span class="p">:</span>
<span class="c1"># Localized number input is not well supported on most browsers</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;widget&quot;</span><span class="p">,</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">max_value</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">MaxValueValidator</span><span class="p">(</span><span class="n">max_value</span><span class="p">))</span>
<span class="k">if</span> <span class="n">min_value</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">MinValueValidator</span><span class="p">(</span><span class="n">min_value</span><span class="p">))</span>
<span class="k">if</span> <span class="n">step_size</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">validators</span><span class="o">.</span><span class="n">StepValueValidator</span><span class="p">(</span><span class="n">step_size</span><span class="p">,</span> <span class="n">offset</span><span class="o">=</span><span class="n">min_value</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that int() can be called on the input. Return the result</span>
<span class="sd"> of int() or None for empty values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">localize</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">formats</span><span class="o">.</span><span class="n">sanitize_separators</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="c1"># Strip trailing decimal and zeros.</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">re_decimal</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)))</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="n">NumberInput</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">min_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min_value</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;max&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_value</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">step_size</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">attrs</span><span class="p">[</span><span class="s2">&quot;step&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">step_size</span>
<span class="k">return</span> <span class="n">attrs</span>
<span class="k">class</span><span class="w"> </span><span class="nc">FloatField</span><span class="p">(</span><span class="n">IntegerField</span><span class="p">):</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a number.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that float() can be called on the input. Return the result</span>
<span class="sd"> of float() or None for empty values.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">IntegerField</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">localize</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">formats</span><span class="o">.</span><span class="n">sanitize_separators</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">math</span><span class="o">.</span><span class="n">isfinite</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="n">NumberInput</span><span class="p">)</span> <span class="ow">and</span> <span class="s2">&quot;step&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">step_size</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">step</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">step_size</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">step</span> <span class="o">=</span> <span class="s2">&quot;any&quot;</span>
<span class="n">attrs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;step&quot;</span><span class="p">,</span> <span class="n">step</span><span class="p">)</span>
<span class="k">return</span> <span class="n">attrs</span>
<span class="k">class</span><span class="w"> </span><span class="nc">DecimalField</span><span class="p">(</span><span class="n">IntegerField</span><span class="p">):</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a number.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">max_value</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">min_value</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">max_digits</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">decimal_places</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="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">max_digits</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">decimal_places</span> <span class="o">=</span> <span class="n">max_digits</span><span class="p">,</span> <span class="n">decimal_places</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">max_value</span><span class="o">=</span><span class="n">max_value</span><span class="p">,</span> <span class="n">min_value</span><span class="o">=</span><span class="n">min_value</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">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">validators</span><span class="o">.</span><span class="n">DecimalValidator</span><span class="p">(</span><span class="n">max_digits</span><span class="p">,</span> <span class="n">decimal_places</span><span class="p">))</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the input is a decimal number. Return a Decimal</span>
<span class="sd"> instance or None for empty values. Ensure that there are no more</span>
<span class="sd"> than max_digits in the number and no more than decimal_places digits</span>
<span class="sd"> after the decimal point.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">localize</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">formats</span><span class="o">.</span><span class="n">sanitize_separators</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">Decimal</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
<span class="k">except</span> <span class="n">DecimalException</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="o">.</span><span class="n">is_finite</span><span class="p">():</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">value</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="n">NumberInput</span><span class="p">)</span> <span class="ow">and</span> <span class="s2">&quot;step&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">decimal_places</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># Use exponential notation for small values since they might</span>
<span class="c1"># be parsed as 0 otherwise. ref #20765</span>
<span class="n">step</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">Decimal</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">scaleb</span><span class="p">(</span><span class="o">-</span><span class="bp">self</span><span class="o">.</span><span class="n">decimal_places</span><span class="p">))</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">step</span> <span class="o">=</span> <span class="s2">&quot;any&quot;</span>
<span class="n">attrs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;step&quot;</span><span class="p">,</span> <span class="n">step</span><span class="p">)</span>
<span class="k">return</span> <span class="n">attrs</span>
<span class="k">class</span><span class="w"> </span><span class="nc">BaseTemporalField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">input_formats</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="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">input_formats</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">input_formats</span> <span class="o">=</span> <span class="n">input_formats</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="c1"># Try to strptime against each input format.</span>
<span class="k">for</span> <span class="nb">format</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">input_formats</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
<span class="k">continue</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">strptime</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="nb">format</span><span class="p">):</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s2">&quot;Subclasses must define this method.&quot;</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">DateField</span><span class="p">(</span><span class="n">BaseTemporalField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">DateInput</span>
<span class="n">input_formats</span> <span class="o">=</span> <span class="n">formats</span><span class="o">.</span><span class="n">get_format_lazy</span><span class="p">(</span><span class="s2">&quot;DATE_INPUT_FORMATS&quot;</span><span class="p">)</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid date.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the input can be converted to a date. Return a Python</span>
<span class="sd"> datetime.date object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span><span class="o">.</span><span class="n">date</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">strptime</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="nb">format</span><span class="p">):</span>
<span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span><span class="o">.</span><span class="n">date</span><span class="p">()</span>
<span class="k">class</span><span class="w"> </span><span class="nc">TimeField</span><span class="p">(</span><span class="n">BaseTemporalField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">TimeInput</span>
<span class="n">input_formats</span> <span class="o">=</span> <span class="n">formats</span><span class="o">.</span><span class="n">get_format_lazy</span><span class="p">(</span><span class="s2">&quot;TIME_INPUT_FORMATS&quot;</span><span class="p">)</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid time.&quot;</span><span class="p">)}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the input can be converted to a time. Return a Python</span>
<span class="sd"> datetime.time object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">strptime</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="nb">format</span><span class="p">):</span>
<span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="k">class</span><span class="w"> </span><span class="nc">DateTimeFormatsIterator</span><span class="p">:</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield from</span> <span class="n">formats</span><span class="o">.</span><span class="n">get_format</span><span class="p">(</span><span class="s2">&quot;DATETIME_INPUT_FORMATS&quot;</span><span class="p">)</span>
<span class="k">yield from</span> <span class="n">formats</span><span class="o">.</span><span class="n">get_format</span><span class="p">(</span><span class="s2">&quot;DATE_INPUT_FORMATS&quot;</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">DateTimeField</span><span class="p">(</span><span class="n">BaseTemporalField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">DateTimeInput</span>
<span class="n">input_formats</span> <span class="o">=</span> <span class="n">DateTimeFormatsIterator</span><span class="p">()</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid date/time.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">prepare_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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">):</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">to_current_timezone</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the input can be converted to a datetime. Return a</span>
<span class="sd"> Python datetime.datetime object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">):</span>
<span class="k">return</span> <span class="n">from_current_timezone</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">year</span><span class="p">,</span> <span class="n">value</span><span class="o">.</span><span class="n">month</span><span class="p">,</span> <span class="n">value</span><span class="o">.</span><span class="n">day</span><span class="p">)</span>
<span class="k">return</span> <span class="n">from_current_timezone</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">parse_datetime</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">from_current_timezone</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">strptime</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="nb">format</span><span class="p">):</span>
<span class="k">return</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">format</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">DurationField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid duration.&quot;</span><span class="p">),</span>
<span class="s2">&quot;overflow&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;The number of days must be between </span><span class="si">{min_days}</span><span class="s2"> and </span><span class="si">{max_days}</span><span class="s2">.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">prepare_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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">):</span>
<span class="k">return</span> <span class="n">duration_string</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">parse_duration</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">OverflowError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;overflow&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">min_days</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">days</span><span class="p">,</span>
<span class="n">max_days</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">days</span><span class="p">,</span>
<span class="p">),</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;overflow&quot;</span><span class="p">,</span>
<span class="p">)</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">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">class</span><span class="w"> </span><span class="nc">RegexField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regex</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> regex can be either a string or a compiled regular expression object.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;strip&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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">_set_regex</span><span class="p">(</span><span class="n">regex</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_get_regex</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_set_regex</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">regex</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">regex</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">regex</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_regex</span> <span class="o">=</span> <span class="n">regex</span>
<span class="k">if</span> <span class="p">(</span>
<span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;_regex_validator&quot;</span><span class="p">)</span>
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_regex_validator</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">validators</span>
<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_regex_validator</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_regex_validator</span> <span class="o">=</span> <span class="n">validators</span><span class="o">.</span><span class="n">RegexValidator</span><span class="p">(</span><span class="n">regex</span><span class="o">=</span><span class="n">regex</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validators</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_regex_validator</span><span class="p">)</span>
<span class="n">regex</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">_get_regex</span><span class="p">,</span> <span class="n">_set_regex</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">EmailField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">EmailInput</span>
<span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_email</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</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="c1"># The default maximum length of an email is 320 characters per RFC 3696</span>
<span class="c1"># section 3.</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;max_length&quot;</span><span class="p">,</span> <span class="mi">320</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">strip</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">FileField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">ClearableFileInput</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;No file was submitted. Check the encoding type on the form.&quot;</span><span class="p">),</span>
<span class="s2">&quot;missing&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;No file was submitted.&quot;</span><span class="p">),</span>
<span class="s2">&quot;empty&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;The submitted file is empty.&quot;</span><span class="p">),</span>
<span class="s2">&quot;max_length&quot;</span><span class="p">:</span> <span class="n">ngettext_lazy</span><span class="p">(</span>
<span class="s2">&quot;Ensure this filename has at most </span><span class="si">%(max)d</span><span class="s2"> character (it has </span><span class="si">%(length)d</span><span class="s2">).&quot;</span><span class="p">,</span>
<span class="s2">&quot;Ensure this filename has at most </span><span class="si">%(max)d</span><span class="s2"> characters (it has </span><span class="si">%(length)d</span><span class="s2">).&quot;</span><span class="p">,</span>
<span class="s2">&quot;max&quot;</span><span class="p">,</span>
<span class="p">),</span>
<span class="s2">&quot;contradiction&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Please either submit a file or check the clear checkbox, not both.&quot;</span>
<span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">max_length</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">allow_empty_file</span><span class="o">=</span><span class="kc">False</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">max_length</span> <span class="o">=</span> <span class="n">max_length</span>
<span class="bp">self</span><span class="o">.</span><span class="n">allow_empty_file</span> <span class="o">=</span> <span class="n">allow_empty_file</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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="w"> </span><span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="n">data</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="c1"># UploadedFile objects should have name and size attributes.</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">file_name</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">name</span>
<span class="n">file_size</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">size</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">max_length</span><span class="p">:</span>
<span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;max&quot;</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="s2">&quot;length&quot;</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">file_name</span><span class="p">)}</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;max_length&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;max_length&quot;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span>
<span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">file_name</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</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">allow_empty_file</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">file_size</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;empty&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;empty&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">data</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">initial</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="c1"># If the widget got contradictory inputs, we raise a validation error</span>
<span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="n">FILE_INPUT_CONTRADICTION</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;contradiction&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;contradiction&quot;</span>
<span class="p">)</span>
<span class="c1"># False means the field value should be cleared; further validation is</span>
<span class="c1"># not needed.</span>
<span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">False</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">required</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="c1"># If the field is required, clearing is not possible (the widget</span>
<span class="c1"># shouldn&#39;t return False data in that case anyway). False is not</span>
<span class="c1"># in self.empty_value; if a False value makes it this far</span>
<span class="c1"># it should be validated from here on out as None (so it will be</span>
<span class="c1"># caught by the required check).</span>
<span class="n">data</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span> <span class="ow">and</span> <span class="n">initial</span><span class="p">:</span>
<span class="k">return</span> <span class="n">initial</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">bound_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">initial</span><span class="p">):</span>
<span class="k">return</span> <span class="n">initial</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</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">disabled</span> <span class="ow">and</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_clean_bound_field</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bf</span><span class="p">):</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">bf</span><span class="o">.</span><span class="n">initial</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span> <span class="k">else</span> <span class="n">bf</span><span class="o">.</span><span class="n">data</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">bf</span><span class="o">.</span><span class="n">initial</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ImageField</span><span class="p">(</span><span class="n">FileField</span><span class="p">):</span>
<span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_image_file_extension</span><span class="p">]</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid_image&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Upload a valid image. The file you uploaded was either not an &quot;</span>
<span class="s2">&quot;image or a corrupted image.&quot;</span>
<span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check that the file-upload field data contains a valid image (GIF, JPG,</span>
<span class="sd"> PNG, etc. -- whatever Pillow supports).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">if</span> <span class="n">f</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="kn">from</span><span class="w"> </span><span class="nn">PIL</span><span class="w"> </span><span class="kn">import</span> <span class="n">Image</span>
<span class="c1"># We need to get a file object for Pillow. We might have a path or we might</span>
<span class="c1"># have to read the data into memory.</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s2">&quot;temporary_file_path&quot;</span><span class="p">):</span>
<span class="n">file</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">temporary_file_path</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">):</span>
<span class="n">file</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">file</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s2">&quot;content&quot;</span><span class="p">])</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># load() could spot a truncated JPEG, but it loads the entire</span>
<span class="c1"># image in memory, which is a DoS vector. See #3848 and #18520.</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1"># verify() must be called immediately after the constructor.</span>
<span class="n">image</span><span class="o">.</span><span class="n">verify</span><span class="p">()</span>
<span class="c1"># Annotating so subclasses can reuse it for their own validation</span>
<span class="n">f</span><span class="o">.</span><span class="n">image</span> <span class="o">=</span> <span class="n">image</span>
<span class="c1"># Pillow doesn&#39;t detect the MIME type of all formats. In those</span>
<span class="c1"># cases, content_type will be None.</span>
<span class="n">f</span><span class="o">.</span><span class="n">content_type</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">MIME</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">image</span><span class="o">.</span><span class="n">format</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<span class="c1"># Pillow doesn&#39;t recognize it as an image.</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_image&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_image&quot;</span><span class="p">,</span>
<span class="p">)</span> <span class="kn">from</span><span class="w"> </span><span class="nn">exc</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">&quot;seek&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">callable</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">):</span>
<span class="n">f</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="k">return</span> <span class="n">f</span>
<span class="k">def</span><span class="w"> </span><span class="nf">widget_attrs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">):</span>
<span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">widget_attrs</span><span class="p">(</span><span class="n">widget</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">widget</span><span class="p">,</span> <span class="n">FileInput</span><span class="p">)</span> <span class="ow">and</span> <span class="s2">&quot;accept&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">widget</span><span class="o">.</span><span class="n">attrs</span><span class="p">:</span>
<span class="n">attrs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;accept&quot;</span><span class="p">,</span> <span class="s2">&quot;image/*&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">attrs</span>
<span class="k">class</span><span class="w"> </span><span class="nc">URLField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">URLInput</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid URL.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">URLValidator</span><span class="p">()]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">assume_scheme</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="k">if</span> <span class="n">assume_scheme</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">FORMS_URLFIELD_ASSUME_HTTPS</span><span class="p">:</span>
<span class="n">assume_scheme</span> <span class="o">=</span> <span class="s2">&quot;https&quot;</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="s2">&quot;The default scheme will be changed from &#39;http&#39; to &#39;https&#39; in &quot;</span>
<span class="s2">&quot;Django 6.0. Pass the forms.URLField.assume_scheme argument to &quot;</span>
<span class="s2">&quot;silence this warning, or set the FORMS_URLFIELD_ASSUME_HTTPS &quot;</span>
<span class="s2">&quot;transitional setting to True to opt into using &#39;https&#39; as the new &quot;</span>
<span class="s2">&quot;default scheme.&quot;</span><span class="p">,</span>
<span class="n">RemovedInDjango60Warning</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="p">)</span>
<span class="n">assume_scheme</span> <span class="o">=</span> <span class="s2">&quot;http&quot;</span>
<span class="c1"># RemovedInDjango60Warning: When the deprecation ends, replace with:</span>
<span class="c1"># self.assume_scheme = assume_scheme or &quot;https&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assume_scheme</span> <span class="o">=</span> <span class="n">assume_scheme</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">strip</span><span class="o">=</span><span class="kc">True</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="w"> </span><span class="nf">to_python</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="k">def</span><span class="w"> </span><span class="nf">split_url</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a list of url parts via urlparse.urlsplit(), or raise</span>
<span class="sd"> ValidationError for some malformed URLs.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="c1"># urlparse.urlsplit can raise a ValueError with some</span>
<span class="c1"># misformatted URLs.</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span><span class="p">:</span>
<span class="n">url_fields</span> <span class="o">=</span> <span class="n">split_url</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">url_fields</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="c1"># If no URL scheme given, add a scheme.</span>
<span class="n">url_fields</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">assume_scheme</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">url_fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
<span class="c1"># Assume that if no domain is provided, that the path segment</span>
<span class="c1"># contains the domain.</span>
<span class="n">url_fields</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">url_fields</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="n">url_fields</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># Rebuild the url_fields list, since the domain segment may now</span>
<span class="c1"># contain the path too.</span>
<span class="n">url_fields</span> <span class="o">=</span> <span class="n">split_url</span><span class="p">(</span><span class="n">urlunsplit</span><span class="p">(</span><span class="n">url_fields</span><span class="p">))</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">urlunsplit</span><span class="p">(</span><span class="n">url_fields</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">class</span><span class="w"> </span><span class="nc">BooleanField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">CheckboxInput</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;Return a Python boolean object.&quot;&quot;&quot;</span>
<span class="c1"># Explicitly check for the string &#39;False&#39;, which is what a hidden field</span>
<span class="c1"># will submit for False. Also check for &#39;0&#39;, since this is what</span>
<span class="c1"># RadioSelect will provide. Because bool(&quot;True&quot;) == bool(&#39;1&#39;) == True,</span>
<span class="c1"># we don&#39;t need to handle that explicitly.</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="n">value</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;false&quot;</span><span class="p">,</span> <span class="s2">&quot;0&quot;</span><span class="p">):</span>
<span class="n">value</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="k">if</span> <span class="ow">not</span> <span class="n">value</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="c1"># Sometimes data or initial may be a string equivalent of a boolean</span>
<span class="c1"># so we should run it through to_python first to get a boolean value</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">NullBooleanField</span><span class="p">(</span><span class="n">BooleanField</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A field whose valid values are None, True, and False. Clean invalid values</span>
<span class="sd"> to None.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">NullBooleanSelect</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Explicitly check for the string &#39;True&#39; and &#39;False&#39;, which is what a</span>
<span class="sd"> hidden field will submit for True and False, for &#39;true&#39; and &#39;false&#39;,</span>
<span class="sd"> which are likely to be returned by JavaScript serializations of forms,</span>
<span class="sd"> and for &#39;1&#39; and &#39;0&#39;, which is what a RadioField will submit. Unlike</span>
<span class="sd"> the Booleanfield, this field must check for True because it doesn&#39;t</span>
<span class="sd"> use the bool() function.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="s2">&quot;True&quot;</span><span class="p">,</span> <span class="s2">&quot;true&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">elif</span> <span class="n">value</span> <span class="ow">in</span> <span class="p">(</span><span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;False&quot;</span><span class="p">,</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span> <span class="s2">&quot;0&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="k">pass</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ChoiceField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">Select</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid_choice&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Select a valid choice. </span><span class="si">%(value)s</span><span class="s2"> is not one of the available choices.&quot;</span>
<span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">choices</span><span class="o">=</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="o">.</span><span class="fm">__init__</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">choices</span> <span class="o">=</span> <span class="n">choices</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">memo</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__deepcopy__</span><span class="p">(</span><span class="n">memo</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">_choices</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_choices</span><span class="p">,</span> <span class="n">memo</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">choices</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_choices</span>
<span class="nd">@choices</span><span class="o">.</span><span class="n">setter</span>
<span class="k">def</span><span class="w"> </span><span class="nf">choices</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="c1"># Setting choices on the field also sets the choices on the widget.</span>
<span class="c1"># Note that the property setter for the widget will re-normalize.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_choices</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">choices</span> <span class="o">=</span> <span class="n">normalize_choices</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="w"> </span><span class="sd">&quot;&quot;&quot;Return a string.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="w"> </span><span class="sd">&quot;&quot;&quot;Validate that the input is in self.choices.&quot;&quot;&quot;</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">valid_value</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">value</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">valid_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="w"> </span><span class="sd">&quot;&quot;&quot;Check to see if the provided value is a valid choice.&quot;&quot;&quot;</span>
<span class="n">text_value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">choices</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
<span class="c1"># This is an optgroup, so look inside the group for options</span>
<span class="k">for</span> <span class="n">k2</span><span class="p">,</span> <span class="n">v2</span> <span class="ow">in</span> <span class="n">v</span><span class="p">:</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">k2</span> <span class="ow">or</span> <span class="n">text_value</span> <span class="o">==</span> <span class="nb">str</span><span class="p">(</span><span class="n">k2</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="n">k</span> <span class="ow">or</span> <span class="n">text_value</span> <span class="o">==</span> <span class="nb">str</span><span class="p">(</span><span class="n">k</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">class</span><span class="w"> </span><span class="nc">TypedChoiceField</span><span class="p">(</span><span class="n">ChoiceField</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">coerce</span><span class="o">=</span><span class="k">lambda</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</span><span class="p">,</span> <span class="n">empty_value</span><span class="o">=</span><span class="s2">&quot;&quot;</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">coerce</span> <span class="o">=</span> <span class="n">coerce</span>
<span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span> <span class="o">=</span> <span class="n">empty_value</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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="w"> </span><span class="nf">_coerce</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the value can be coerced to the right type (if not empty).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span> <span class="ow">or</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">coerce</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="n">ValidationError</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">value</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</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="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coerce</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">MultipleChoiceField</span><span class="p">(</span><span class="n">ChoiceField</span><span class="p">):</span>
<span class="n">hidden_widget</span> <span class="o">=</span> <span class="n">MultipleHiddenInput</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">SelectMultiple</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid_choice&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Select a valid choice. </span><span class="si">%(value)s</span><span class="s2"> is not one of the available choices.&quot;</span>
<span class="p">),</span>
<span class="s2">&quot;invalid_list&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a list of values.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="k">if</span> <span class="ow">not</span> <span class="n">value</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_list&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_list&quot;</span>
<span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">val</span><span class="p">)</span> <span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">value</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="w"> </span><span class="sd">&quot;&quot;&quot;Validate that the input is a list or tuple.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">value</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span><span class="p">)</span>
<span class="c1"># Validate that each value in the value list is in self.choices.</span>
<span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="n">value</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">valid_value</span><span class="p">(</span><span class="n">val</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">val</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">initial</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">initial</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="n">initial_set</span> <span class="o">=</span> <span class="p">{</span><span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">initial</span><span class="p">}</span>
<span class="n">data_set</span> <span class="o">=</span> <span class="p">{</span><span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">data</span><span class="p">}</span>
<span class="k">return</span> <span class="n">data_set</span> <span class="o">!=</span> <span class="n">initial_set</span>
<span class="k">class</span><span class="w"> </span><span class="nc">TypedMultipleChoiceField</span><span class="p">(</span><span class="n">MultipleChoiceField</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">coerce</span><span class="o">=</span><span class="k">lambda</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</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">coerce</span> <span class="o">=</span> <span class="n">coerce</span>
<span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;empty_value&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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="w"> </span><span class="nf">_coerce</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate that the values are in self.choices and can be coerced to the</span>
<span class="sd"> right type.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">value</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span> <span class="ow">or</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span>
<span class="n">new_value</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">choice</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">new_value</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">coerce</span><span class="p">(</span><span class="n">choice</span><span class="p">))</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">,</span> <span class="n">ValidationError</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_choice&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">choice</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">new_value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</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="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_coerce</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="k">if</span> <span class="n">value</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_value</span><span class="p">:</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ComboField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A Field whose clean() method calls multiple Field clean() methods.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fields</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="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="c1"># Set &#39;required&#39; to False on the individual fields, because the</span>
<span class="c1"># required validation will be handled by ComboField, not by those</span>
<span class="c1"># individual fields.</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">fields</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">required</span> <span class="o">=</span> <span class="kc">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fields</span> <span class="o">=</span> <span class="n">fields</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate the given value against all of self.fields, which is a</span>
<span class="sd"> list of Field instances.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">class</span><span class="w"> </span><span class="nc">MultiValueField</span><span class="p">(</span><span class="n">Field</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Aggregate the logic of multiple Fields.</span>
<span class="sd"> Its clean() method takes a &quot;decompressed&quot; list of values, which are then</span>
<span class="sd"> cleaned into a single value according to self.fields. Each value in</span>
<span class="sd"> this list is cleaned by the corresponding field -- the first value is</span>
<span class="sd"> cleaned by the first field, the second value is cleaned by the second</span>
<span class="sd"> field, etc. Once all fields are cleaned, the list of clean values is</span>
<span class="sd"> &quot;compressed&quot; into a single value.</span>
<span class="sd"> Subclasses should not have to implement clean(). Instead, they must</span>
<span class="sd"> implement compress(), which takes a list of valid values and returns a</span>
<span class="sd"> &quot;compressed&quot; version of those values -- a single value.</span>
<span class="sd"> You&#39;ll probably want to use this with MultiWidget.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a list of values.&quot;</span><span class="p">),</span>
<span class="s2">&quot;incomplete&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a complete value.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fields</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">require_all_fields</span><span class="o">=</span><span class="kc">True</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">require_all_fields</span> <span class="o">=</span> <span class="n">require_all_fields</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">fields</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">error_messages</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;incomplete&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;incomplete&quot;</span><span class="p">])</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="n">f</span><span class="o">.</span><span class="n">disabled</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">require_all_fields</span><span class="p">:</span>
<span class="c1"># Set &#39;required&#39; to False on the individual fields, because the</span>
<span class="c1"># required validation will be handled by MultiValueField, not</span>
<span class="c1"># by those individual fields.</span>
<span class="n">f</span><span class="o">.</span><span class="n">required</span> <span class="o">=</span> <span class="kc">False</span>
<span class="bp">self</span><span class="o">.</span><span class="n">fields</span> <span class="o">=</span> <span class="n">fields</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__deepcopy__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">memo</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">__deepcopy__</span><span class="p">(</span><span class="n">memo</span><span class="p">)</span>
<span class="n">result</span><span class="o">.</span><span class="n">fields</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">__deepcopy__</span><span class="p">(</span><span class="n">memo</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
<span class="k">def</span><span class="w"> </span><span class="nf">validate</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="k">pass</span>
<span class="k">def</span><span class="w"> </span><span class="nf">clean</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="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate every value in the given list. A value is validated against</span>
<span class="sd"> the corresponding Field in self.fields.</span>
<span class="sd"> For example, if this MultiValueField was instantiated with</span>
<span class="sd"> fields=(DateField(), TimeField()), clean() would call</span>
<span class="sd"> DateField.clean(value[0]) and TimeField.clean(value[1]).</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">clean_data</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">errors</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">decompress</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">value</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">value</span> <span class="ow">or</span> <span class="ow">not</span> <span class="p">[</span><span class="n">v</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">value</span> <span class="k">if</span> <span class="n">v</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">]:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">compress</span><span class="p">([])</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">field</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">field_value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="n">field_value</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">field_value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">require_all_fields</span><span class="p">:</span>
<span class="c1"># Raise a &#39;required&#39; error if the MultiValueField is</span>
<span class="c1"># required and any field is empty.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;required&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;required&quot;</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">field</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="c1"># Otherwise, add an &#39;incomplete&#39; error to the list of</span>
<span class="c1"># collected errors and skip field cleaning, if a required</span>
<span class="c1"># field is empty.</span>
<span class="k">if</span> <span class="n">field</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;incomplete&quot;</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">errors</span><span class="p">:</span>
<span class="n">errors</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">field</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;incomplete&quot;</span><span class="p">])</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">clean_data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">field</span><span class="o">.</span><span class="n">clean</span><span class="p">(</span><span class="n">field_value</span><span class="p">))</span>
<span class="k">except</span> <span class="n">ValidationError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="c1"># Collect all validation errors in a single list, which we&#39;ll</span>
<span class="c1"># raise at the end of clean(), rather than raising a single</span>
<span class="c1"># exception for the first error we encounter. Skip duplicates.</span>
<span class="n">errors</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">m</span> <span class="k">for</span> <span class="n">m</span> <span class="ow">in</span> <span class="n">e</span><span class="o">.</span><span class="n">error_list</span> <span class="k">if</span> <span class="n">m</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">errors</span><span class="p">)</span>
<span class="k">if</span> <span class="n">errors</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
<span class="n">out</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">compress</span><span class="p">(</span><span class="n">clean_data</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">run_validators</span><span class="p">(</span><span class="n">out</span><span class="p">)</span>
<span class="k">return</span> <span class="n">out</span>
<span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_list</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return a single value for the given list of values. The values can be</span>
<span class="sd"> assumed to be valid.</span>
<span class="sd"> For example, if this MultiValueField was instantiated with</span>
<span class="sd"> fields=(DateField(), TimeField()), this might return a datetime</span>
<span class="sd"> object created by combining the date and time in data_list.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s2">&quot;Subclasses must implement this method.&quot;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">initial</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">initial</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;&quot;</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">initial</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
<span class="n">initial</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">decompress</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span>
<span class="k">for</span> <span class="n">field</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fields</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">initial</span> <span class="o">=</span> <span class="n">field</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span>
<span class="k">except</span> <span class="n">ValidationError</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">field</span><span class="o">.</span><span class="n">has_changed</span><span class="p">(</span><span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">class</span><span class="w"> </span><span class="nc">FilePathField</span><span class="p">(</span><span class="n">ChoiceField</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">match</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">recursive</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">allow_files</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">allow_folders</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
<span class="p">):</span>
<span class="bp">self</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">match</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">recursive</span> <span class="o">=</span> <span class="n">path</span><span class="p">,</span> <span class="n">match</span><span class="p">,</span> <span class="n">recursive</span>
<span class="bp">self</span><span class="o">.</span><span class="n">allow_files</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">allow_folders</span> <span class="o">=</span> <span class="n">allow_files</span><span class="p">,</span> <span class="n">allow_folders</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">choices</span><span class="o">=</span><span class="p">(),</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">required</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">choices</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">choices</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;---------&quot;</span><span class="p">)]</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">match</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">match_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">match</span><span class="p">)</span>
<span class="k">if</span> <span class="n">recursive</span><span class="p">:</span>
<span class="k">for</span> <span class="n">root</span><span class="p">,</span> <span class="n">dirs</span><span class="p">,</span> <span class="n">files</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">walk</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">)):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">allow_files</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">files</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">match</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">match_re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">f</span> <span class="o">=</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="n">root</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">choices</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">f</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">allow_folders</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">dirs</span><span class="p">):</span>
<span class="k">if</span> <span class="n">f</span> <span class="o">==</span> <span class="s2">&quot;__pycache__&quot;</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">match</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">match_re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">f</span> <span class="o">=</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="n">root</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">choices</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">f</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">choices</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">with</span> <span class="n">os</span><span class="o">.</span><span class="n">scandir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">)</span> <span class="k">as</span> <span class="n">entries</span><span class="p">:</span>
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">entries</span><span class="p">:</span>
<span class="k">if</span> <span class="n">f</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s2">&quot;__pycache__&quot;</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="p">(</span>
<span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">allow_files</span> <span class="ow">and</span> <span class="n">f</span><span class="o">.</span><span class="n">is_file</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">allow_folders</span> <span class="ow">and</span> <span class="n">f</span><span class="o">.</span><span class="n">is_dir</span><span class="p">())</span>
<span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">match</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">match_re</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">)):</span>
<span class="n">choices</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">f</span><span class="o">.</span><span class="n">path</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
<span class="n">choices</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="n">operator</span><span class="o">.</span><span class="n">itemgetter</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">choices</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">choices</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">widget</span><span class="o">.</span><span class="n">choices</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">choices</span>
<span class="k">class</span><span class="w"> </span><span class="nc">SplitDateTimeField</span><span class="p">(</span><span class="n">MultiValueField</span><span class="p">):</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">SplitDateTimeWidget</span>
<span class="n">hidden_widget</span> <span class="o">=</span> <span class="n">SplitHiddenDateTimeWidget</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid_date&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid date.&quot;</span><span class="p">),</span>
<span class="s2">&quot;invalid_time&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid time.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">input_date_formats</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">input_time_formats</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="n">errors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_error_messages</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">if</span> <span class="s2">&quot;error_messages&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="n">errors</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="s2">&quot;error_messages&quot;</span><span class="p">])</span>
<span class="n">localize</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="s2">&quot;localize&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="n">fields</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">DateField</span><span class="p">(</span>
<span class="n">input_formats</span><span class="o">=</span><span class="n">input_date_formats</span><span class="p">,</span>
<span class="n">error_messages</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">errors</span><span class="p">[</span><span class="s2">&quot;invalid_date&quot;</span><span class="p">]},</span>
<span class="n">localize</span><span class="o">=</span><span class="n">localize</span><span class="p">,</span>
<span class="p">),</span>
<span class="n">TimeField</span><span class="p">(</span>
<span class="n">input_formats</span><span class="o">=</span><span class="n">input_time_formats</span><span class="p">,</span>
<span class="n">error_messages</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">errors</span><span class="p">[</span><span class="s2">&quot;invalid_time&quot;</span><span class="p">]},</span>
<span class="n">localize</span><span class="o">=</span><span class="n">localize</span><span class="p">,</span>
<span class="p">),</span>
<span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">fields</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="w"> </span><span class="nf">compress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data_list</span><span class="p">):</span>
<span class="k">if</span> <span class="n">data_list</span><span class="p">:</span>
<span class="c1"># Raise a validation error if time or date is empty</span>
<span class="c1"># (possible if SplitDateTimeField has required=False).</span>
<span class="k">if</span> <span class="n">data_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_date&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_date&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">data_list</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid_time&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid_time&quot;</span>
<span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">combine</span><span class="p">(</span><span class="o">*</span><span class="n">data_list</span><span class="p">)</span>
<span class="k">return</span> <span class="n">from_current_timezone</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">class</span><span class="w"> </span><span class="nc">GenericIPAddressField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">protocol</span><span class="o">=</span><span class="s2">&quot;both&quot;</span><span class="p">,</span> <span class="n">unpack_ipv4</span><span class="o">=</span><span class="kc">False</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">unpack_ipv4</span> <span class="o">=</span> <span class="n">unpack_ipv4</span>
<span class="bp">self</span><span class="o">.</span><span class="n">default_validators</span> <span class="o">=</span> <span class="n">validators</span><span class="o">.</span><span class="n">ip_address_validators</span><span class="p">(</span>
<span class="n">protocol</span><span class="p">,</span> <span class="n">unpack_ipv4</span>
<span class="p">)</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;max_length&quot;</span><span class="p">,</span> <span class="n">MAX_IPV6_ADDRESS_LENGTH</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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="w"> </span><span class="nf">to_python</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="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">and</span> <span class="s2">&quot;:&quot;</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
<span class="k">return</span> <span class="n">clean_ipv6_address</span><span class="p">(</span>
<span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">unpack_ipv4</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">max_length</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">class</span><span class="w"> </span><span class="nc">SlugField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_slug</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">allow_unicode</span><span class="o">=</span><span class="kc">False</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">allow_unicode</span> <span class="o">=</span> <span class="n">allow_unicode</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">allow_unicode</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">default_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">validators</span><span class="o">.</span><span class="n">validate_unicode_slug</span><span class="p">]</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">UUIDField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid UUID.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">prepare_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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">uuid</span><span class="o">.</span><span class="n">UUID</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_python</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="n">value</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">uuid</span><span class="o">.</span><span class="n">UUID</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">uuid</span><span class="o">.</span><span class="n">UUID</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span> <span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">class</span><span class="w"> </span><span class="nc">InvalidJSONInput</span><span class="p">(</span><span class="nb">str</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span><span class="w"> </span><span class="nc">JSONString</span><span class="p">(</span><span class="nb">str</span><span class="p">):</span>
<span class="k">pass</span>
<span class="k">class</span><span class="w"> </span><span class="nc">JSONField</span><span class="p">(</span><span class="n">CharField</span><span class="p">):</span>
<span class="n">default_error_messages</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;invalid&quot;</span><span class="p">:</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Enter a valid JSON.&quot;</span><span class="p">),</span>
<span class="p">}</span>
<span class="n">widget</span> <span class="o">=</span> <span class="n">Textarea</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">encoder</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">decoder</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">encoder</span> <span class="o">=</span> <span class="n">encoder</span>
<span class="bp">self</span><span class="o">.</span><span class="n">decoder</span> <span class="o">=</span> <span class="n">decoder</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</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="w"> </span><span class="nf">to_python</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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">empty_values</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="nb">dict</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="n">JSONString</span><span class="p">)):</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">converted</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">decoder</span><span class="p">)</span>
<span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">error_messages</span><span class="p">[</span><span class="s2">&quot;invalid&quot;</span><span class="p">],</span>
<span class="n">code</span><span class="o">=</span><span class="s2">&quot;invalid&quot;</span><span class="p">,</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;value&quot;</span><span class="p">:</span> <span class="n">value</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">converted</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="k">return</span> <span class="n">JSONString</span><span class="p">(</span><span class="n">converted</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">converted</span>
<span class="k">def</span><span class="w"> </span><span class="nf">bound_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">initial</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">:</span>
<span class="k">return</span> <span class="n">initial</span>
<span class="k">if</span> <span class="n">data</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">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">decoder</span><span class="p">)</span>
<span class="k">except</span> <span class="n">json</span><span class="o">.</span><span class="n">JSONDecodeError</span><span class="p">:</span>
<span class="k">return</span> <span class="n">InvalidJSONInput</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">prepare_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="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">InvalidJSONInput</span><span class="p">):</span>
<span class="k">return</span> <span class="n">value</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">encoder</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">has_changed</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">has_changed</span><span class="p">(</span><span class="n">initial</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># For purposes of seeing whether something has changed, True isn&#39;t the</span>
<span class="c1"># same as 1 and the order of keys doesn&#39;t matter.</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">initial</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">encoder</span><span class="p">)</span> <span class="o">!=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">data</span><span class="p">),</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">encoder</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">django.forms.fields</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>