nautobot 2.2.2__py3-none-any.whl → 2.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. nautobot/apps/jobs.py +2 -0
  2. nautobot/core/api/utils.py +12 -9
  3. nautobot/core/apps/__init__.py +2 -2
  4. nautobot/core/celery/__init__.py +79 -68
  5. nautobot/core/celery/backends.py +9 -1
  6. nautobot/core/celery/control.py +4 -7
  7. nautobot/core/celery/schedulers.py +4 -2
  8. nautobot/core/celery/task.py +78 -5
  9. nautobot/core/graphql/schema.py +2 -1
  10. nautobot/core/jobs/__init__.py +2 -1
  11. nautobot/core/templates/generic/object_list.html +3 -3
  12. nautobot/core/templatetags/helpers.py +66 -9
  13. nautobot/core/testing/__init__.py +6 -1
  14. nautobot/core/testing/api.py +12 -13
  15. nautobot/core/testing/mixins.py +2 -2
  16. nautobot/core/testing/views.py +50 -51
  17. nautobot/core/tests/test_api.py +23 -2
  18. nautobot/core/tests/test_templatetags_helpers.py +32 -0
  19. nautobot/core/tests/test_views.py +19 -0
  20. nautobot/core/tests/test_views_utils.py +22 -1
  21. nautobot/core/utils/module_loading.py +89 -0
  22. nautobot/core/views/utils.py +3 -2
  23. nautobot/dcim/choices.py +14 -0
  24. nautobot/dcim/forms.py +51 -1
  25. nautobot/dcim/models/device_components.py +9 -5
  26. nautobot/dcim/templates/dcim/location.html +32 -13
  27. nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +102 -0
  28. nautobot/dcim/tests/test_views.py +137 -0
  29. nautobot/dcim/urls.py +5 -0
  30. nautobot/dcim/views.py +149 -1
  31. nautobot/extras/api/views.py +21 -10
  32. nautobot/extras/constants.py +3 -3
  33. nautobot/extras/datasources/git.py +47 -58
  34. nautobot/extras/forms/forms.py +3 -1
  35. nautobot/extras/jobs.py +79 -146
  36. nautobot/extras/models/datasources.py +0 -2
  37. nautobot/extras/models/jobs.py +36 -18
  38. nautobot/extras/plugins/__init__.py +1 -20
  39. nautobot/extras/signals.py +6 -9
  40. nautobot/extras/test_jobs/__init__.py +8 -0
  41. nautobot/extras/test_jobs/dry_run.py +3 -2
  42. nautobot/extras/test_jobs/fail.py +43 -0
  43. nautobot/extras/test_jobs/ipaddress_vars.py +40 -1
  44. nautobot/extras/test_jobs/jobs_module/__init__.py +5 -0
  45. nautobot/extras/test_jobs/jobs_module/jobs_submodule/__init__.py +1 -0
  46. nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +6 -0
  47. nautobot/extras/test_jobs/pass.py +40 -0
  48. nautobot/extras/test_jobs/relative_import.py +11 -0
  49. nautobot/extras/tests/test_api.py +3 -0
  50. nautobot/extras/tests/test_datasources.py +125 -118
  51. nautobot/extras/tests/test_job_variables.py +57 -15
  52. nautobot/extras/tests/test_jobs.py +135 -1
  53. nautobot/extras/tests/test_models.py +26 -19
  54. nautobot/extras/tests/test_plugins.py +1 -3
  55. nautobot/extras/tests/test_views.py +2 -4
  56. nautobot/extras/views.py +47 -95
  57. nautobot/ipam/api/views.py +8 -1
  58. nautobot/ipam/graphql/types.py +11 -0
  59. nautobot/ipam/mixins.py +32 -0
  60. nautobot/ipam/models.py +2 -1
  61. nautobot/ipam/querysets.py +6 -1
  62. nautobot/ipam/tests/test_models.py +82 -0
  63. nautobot/project-static/docs/assets/extra.css +4 -0
  64. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1 -1
  65. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +180 -211
  66. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +1 -1
  67. nautobot/project-static/docs/development/core/application-registry.html +126 -84
  68. nautobot/project-static/docs/development/core/model-checklist.html +49 -1
  69. nautobot/project-static/docs/development/core/model-features.html +1 -1
  70. nautobot/project-static/docs/development/jobs/index.html +334 -58
  71. nautobot/project-static/docs/development/jobs/migration/from-v1.html +1 -1
  72. nautobot/project-static/docs/objects.inv +0 -0
  73. nautobot/project-static/docs/release-notes/version-2.2.html +237 -55
  74. nautobot/project-static/docs/search/search_index.json +1 -1
  75. nautobot/project-static/docs/sitemap.xml +254 -254
  76. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  77. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +7 -4
  78. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +111 -0
  79. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +15 -28
  80. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +4 -4
  81. nautobot/project-static/js/forms.js +18 -11
  82. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/METADATA +3 -3
  83. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/RECORD +87 -81
  84. nautobot/extras/test_jobs/job_variables.py +0 -93
  85. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/LICENSE.txt +0 -0
  86. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/NOTICE +0 -0
  87. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/WHEEL +0 -0
  88. {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/entry_points.txt +0 -0
@@ -6793,6 +6793,15 @@
6793
6793
  </span>
6794
6794
  </a>
6795
6795
 
6796
+ </li>
6797
+
6798
+ <li class="md-nav__item">
6799
+ <a href="#jobs" class="md-nav__link">
6800
+ <span class="md-ellipsis">
6801
+ jobs
6802
+ </span>
6803
+ </a>
6804
+
6796
6805
  </li>
6797
6806
 
6798
6807
  <li class="md-nav__item">
@@ -7849,6 +7858,15 @@
7849
7858
  </span>
7850
7859
  </a>
7851
7860
 
7861
+ </li>
7862
+
7863
+ <li class="md-nav__item">
7864
+ <a href="#jobs" class="md-nav__link">
7865
+ <span class="md-ellipsis">
7866
+ jobs
7867
+ </span>
7868
+ </a>
7869
+
7852
7870
  </li>
7853
7871
 
7854
7872
  <li class="md-nav__item">
@@ -7993,19 +8011,43 @@
7993
8011
  <a id="__codelineno-2-29" name="__codelineno-2-29" href="#__codelineno-2-29"></a> <span class="p">}</span>
7994
8012
  <a id="__codelineno-2-30" name="__codelineno-2-30" href="#__codelineno-2-30"></a><span class="p">}</span>
7995
8013
  </code></pre></div>
8014
+ <h3 id="jobs"><code>jobs</code><a class="headerlink" href="#jobs" title="Permanent link">&para;</a></h3>
8015
+ <div class="admonition version-added">
8016
+ <p class="admonition-title">Added in version 2.2.3</p>
8017
+ </div>
8018
+ <p>A dictionary of registered <a href="../jobs/index.html">Job classes</a>, indexed by their <a href="../../user-guide/platform-functionality/jobs/index.html#jobs-and-class_path">class path</a>. For example:</p>
8019
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">{</span>
8020
+ <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a> <span class="s2">&quot;nautobot.core.jobs.ExportObjectList&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">nautobot</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExportObjectList</span><span class="s2">&quot;&gt;,</span>
8021
+ <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a> <span class="s2">&quot;nautobot.core.jobs.GitRepositorySync&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">nautobot</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">GitRepositorySync</span><span class="s2">&quot;&gt;,</span>
8022
+ <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> <span class="s2">&quot;nautobot.core.jobs.GitRepositoryDryRun&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">nautobot</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">GitRepositoryDryRun</span><span class="s2">&quot;&gt;,</span>
8023
+ <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a> <span class="s2">&quot;nautobot.core.jobs.ImportObjects&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">nautobot</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ImportObjects</span><span class="s2">&quot;&gt;,</span>
8024
+ <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a> <span class="s2">&quot;example_app.jobs.ExampleDryRunJob&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleDryRunJob</span><span class="s2">&quot;&gt;,</span>
8025
+ <a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a> <span class="s2">&quot;example_app.jobs.ExampleJob&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleJob</span><span class="s2">&quot;&gt;,</span>
8026
+ <a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a> <span class="s2">&quot;example_app.jobs.ExampleHiddenJob&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleHiddenJob</span><span class="s2">&quot;&gt;,</span>
8027
+ <a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a> <span class="s2">&quot;example_app.jobs.ExampleLoggingJob&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleLoggingJob</span><span class="s2">&quot;&gt;,</span>
8028
+ <a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a> <span class="s2">&quot;example_app.jobs.ExampleFileInputOutputJob&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleFileInputOutputJob</span><span class="s2">&quot;&gt;,</span>
8029
+ <a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a> <span class="s2">&quot;example_app.jobs.ExampleJobHookReceiver&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleJobHookReceiver</span><span class="s2">&quot;&gt;,</span>
8030
+ <a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a> <span class="s2">&quot;example_app.jobs.ExampleSimpleJobButtonReceiver&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleSimpleJobButtonReceiver</span><span class="s2">&quot;&gt;,</span>
8031
+ <a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a> <span class="s2">&quot;example_app.jobs.ExampleComplexJobButtonReceiver&quot;</span><span class="p">:</span> <span class="o">&lt;</span><span class="k">class</span> <span class="err">&quot;</span><span class="nc">example_app</span><span class="o">.</span><span class="n">jobs</span><span class="o">.</span><span class="n">ExampleComplexJobButtonReceiver</span><span class="s2">&quot;&gt;</span>
8032
+ <a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a><span class="p">}</span>
8033
+ </code></pre></div>
8034
+ <div class="admonition caution">
8035
+ <p class="admonition-title">Caution</p>
8036
+ <p>This registry entry should be treated as a cache and as an implementation detail; in general you should prefer the use of the <code>nautobot.apps.get_jobs()</code> and/or <code>nautobot.apps.get_job()</code> APIs in order to retrieve specific Job classes.</p>
8037
+ </div>
7996
8038
  <h3 id="model_features"><code>model_features</code><a class="headerlink" href="#model_features" title="Permanent link">&para;</a></h3>
7997
8039
  <p>A dictionary of particular features (e.g. custom fields) mapped to the Nautobot models which support them, arranged by app. For example:</p>
7998
- <div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">{</span>
7999
- <a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a> <span class="s1">&#39;custom_fields&#39;</span><span class="p">:</span> <span class="p">{</span>
8000
- <a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a> <span class="s1">&#39;circuits&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;provider&#39;</span><span class="p">,</span> <span class="s1">&#39;circuit&#39;</span><span class="p">],</span>
8001
- <a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> <span class="s1">&#39;dcim&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;location&#39;</span><span class="p">,</span> <span class="s1">&#39;rack&#39;</span><span class="p">,</span> <span class="s1">&#39;devicetype&#39;</span><span class="p">,</span> <span class="o">...</span><span class="p">],</span>
8002
- <a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a> <span class="o">...</span>
8003
- <a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a> <span class="p">},</span>
8004
- <a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a> <span class="s1">&#39;webhooks&#39;</span><span class="p">:</span> <span class="p">{</span>
8005
- <a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a> <span class="o">...</span>
8006
- <a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a> <span class="p">},</span>
8007
- <a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a> <span class="o">...</span>
8008
- <a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a><span class="p">}</span>
8040
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="p">{</span>
8041
+ <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a> <span class="s1">&#39;custom_fields&#39;</span><span class="p">:</span> <span class="p">{</span>
8042
+ <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a> <span class="s1">&#39;circuits&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;provider&#39;</span><span class="p">,</span> <span class="s1">&#39;circuit&#39;</span><span class="p">],</span>
8043
+ <a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a> <span class="s1">&#39;dcim&#39;</span><span class="p">:</span> <span class="p">[</span><span class="s1">&#39;location&#39;</span><span class="p">,</span> <span class="s1">&#39;rack&#39;</span><span class="p">,</span> <span class="s1">&#39;devicetype&#39;</span><span class="p">,</span> <span class="o">...</span><span class="p">],</span>
8044
+ <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> <span class="o">...</span>
8045
+ <a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a> <span class="p">},</span>
8046
+ <a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a> <span class="s1">&#39;webhooks&#39;</span><span class="p">:</span> <span class="p">{</span>
8047
+ <a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a> <span class="o">...</span>
8048
+ <a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a> <span class="p">},</span>
8049
+ <a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a> <span class="o">...</span>
8050
+ <a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="p">}</span>
8009
8051
  </code></pre></div>
8010
8052
  <p>For more information visit <a href="model-features.html">model-features</a>.</p>
8011
8053
  <h3 id="nav_menu"><code>nav_menu</code><a class="headerlink" href="#nav_menu" title="Permanent link">&para;</a></h3>
@@ -8014,77 +8056,77 @@
8014
8056
  </div>
8015
8057
  <p>Navigation menu items provided by Nautobot applications. Each app may register its navbar configuration inside of the <code>nav_menu</code> dictionary using <code>navigation.py</code>. Tabs are stored in the top level moving down to groups, items and buttons. Tabs, groups and items can be modified by using the key values inside other core applications and Apps. The <code>nav_menu</code> dict should never be modified directly.</p>
8016
8058
  <p>Example:</p>
8017
- <div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="p">{</span>
8018
- <a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a> <span class="s2">&quot;tabs&quot;</span><span class="p">:</span> <span class="p">{</span>
8019
- <a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a> <span class="s2">&quot;tab_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8020
- <a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8021
- <a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8022
- <a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a> <span class="s2">&quot;groups&quot;</span><span class="p">:</span> <span class="p">{</span>
8023
- <a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a> <span class="s2">&quot;group_1&quot;</span><span class="p">:{</span>
8024
- <a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8025
- <a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8026
- <a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a> <span class="s2">&quot;items&quot;</span><span class="p">:</span> <span class="p">{</span>
8027
- <a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a> <span class="s2">&quot;item_link_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8028
- <a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a> <span class="s2">&quot;link_text&quot;</span><span class="p">:</span> <span class="s2">&quot;Item 1&quot;</span><span class="p">,</span>
8029
- <a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8030
- <a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8031
- <a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a> <span class="s2">&quot;buttons&quot;</span><span class="p">:</span> <span class="p">{</span>
8032
- <a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a> <span class="s2">&quot;button_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8033
- <a id="__codelineno-4-17" name="__codelineno-4-17" href="#__codelineno-4-17"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8034
- <a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8035
- <a id="__codelineno-4-19" name="__codelineno-4-19" href="#__codelineno-4-19"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_1&quot;</span><span class="p">,</span>
8036
- <a id="__codelineno-4-20" name="__codelineno-4-20" href="#__codelineno-4-20"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8037
- <a id="__codelineno-4-21" name="__codelineno-4-21" href="#__codelineno-4-21"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8038
- <a id="__codelineno-4-22" name="__codelineno-4-22" href="#__codelineno-4-22"></a> <span class="p">},</span>
8039
- <a id="__codelineno-4-23" name="__codelineno-4-23" href="#__codelineno-4-23"></a> <span class="s2">&quot;button_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8040
- <a id="__codelineno-4-24" name="__codelineno-4-24" href="#__codelineno-4-24"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8041
- <a id="__codelineno-4-25" name="__codelineno-4-25" href="#__codelineno-4-25"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8042
- <a id="__codelineno-4-26" name="__codelineno-4-26" href="#__codelineno-4-26"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_2&quot;</span><span class="p">,</span>
8043
- <a id="__codelineno-4-27" name="__codelineno-4-27" href="#__codelineno-4-27"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8044
- <a id="__codelineno-4-28" name="__codelineno-4-28" href="#__codelineno-4-28"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8045
- <a id="__codelineno-4-29" name="__codelineno-4-29" href="#__codelineno-4-29"></a> <span class="p">}</span>
8046
- <a id="__codelineno-4-30" name="__codelineno-4-30" href="#__codelineno-4-30"></a> <span class="p">}</span>
8047
- <a id="__codelineno-4-31" name="__codelineno-4-31" href="#__codelineno-4-31"></a> <span class="p">},</span>
8048
- <a id="__codelineno-4-32" name="__codelineno-4-32" href="#__codelineno-4-32"></a> <span class="s2">&quot;item_link_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8049
- <a id="__codelineno-4-33" name="__codelineno-4-33" href="#__codelineno-4-33"></a> <span class="s2">&quot;link_text&quot;</span><span class="p">:</span> <span class="s2">&quot;Item 2&quot;</span><span class="p">,</span>
8050
- <a id="__codelineno-4-34" name="__codelineno-4-34" href="#__codelineno-4-34"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8051
- <a id="__codelineno-4-35" name="__codelineno-4-35" href="#__codelineno-4-35"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8052
- <a id="__codelineno-4-36" name="__codelineno-4-36" href="#__codelineno-4-36"></a> <span class="s2">&quot;buttons&quot;</span><span class="p">:</span> <span class="p">{</span>
8053
- <a id="__codelineno-4-37" name="__codelineno-4-37" href="#__codelineno-4-37"></a> <span class="s2">&quot;button_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8054
- <a id="__codelineno-4-38" name="__codelineno-4-38" href="#__codelineno-4-38"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8055
- <a id="__codelineno-4-39" name="__codelineno-4-39" href="#__codelineno-4-39"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8056
- <a id="__codelineno-4-40" name="__codelineno-4-40" href="#__codelineno-4-40"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_1&quot;</span><span class="p">,</span>
8057
- <a id="__codelineno-4-41" name="__codelineno-4-41" href="#__codelineno-4-41"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8058
- <a id="__codelineno-4-42" name="__codelineno-4-42" href="#__codelineno-4-42"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8059
- <a id="__codelineno-4-43" name="__codelineno-4-43" href="#__codelineno-4-43"></a> <span class="p">},</span>
8060
- <a id="__codelineno-4-44" name="__codelineno-4-44" href="#__codelineno-4-44"></a> <span class="s2">&quot;button_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8061
- <a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8062
- <a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8063
- <a id="__codelineno-4-47" name="__codelineno-4-47" href="#__codelineno-4-47"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_2&quot;</span><span class="p">,</span>
8064
- <a id="__codelineno-4-48" name="__codelineno-4-48" href="#__codelineno-4-48"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8065
- <a id="__codelineno-4-49" name="__codelineno-4-49" href="#__codelineno-4-49"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8066
- <a id="__codelineno-4-50" name="__codelineno-4-50" href="#__codelineno-4-50"></a> <span class="p">}</span>
8067
- <a id="__codelineno-4-51" name="__codelineno-4-51" href="#__codelineno-4-51"></a> <span class="p">}</span>
8068
- <a id="__codelineno-4-52" name="__codelineno-4-52" href="#__codelineno-4-52"></a> <span class="p">},</span>
8069
- <a id="__codelineno-4-53" name="__codelineno-4-53" href="#__codelineno-4-53"></a> <span class="p">}</span>
8070
- <a id="__codelineno-4-54" name="__codelineno-4-54" href="#__codelineno-4-54"></a> <span class="p">}</span>
8071
- <a id="__codelineno-4-55" name="__codelineno-4-55" href="#__codelineno-4-55"></a> <span class="p">}</span>
8072
- <a id="__codelineno-4-56" name="__codelineno-4-56" href="#__codelineno-4-56"></a> <span class="p">}</span>
8073
- <a id="__codelineno-4-57" name="__codelineno-4-57" href="#__codelineno-4-57"></a> <span class="p">}</span>
8074
- <a id="__codelineno-4-58" name="__codelineno-4-58" href="#__codelineno-4-58"></a><span class="p">}</span>
8059
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="p">{</span>
8060
+ <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a> <span class="s2">&quot;tabs&quot;</span><span class="p">:</span> <span class="p">{</span>
8061
+ <a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="s2">&quot;tab_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8062
+ <a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8063
+ <a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8064
+ <a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="s2">&quot;groups&quot;</span><span class="p">:</span> <span class="p">{</span>
8065
+ <a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> <span class="s2">&quot;group_1&quot;</span><span class="p">:{</span>
8066
+ <a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8067
+ <a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8068
+ <a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="s2">&quot;items&quot;</span><span class="p">:</span> <span class="p">{</span>
8069
+ <a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="s2">&quot;item_link_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8070
+ <a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="s2">&quot;link_text&quot;</span><span class="p">:</span> <span class="s2">&quot;Item 1&quot;</span><span class="p">,</span>
8071
+ <a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8072
+ <a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8073
+ <a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="s2">&quot;buttons&quot;</span><span class="p">:</span> <span class="p">{</span>
8074
+ <a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> <span class="s2">&quot;button_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8075
+ <a id="__codelineno-5-17" name="__codelineno-5-17" href="#__codelineno-5-17"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8076
+ <a id="__codelineno-5-18" name="__codelineno-5-18" href="#__codelineno-5-18"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8077
+ <a id="__codelineno-5-19" name="__codelineno-5-19" href="#__codelineno-5-19"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_1&quot;</span><span class="p">,</span>
8078
+ <a id="__codelineno-5-20" name="__codelineno-5-20" href="#__codelineno-5-20"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8079
+ <a id="__codelineno-5-21" name="__codelineno-5-21" href="#__codelineno-5-21"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8080
+ <a id="__codelineno-5-22" name="__codelineno-5-22" href="#__codelineno-5-22"></a> <span class="p">},</span>
8081
+ <a id="__codelineno-5-23" name="__codelineno-5-23" href="#__codelineno-5-23"></a> <span class="s2">&quot;button_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8082
+ <a id="__codelineno-5-24" name="__codelineno-5-24" href="#__codelineno-5-24"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8083
+ <a id="__codelineno-5-25" name="__codelineno-5-25" href="#__codelineno-5-25"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8084
+ <a id="__codelineno-5-26" name="__codelineno-5-26" href="#__codelineno-5-26"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_2&quot;</span><span class="p">,</span>
8085
+ <a id="__codelineno-5-27" name="__codelineno-5-27" href="#__codelineno-5-27"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8086
+ <a id="__codelineno-5-28" name="__codelineno-5-28" href="#__codelineno-5-28"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8087
+ <a id="__codelineno-5-29" name="__codelineno-5-29" href="#__codelineno-5-29"></a> <span class="p">}</span>
8088
+ <a id="__codelineno-5-30" name="__codelineno-5-30" href="#__codelineno-5-30"></a> <span class="p">}</span>
8089
+ <a id="__codelineno-5-31" name="__codelineno-5-31" href="#__codelineno-5-31"></a> <span class="p">},</span>
8090
+ <a id="__codelineno-5-32" name="__codelineno-5-32" href="#__codelineno-5-32"></a> <span class="s2">&quot;item_link_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8091
+ <a id="__codelineno-5-33" name="__codelineno-5-33" href="#__codelineno-5-33"></a> <span class="s2">&quot;link_text&quot;</span><span class="p">:</span> <span class="s2">&quot;Item 2&quot;</span><span class="p">,</span>
8092
+ <a id="__codelineno-5-34" name="__codelineno-5-34" href="#__codelineno-5-34"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8093
+ <a id="__codelineno-5-35" name="__codelineno-5-35" href="#__codelineno-5-35"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8094
+ <a id="__codelineno-5-36" name="__codelineno-5-36" href="#__codelineno-5-36"></a> <span class="s2">&quot;buttons&quot;</span><span class="p">:</span> <span class="p">{</span>
8095
+ <a id="__codelineno-5-37" name="__codelineno-5-37" href="#__codelineno-5-37"></a> <span class="s2">&quot;button_1&quot;</span><span class="p">:</span> <span class="p">{</span>
8096
+ <a id="__codelineno-5-38" name="__codelineno-5-38" href="#__codelineno-5-38"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8097
+ <a id="__codelineno-5-39" name="__codelineno-5-39" href="#__codelineno-5-39"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8098
+ <a id="__codelineno-5-40" name="__codelineno-5-40" href="#__codelineno-5-40"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_1&quot;</span><span class="p">,</span>
8099
+ <a id="__codelineno-5-41" name="__codelineno-5-41" href="#__codelineno-5-41"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
8100
+ <a id="__codelineno-5-42" name="__codelineno-5-42" href="#__codelineno-5-42"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8101
+ <a id="__codelineno-5-43" name="__codelineno-5-43" href="#__codelineno-5-43"></a> <span class="p">},</span>
8102
+ <a id="__codelineno-5-44" name="__codelineno-5-44" href="#__codelineno-5-44"></a> <span class="s2">&quot;button_2&quot;</span><span class="p">:</span> <span class="p">{</span>
8103
+ <a id="__codelineno-5-45" name="__codelineno-5-45" href="#__codelineno-5-45"></a> <span class="s2">&quot;button_class&quot;</span><span class="p">:</span> <span class="s2">&quot;success&quot;</span><span class="p">,</span>
8104
+ <a id="__codelineno-5-46" name="__codelineno-5-46" href="#__codelineno-5-46"></a> <span class="s2">&quot;icon_class&quot;</span><span class="p">:</span> <span class="s2">&quot;mdi-plus-thick&quot;</span><span class="p">,</span>
8105
+ <a id="__codelineno-5-47" name="__codelineno-5-47" href="#__codelineno-5-47"></a> <span class="s2">&quot;link&quot;</span><span class="p">:</span> <span class="s2">&quot;button_link_2&quot;</span><span class="p">,</span>
8106
+ <a id="__codelineno-5-48" name="__codelineno-5-48" href="#__codelineno-5-48"></a> <span class="s2">&quot;weight&quot;</span><span class="p">:</span> <span class="mi">200</span><span class="p">,</span>
8107
+ <a id="__codelineno-5-49" name="__codelineno-5-49" href="#__codelineno-5-49"></a> <span class="s2">&quot;permissions&quot;</span><span class="p">:</span> <span class="p">[],</span>
8108
+ <a id="__codelineno-5-50" name="__codelineno-5-50" href="#__codelineno-5-50"></a> <span class="p">}</span>
8109
+ <a id="__codelineno-5-51" name="__codelineno-5-51" href="#__codelineno-5-51"></a> <span class="p">}</span>
8110
+ <a id="__codelineno-5-52" name="__codelineno-5-52" href="#__codelineno-5-52"></a> <span class="p">},</span>
8111
+ <a id="__codelineno-5-53" name="__codelineno-5-53" href="#__codelineno-5-53"></a> <span class="p">}</span>
8112
+ <a id="__codelineno-5-54" name="__codelineno-5-54" href="#__codelineno-5-54"></a> <span class="p">}</span>
8113
+ <a id="__codelineno-5-55" name="__codelineno-5-55" href="#__codelineno-5-55"></a> <span class="p">}</span>
8114
+ <a id="__codelineno-5-56" name="__codelineno-5-56" href="#__codelineno-5-56"></a> <span class="p">}</span>
8115
+ <a id="__codelineno-5-57" name="__codelineno-5-57" href="#__codelineno-5-57"></a> <span class="p">}</span>
8116
+ <a id="__codelineno-5-58" name="__codelineno-5-58" href="#__codelineno-5-58"></a><span class="p">}</span>
8075
8117
  </code></pre></div>
8076
8118
  <h3 id="plugin_custom_validators"><code>plugin_custom_validators</code><a class="headerlink" href="#plugin_custom_validators" title="Permanent link">&para;</a></h3>
8077
8119
  <p>App <a href="../apps/api/platform-features/custom-validators.html">custom validator classes</a> that provide additional data model validation logic. Implemented as a dictionary mapping data model names to a list of <code>CustomValidator</code> subclasses, for example:</p>
8078
- <div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="p">{</span>
8079
- <a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a> <span class="s1">&#39;circuits.circuit&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">CircuitMustHaveDescriptionValidator</span><span class="p">],</span>
8080
- <a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="s1">&#39;dcim.location&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">LocationMustHaveTenantValidator</span><span class="p">,</span> <span class="n">LocationNameMustIncludeCountryCodeValidator</span><span class="p">],</span>
8081
- <a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="p">}</span>
8120
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">{</span>
8121
+ <a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> <span class="s1">&#39;circuits.circuit&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">CircuitMustHaveDescriptionValidator</span><span class="p">],</span>
8122
+ <a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> <span class="s1">&#39;dcim.location&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">LocationMustHaveTenantValidator</span><span class="p">,</span> <span class="n">LocationNameMustIncludeCountryCodeValidator</span><span class="p">],</span>
8123
+ <a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="p">}</span>
8082
8124
  </code></pre></div>
8083
8125
  <h3 id="plugin_graphql_types"><code>plugin_graphql_types</code><a class="headerlink" href="#plugin_graphql_types" title="Permanent link">&para;</a></h3>
8084
8126
  <p>List of GraphQL Type objects that will be added to the GraphQL schema. GraphQL objects that are defined in an App will be automatically registered into this registry. An example:</p>
8085
- <div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">[</span>
8086
- <a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> <span class="o">&lt;</span><span class="n">DjangoObjectType</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">DjangoObjectType</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">OptimizedDjangoObjectType</span><span class="o">&gt;</span>
8087
- <a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="p">]</span>
8127
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">[</span>
8128
+ <a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a> <span class="o">&lt;</span><span class="n">DjangoObjectType</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">DjangoObjectType</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">OptimizedDjangoObjectType</span><span class="o">&gt;</span>
8129
+ <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="p">]</span>
8088
8130
  </code></pre></div>
8089
8131
  <div class="admonition version-removed">
8090
8132
  <p class="admonition-title">Removed in version 2.0.0</p>
@@ -8092,14 +8134,14 @@
8092
8134
  </div>
8093
8135
  <h3 id="plugin_template_extensions"><code>plugin_template_extensions</code><a class="headerlink" href="#plugin_template_extensions" title="Permanent link">&para;</a></h3>
8094
8136
  <p>App content that gets embedded into core Nautobot templates. The store comprises Nautobot models registered as dictionary keys, each pointing to a list of applicable template extension classes that exist. An example:</p>
8095
- <div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">{</span>
8096
- <a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a> <span class="s1">&#39;dcim.location&#39;</span><span class="p">:</span> <span class="p">[</span>
8097
- <a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span>
8098
- <a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> <span class="p">],</span>
8099
- <a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> <span class="s1">&#39;dcim.rack&#39;</span><span class="p">:</span> <span class="p">[</span>
8100
- <a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span>
8101
- <a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> <span class="p">],</span>
8102
- <a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a><span class="p">}</span>
8137
+ <div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="p">{</span>
8138
+ <a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a> <span class="s1">&#39;dcim.location&#39;</span><span class="p">:</span> <span class="p">[</span>
8139
+ <a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span>
8140
+ <a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a> <span class="p">],</span>
8141
+ <a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a> <span class="s1">&#39;dcim.rack&#39;</span><span class="p">:</span> <span class="p">[</span>
8142
+ <a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span> <span class="o">&lt;</span><span class="n">TemplateExtension</span><span class="o">&gt;</span><span class="p">,</span>
8143
+ <a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a> <span class="p">],</span>
8144
+ <a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="p">}</span>
8103
8145
  </code></pre></div>
8104
8146
 
8105
8147
 
@@ -6931,6 +6931,21 @@
6931
6931
  </span>
6932
6932
  </a>
6933
6933
 
6934
+ <nav class="md-nav" aria-label="Data Model">
6935
+ <ul class="md-nav__list">
6936
+
6937
+ <li class="md-nav__item">
6938
+ <a href="#extras-features" class="md-nav__link">
6939
+ <span class="md-ellipsis">
6940
+ Extras Features
6941
+ </span>
6942
+ </a>
6943
+
6944
+ </li>
6945
+
6946
+ </ul>
6947
+ </nav>
6948
+
6934
6949
  </li>
6935
6950
 
6936
6951
  <li class="md-nav__item">
@@ -7870,6 +7885,21 @@
7870
7885
  </span>
7871
7886
  </a>
7872
7887
 
7888
+ <nav class="md-nav" aria-label="Data Model">
7889
+ <ul class="md-nav__list">
7890
+
7891
+ <li class="md-nav__item">
7892
+ <a href="#extras-features" class="md-nav__link">
7893
+ <span class="md-ellipsis">
7894
+ Extras Features
7895
+ </span>
7896
+ </a>
7897
+
7898
+ </li>
7899
+
7900
+ </ul>
7901
+ </nav>
7902
+
7873
7903
  </li>
7874
7904
 
7875
7905
  <li class="md-nav__item">
@@ -7998,7 +8028,7 @@ article ul li {
7998
8028
  <ul>
7999
8029
  <li>Implement model in <code>nautobot.&lt;app&gt;.models</code> module<ul>
8000
8030
  <li>Use appropriate <a href="best-practices.html#base-classes">base class</a> and mixin(s)</li>
8001
- <li>Use appropriate <code>@extras_features</code> decorator values</li>
8031
+ <li>Use appropriate <a href="#extras-features"><code>@extras_features</code></a> decorator values</li>
8002
8032
  <li>Define appropriate uniqueness constraint(s)</li>
8003
8033
  <li>Define appropriate <code>__str__()</code> logic</li>
8004
8034
  <li><em>optional</em> Define appropriate additional <a href="best-practices.html#model-validation"><code>clean()</code></a> logic<ul>
@@ -8020,6 +8050,24 @@ article ul li {
8020
8050
  </li>
8021
8051
  <li><em>optional</em> Expose any new relevant Python APIs in <code>nautobot.apps</code> namespace for App consumption</li>
8022
8052
  </ul>
8053
+ <h4 id="extras-features">Extras Features<a class="headerlink" href="#extras-features" title="Permanent link">&para;</a></h4>
8054
+ <ul>
8055
+ <li><code>cable_terminations</code>: Models that can be connected to another model with a <code>Cable</code></li>
8056
+ <li><code>config_context_owners</code>: Models that can be assigned to the <code>owner</code> GenericForeignKey field on a <code>ConfigContext</code></li>
8057
+ <li><code>custom_fields</code>: (DEPRECATED - Uses <code>nautobot.extras.utils.populate_model_features_registry</code> to populate <a href="model-features.html">Model Features Registry</a>) Models that support ComputedFields and CustomFields, used for limiting the choices for the <code>CustomField.content_types</code> and <code>ComputedField.content_type</code> fields</li>
8058
+ <li><code>custom_links</code>: Models that can display <code>CustomLinks</code> on the object's detail view (by default, all models that use <code>generic/object_retrieve.html</code> as a base template support custom links)</li>
8059
+ <li><code>custom_validators</code>: Models that can support custom <code>clean</code> logic by implementing a <a href="../apps/api/platform-features/custom-validators.html"><code>CustomValidator</code></a></li>
8060
+ <li><code>dynamic_groups</code>: Models that can be assigned to a <code>DynamicGroup</code>, used for limiting the choices for the <code>DynamicGroup.content_type</code> form field</li>
8061
+ <li><code>export_template_owners</code>: Models that can be assigned to the <code>owner</code> GenericForeignKey field on an <code>ExportTemplate</code></li>
8062
+ <li><code>export_templates</code>: Models that can be exported using an <code>ExportTemplate</code>, used for limiting the choices for the <code>ExportTemplate.content_type</code> field</li>
8063
+ <li><code>graphql</code>: Models that should be exposed through the <a href="../apps/api/models/graphql.html">GraphQL API</a>, used to build the list of registered models to build the GraphQL schema</li>
8064
+ <li><code>job_results</code>: No longer used.</li>
8065
+ <li><code>locations</code>: Models that support a foreign key to <code>Location</code>, used for limiting the choices for the <code>LocationType.content_types</code> field</li>
8066
+ <li><code>relationships</code>: (DEPRECATED - Uses <code>nautobot.extras.utils.populate_model_features_registry</code> to populate <a href="model-features.html">Model Features Registry</a>) Models that support custom relationships</li>
8067
+ <li><code>statuses</code>: Models that support a foreign key to <code>Status</code>, used for limiting the choices for the <code>Status.content_types</code> field</li>
8068
+ <li><code>webhooks</code>: Models that can be used to trigger webhooks, used for limiting the choices for the <code>Webhook.content_types</code> field</li>
8069
+ </ul>
8070
+ <p>Most new models should use the <code>custom_links</code>, <code>custom_validators</code>, <code>export_templates</code>, <code>graphql</code>, and <code>webhooks</code> features at minimum.</p>
8023
8071
  <h3 id="rest-api">REST API<a class="headerlink" href="#rest-api" title="Permanent link">&para;</a></h3>
8024
8072
  <ul>
8025
8073
  <li>Implement <code>&lt;Model&gt;FilterSet</code> class in <code>nautobot.&lt;app&gt;.filters</code> module<ul>
@@ -7821,8 +7821,8 @@
7821
7821
  <p>With this only Models which have fields names of <code>source_for_associations</code> and <code>destination_for_associations</code>, which in turn has the attribute <code>related_model=RelationshipAssociation</code>, would be a valid model for the feature <code>relationships</code>.</p>
7822
7822
  <div class="admonition note">
7823
7823
  <p class="admonition-title">Note</p>
7824
- </div>
7825
7824
  <p><code>populate_model_features_registry()</code> and <code>lookup_confs</code> provide an alternative to the older method of feature flagging models via the <code>@extras_features</code> decorator. In general new feature flags should preferentially be implemented via additions to <code>lookup_confs</code>, <em>not</em> by any new additions to <code>extras_features</code>.</p>
7825
+ </div>
7826
7826
 
7827
7827
 
7828
7828