nautobot 1.6.19__py3-none-any.whl → 1.6.21__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.
- nautobot/core/api/views.py +7 -1
- nautobot/core/templates/generic/object_list.html +21 -12
- nautobot/core/tests/test_views.py +19 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +71 -71
- nautobot/project-static/docs/release-notes/version-1.6.html +195 -84
- nautobot/project-static/docs/requirements.txt +1 -1
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +187 -187
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/METADATA +4 -4
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/RECORD +15 -15
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/LICENSE.txt +0 -0
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/NOTICE +0 -0
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/WHEEL +0 -0
- {nautobot-1.6.19.dist-info → nautobot-1.6.21.dist-info}/entry_points.txt +0 -0
nautobot/core/api/views.py
CHANGED
|
@@ -199,7 +199,13 @@ class ModelViewSetMixin:
|
|
|
199
199
|
# If using brief mode, clear all prefetches from the queryset and append only brief_prefetch_fields (if any)
|
|
200
200
|
if self.brief:
|
|
201
201
|
# v2 TODO(jathan): Replace prefetch_related with select_related
|
|
202
|
-
return
|
|
202
|
+
return (
|
|
203
|
+
super()
|
|
204
|
+
.get_queryset()
|
|
205
|
+
.select_related(None)
|
|
206
|
+
.prefetch_related(None)
|
|
207
|
+
.prefetch_related(*self.brief_prefetch_fields)
|
|
208
|
+
)
|
|
203
209
|
|
|
204
210
|
return super().get_queryset()
|
|
205
211
|
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
class="remove-filter-param"
|
|
69
69
|
title="Remove all items"
|
|
70
70
|
data-field-type="parent"
|
|
71
|
-
data-field-value={{ field.name }}
|
|
71
|
+
data-field-value="{{ field.name }}"
|
|
72
72
|
>×</span>
|
|
73
73
|
<ul class="filter-selection-rendered">
|
|
74
74
|
{% for value in field.values %}
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
<span
|
|
80
80
|
class="filter-selection-choice-remove remove-filter-param"
|
|
81
81
|
data-field-type="child"
|
|
82
|
-
data-field-parent={{ field.name }}
|
|
83
|
-
data-field-value={{ value.name }}
|
|
82
|
+
data-field-parent="{{ field.name }}"
|
|
83
|
+
data-field-value="{{ value.name }}"
|
|
84
84
|
>×</span>{{ value.display }}
|
|
85
85
|
</li>
|
|
86
86
|
{% endfor %}
|
|
@@ -185,18 +185,19 @@
|
|
|
185
185
|
|
|
186
186
|
// Remove applied filters
|
|
187
187
|
$(".remove-filter-param").on("click", function(){
|
|
188
|
-
let query_params = location.search;
|
|
188
|
+
let query_params = new URLSearchParams(location.search);
|
|
189
189
|
let type = $(this).attr("data-field-type");
|
|
190
190
|
let field_value = $(this).attr("data-field-value");
|
|
191
|
-
let query_string = location.search.substr(1).split("&");
|
|
192
191
|
|
|
193
192
|
if (type === "parent") {
|
|
194
|
-
|
|
193
|
+
// Remove all instances of this query param
|
|
194
|
+
query_params.delete(field_value);
|
|
195
195
|
} else {
|
|
196
|
+
// Remove this specific instance of this query param
|
|
196
197
|
let parent = $(this).attr("data-field-parent");
|
|
197
|
-
|
|
198
|
+
query_params.delete(parent, field_value);
|
|
198
199
|
}
|
|
199
|
-
location.
|
|
200
|
+
location.assign("?" + query_params);
|
|
200
201
|
})
|
|
201
202
|
|
|
202
203
|
// On submit of filter form
|
|
@@ -210,10 +211,18 @@
|
|
|
210
211
|
q_field_phantom.val(q_field.val())
|
|
211
212
|
dynamic_form.append(q_field_phantom);
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
// Get the serialized data from the forms and:
|
|
215
|
+
// 1) filter out query_params which values are empty e.g. ?sam=&dan=2 becomes ?dan=2
|
|
216
|
+
// 2) combine the two forms into a single set of data without duplicate entries
|
|
217
|
+
let search_query = new URLSearchParams()
|
|
218
|
+
let dynamic_query = new URLSearchParams(new FormData(document.getElementById("dynamic-filter-form")));
|
|
219
|
+
dynamic_query.forEach((value, key) => { if (value != "") { search_query.append(key, value); }});
|
|
220
|
+
let default_query = new URLSearchParams(new FormData(document.getElementById("default-filter").firstElementChild));
|
|
221
|
+
default_query.forEach((value, key) => {
|
|
222
|
+
if (value != "" && !search_query.has(key, value)) { search_query.append(key, value); }
|
|
223
|
+
});
|
|
224
|
+
$("#FilterForm_modal").modal("hide");
|
|
225
|
+
location.assign("?" + search_query);
|
|
217
226
|
})
|
|
218
227
|
|
|
219
228
|
// On submit of filter search form
|
|
@@ -163,6 +163,25 @@ class FilterFormsTestCase(TestCase):
|
|
|
163
163
|
response.content.decode(response.charset),
|
|
164
164
|
)
|
|
165
165
|
|
|
166
|
+
def test_filtering_crafted_query_params(self):
|
|
167
|
+
"""Test for reflected-XSS vulnerability GHSA-jxgr-gcj5-cqqg."""
|
|
168
|
+
self.add_permissions("dcim.view_location")
|
|
169
|
+
query_param = "?location_type=1 onmouseover=alert('hi') foo=bar"
|
|
170
|
+
url = reverse("dcim:location_list") + query_param
|
|
171
|
+
response = self.client.get(url)
|
|
172
|
+
self.assertHttpStatus(response, 200)
|
|
173
|
+
response_content = response.content.decode(response.charset)
|
|
174
|
+
# The important thing here is that the data-field-parent and data-field-value are correctly quoted
|
|
175
|
+
self.assertInHTML(
|
|
176
|
+
"""
|
|
177
|
+
<span class="filter-selection-choice-remove remove-filter-param"
|
|
178
|
+
data-field-type="child"
|
|
179
|
+
data-field-parent="location_type"
|
|
180
|
+
data-field-value="1 onmouseover=alert('hi') foo=bar"
|
|
181
|
+
>×</span>""", # noqa: RUF001 - ambiguous-unicode-character-string
|
|
182
|
+
response_content,
|
|
183
|
+
)
|
|
184
|
+
|
|
166
185
|
|
|
167
186
|
class ForceScriptNameTestcase(TestCase):
|
|
168
187
|
"""Basic test to assert that `settings.FORCE_SCRIPT_NAME` works as intended."""
|
|
@@ -5055,13 +5055,7 @@ to the end of <code>fields</code> if they are applicable to this model and this
|
|
|
5055
5055
|
|
|
5056
5056
|
<details class="quote">
|
|
5057
5057
|
<summary>Source code in <code>nautobot/core/api/views.py</code></summary>
|
|
5058
|
-
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-
|
|
5059
|
-
<span class="normal"><a href="#__codelineno-0-257">257</a></span>
|
|
5060
|
-
<span class="normal"><a href="#__codelineno-0-258">258</a></span>
|
|
5061
|
-
<span class="normal"><a href="#__codelineno-0-259">259</a></span>
|
|
5062
|
-
<span class="normal"><a href="#__codelineno-0-260">260</a></span>
|
|
5063
|
-
<span class="normal"><a href="#__codelineno-0-261">261</a></span>
|
|
5064
|
-
<span class="normal"><a href="#__codelineno-0-262">262</a></span>
|
|
5058
|
+
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-262">262</a></span>
|
|
5065
5059
|
<span class="normal"><a href="#__codelineno-0-263">263</a></span>
|
|
5066
5060
|
<span class="normal"><a href="#__codelineno-0-264">264</a></span>
|
|
5067
5061
|
<span class="normal"><a href="#__codelineno-0-265">265</a></span>
|
|
@@ -5111,63 +5105,69 @@ to the end of <code>fields</code> if they are applicable to this model and this
|
|
|
5111
5105
|
<span class="normal"><a href="#__codelineno-0-309">309</a></span>
|
|
5112
5106
|
<span class="normal"><a href="#__codelineno-0-310">310</a></span>
|
|
5113
5107
|
<span class="normal"><a href="#__codelineno-0-311">311</a></span>
|
|
5114
|
-
<span class="normal"><a href="#__codelineno-0-312">312</a></span
|
|
5115
|
-
<
|
|
5116
|
-
<
|
|
5117
|
-
<
|
|
5118
|
-
<
|
|
5119
|
-
<
|
|
5120
|
-
<a id="__codelineno-0-262" name="__codelineno-0-262"></a><span class="p">
|
|
5121
|
-
<a id="__codelineno-0-263" name="__codelineno-0-263"></a
|
|
5122
|
-
<a id="__codelineno-0-264" name="__codelineno-0-264"></a
|
|
5123
|
-
<a id="__codelineno-0-265" name="__codelineno-0-265"></a
|
|
5124
|
-
<a id="__codelineno-0-266" name="__codelineno-0-266"></a>
|
|
5125
|
-
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="
|
|
5126
|
-
<a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="
|
|
5127
|
-
<a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="
|
|
5128
|
-
<a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd">
|
|
5129
|
-
<a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd">
|
|
5130
|
-
<a id="__codelineno-0-272" name="__codelineno-0-272"></a>
|
|
5131
|
-
<a id="__codelineno-0-273" name="__codelineno-0-273"></a>
|
|
5132
|
-
<a id="__codelineno-0-274" name="__codelineno-0-274"></a
|
|
5133
|
-
<a id="__codelineno-0-275" name="__codelineno-0-275"></a
|
|
5134
|
-
<a id="__codelineno-0-276" name="__codelineno-0-276"></a
|
|
5135
|
-
<a id="__codelineno-0-277" name="__codelineno-0-277"></a
|
|
5136
|
-
<a id="__codelineno-0-278" name="__codelineno-0-278"></a>
|
|
5137
|
-
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="
|
|
5138
|
-
<a id="__codelineno-0-280" name="__codelineno-0-280"></a>
|
|
5139
|
-
<a id="__codelineno-0-281" name="__codelineno-0-281"></a>
|
|
5140
|
-
<a id="__codelineno-0-282" name="__codelineno-0-282"></a>
|
|
5141
|
-
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="
|
|
5142
|
-
<a id="__codelineno-0-284" name="__codelineno-0-284"></a>
|
|
5143
|
-
<a id="__codelineno-0-285" name="__codelineno-0-285"></a>
|
|
5144
|
-
<a id="__codelineno-0-286" name="__codelineno-0-286"></a>
|
|
5145
|
-
<a id="__codelineno-0-287" name="__codelineno-0-287"></a>
|
|
5146
|
-
<a id="__codelineno-0-288" name="__codelineno-0-288"></a>
|
|
5147
|
-
<a id="__codelineno-0-289" name="__codelineno-0-289"></a>
|
|
5148
|
-
<a id="__codelineno-0-290" name="__codelineno-0-290"></a>
|
|
5149
|
-
<a id="__codelineno-0-291" name="__codelineno-0-291"></a>
|
|
5150
|
-
<a id="__codelineno-0-292" name="__codelineno-0-292"></a>
|
|
5151
|
-
<a id="__codelineno-0-293" name="__codelineno-0-293"></a>
|
|
5152
|
-
<a id="__codelineno-0-294" name="__codelineno-0-294"></a>
|
|
5153
|
-
<a id="__codelineno-0-295" name="__codelineno-0-295"></a>
|
|
5154
|
-
<a id="__codelineno-0-296" name="__codelineno-0-296"></a>
|
|
5155
|
-
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="
|
|
5156
|
-
<a id="__codelineno-0-298" name="__codelineno-0-298"></a>
|
|
5157
|
-
<a id="__codelineno-0-299" name="__codelineno-0-299"></a>
|
|
5158
|
-
<a id="__codelineno-0-300" name="__codelineno-0-300"></a>
|
|
5159
|
-
<a id="__codelineno-0-301" name="__codelineno-0-301"></a>
|
|
5160
|
-
<a id="__codelineno-0-302" name="__codelineno-0-302"></a>
|
|
5161
|
-
<a id="__codelineno-0-303" name="__codelineno-0-303"></a>
|
|
5162
|
-
<a id="__codelineno-0-304" name="__codelineno-0-304"></a>
|
|
5163
|
-
<a id="__codelineno-0-305" name="__codelineno-0-305"></a>
|
|
5164
|
-
<a id="__codelineno-0-306" name="__codelineno-0-306"></a>
|
|
5165
|
-
<a id="__codelineno-0-307" name="__codelineno-0-307"></a>
|
|
5166
|
-
<a id="__codelineno-0-308" name="__codelineno-0-308"></a>
|
|
5167
|
-
<a id="__codelineno-0-309" name="__codelineno-0-309"></a>
|
|
5168
|
-
<a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="
|
|
5169
|
-
<a id="__codelineno-0-311" name="__codelineno-0-311"></a>
|
|
5170
|
-
<a id="__codelineno-0-312" name="__codelineno-0-312"></a>
|
|
5108
|
+
<span class="normal"><a href="#__codelineno-0-312">312</a></span>
|
|
5109
|
+
<span class="normal"><a href="#__codelineno-0-313">313</a></span>
|
|
5110
|
+
<span class="normal"><a href="#__codelineno-0-314">314</a></span>
|
|
5111
|
+
<span class="normal"><a href="#__codelineno-0-315">315</a></span>
|
|
5112
|
+
<span class="normal"><a href="#__codelineno-0-316">316</a></span>
|
|
5113
|
+
<span class="normal"><a href="#__codelineno-0-317">317</a></span>
|
|
5114
|
+
<span class="normal"><a href="#__codelineno-0-318">318</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-262" name="__codelineno-0-262"></a><span class="k">class</span> <span class="nc">ModelViewSet</span><span class="p">(</span>
|
|
5115
|
+
<a id="__codelineno-0-263" name="__codelineno-0-263"></a> <span class="n">NautobotAPIVersionMixin</span><span class="p">,</span>
|
|
5116
|
+
<a id="__codelineno-0-264" name="__codelineno-0-264"></a> <span class="n">BulkUpdateModelMixin</span><span class="p">,</span>
|
|
5117
|
+
<a id="__codelineno-0-265" name="__codelineno-0-265"></a> <span class="n">BulkDestroyModelMixin</span><span class="p">,</span>
|
|
5118
|
+
<a id="__codelineno-0-266" name="__codelineno-0-266"></a> <span class="n">ModelViewSetMixin</span><span class="p">,</span>
|
|
5119
|
+
<a id="__codelineno-0-267" name="__codelineno-0-267"></a> <span class="n">ModelViewSet_</span><span class="p">,</span>
|
|
5120
|
+
<a id="__codelineno-0-268" name="__codelineno-0-268"></a><span class="p">):</span>
|
|
5121
|
+
<a id="__codelineno-0-269" name="__codelineno-0-269"></a><span class="w"> </span><span class="sd">"""</span>
|
|
5122
|
+
<a id="__codelineno-0-270" name="__codelineno-0-270"></a><span class="sd"> Extend DRF's ModelViewSet to support bulk update and delete functions.</span>
|
|
5123
|
+
<a id="__codelineno-0-271" name="__codelineno-0-271"></a><span class="sd"> """</span>
|
|
5124
|
+
<a id="__codelineno-0-272" name="__codelineno-0-272"></a>
|
|
5125
|
+
<a id="__codelineno-0-273" name="__codelineno-0-273"></a> <span class="k">def</span> <span class="nf">_validate_objects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
|
|
5126
|
+
<a id="__codelineno-0-274" name="__codelineno-0-274"></a><span class="w"> </span><span class="sd">"""</span>
|
|
5127
|
+
<a id="__codelineno-0-275" name="__codelineno-0-275"></a><span class="sd"> Check that the provided instance or list of instances are matched by the current queryset. This confirms that</span>
|
|
5128
|
+
<a id="__codelineno-0-276" name="__codelineno-0-276"></a><span class="sd"> any newly created or modified objects abide by the attributes granted by any applicable ObjectPermissions.</span>
|
|
5129
|
+
<a id="__codelineno-0-277" name="__codelineno-0-277"></a><span class="sd"> """</span>
|
|
5130
|
+
<a id="__codelineno-0-278" name="__codelineno-0-278"></a> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="nb">list</span><span class="p">):</span>
|
|
5131
|
+
<a id="__codelineno-0-279" name="__codelineno-0-279"></a> <span class="c1"># Check that all instances are still included in the view's queryset</span>
|
|
5132
|
+
<a id="__codelineno-0-280" name="__codelineno-0-280"></a> <span class="n">conforming_count</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">pk__in</span><span class="o">=</span><span class="p">[</span><span class="n">obj</span><span class="o">.</span><span class="n">pk</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">instance</span><span class="p">])</span><span class="o">.</span><span class="n">count</span><span class="p">()</span>
|
|
5133
|
+
<a id="__codelineno-0-281" name="__codelineno-0-281"></a> <span class="k">if</span> <span class="n">conforming_count</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">instance</span><span class="p">):</span>
|
|
5134
|
+
<a id="__codelineno-0-282" name="__codelineno-0-282"></a> <span class="k">raise</span> <span class="n">ObjectDoesNotExist</span>
|
|
5135
|
+
<a id="__codelineno-0-283" name="__codelineno-0-283"></a> <span class="k">else</span><span class="p">:</span>
|
|
5136
|
+
<a id="__codelineno-0-284" name="__codelineno-0-284"></a> <span class="c1"># Check that the instance is matched by the view's queryset</span>
|
|
5137
|
+
<a id="__codelineno-0-285" name="__codelineno-0-285"></a> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pk</span><span class="o">=</span><span class="n">instance</span><span class="o">.</span><span class="n">pk</span><span class="p">)</span>
|
|
5138
|
+
<a id="__codelineno-0-286" name="__codelineno-0-286"></a>
|
|
5139
|
+
<a id="__codelineno-0-287" name="__codelineno-0-287"></a> <span class="k">def</span> <span class="nf">perform_create</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serializer</span><span class="p">):</span>
|
|
5140
|
+
<a id="__codelineno-0-288" name="__codelineno-0-288"></a> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">model</span>
|
|
5141
|
+
<a id="__codelineno-0-289" name="__codelineno-0-289"></a> <span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"nautobot.core.api.views.ModelViewSet"</span><span class="p">)</span>
|
|
5142
|
+
<a id="__codelineno-0-290" name="__codelineno-0-290"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Creating new </span><span class="si">{</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
5143
|
+
<a id="__codelineno-0-291" name="__codelineno-0-291"></a>
|
|
5144
|
+
<a id="__codelineno-0-292" name="__codelineno-0-292"></a> <span class="c1"># Enforce object-level permissions on save()</span>
|
|
5145
|
+
<a id="__codelineno-0-293" name="__codelineno-0-293"></a> <span class="k">try</span><span class="p">:</span>
|
|
5146
|
+
<a id="__codelineno-0-294" name="__codelineno-0-294"></a> <span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">():</span>
|
|
5147
|
+
<a id="__codelineno-0-295" name="__codelineno-0-295"></a> <span class="n">instance</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
|
|
5148
|
+
<a id="__codelineno-0-296" name="__codelineno-0-296"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_validate_objects</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
5149
|
+
<a id="__codelineno-0-297" name="__codelineno-0-297"></a> <span class="k">except</span> <span class="n">ObjectDoesNotExist</span><span class="p">:</span>
|
|
5150
|
+
<a id="__codelineno-0-298" name="__codelineno-0-298"></a> <span class="k">raise</span> <span class="n">PermissionDenied</span><span class="p">()</span>
|
|
5151
|
+
<a id="__codelineno-0-299" name="__codelineno-0-299"></a>
|
|
5152
|
+
<a id="__codelineno-0-300" name="__codelineno-0-300"></a> <span class="k">def</span> <span class="nf">perform_update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serializer</span><span class="p">):</span>
|
|
5153
|
+
<a id="__codelineno-0-301" name="__codelineno-0-301"></a> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">model</span>
|
|
5154
|
+
<a id="__codelineno-0-302" name="__codelineno-0-302"></a> <span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"nautobot.core.api.views.ModelViewSet"</span><span class="p">)</span>
|
|
5155
|
+
<a id="__codelineno-0-303" name="__codelineno-0-303"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Updating </span><span class="si">{</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">serializer</span><span class="o">.</span><span class="n">instance</span><span class="si">}</span><span class="s2"> (PK: </span><span class="si">{</span><span class="n">serializer</span><span class="o">.</span><span class="n">instance</span><span class="o">.</span><span class="n">pk</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
|
|
5156
|
+
<a id="__codelineno-0-304" name="__codelineno-0-304"></a>
|
|
5157
|
+
<a id="__codelineno-0-305" name="__codelineno-0-305"></a> <span class="c1"># Enforce object-level permissions on save()</span>
|
|
5158
|
+
<a id="__codelineno-0-306" name="__codelineno-0-306"></a> <span class="k">try</span><span class="p">:</span>
|
|
5159
|
+
<a id="__codelineno-0-307" name="__codelineno-0-307"></a> <span class="k">with</span> <span class="n">transaction</span><span class="o">.</span><span class="n">atomic</span><span class="p">():</span>
|
|
5160
|
+
<a id="__codelineno-0-308" name="__codelineno-0-308"></a> <span class="n">instance</span> <span class="o">=</span> <span class="n">serializer</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
|
|
5161
|
+
<a id="__codelineno-0-309" name="__codelineno-0-309"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_validate_objects</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
5162
|
+
<a id="__codelineno-0-310" name="__codelineno-0-310"></a> <span class="k">except</span> <span class="n">ObjectDoesNotExist</span><span class="p">:</span>
|
|
5163
|
+
<a id="__codelineno-0-311" name="__codelineno-0-311"></a> <span class="k">raise</span> <span class="n">PermissionDenied</span><span class="p">()</span>
|
|
5164
|
+
<a id="__codelineno-0-312" name="__codelineno-0-312"></a>
|
|
5165
|
+
<a id="__codelineno-0-313" name="__codelineno-0-313"></a> <span class="k">def</span> <span class="nf">perform_destroy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instance</span><span class="p">):</span>
|
|
5166
|
+
<a id="__codelineno-0-314" name="__codelineno-0-314"></a> <span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">queryset</span><span class="o">.</span><span class="n">model</span>
|
|
5167
|
+
<a id="__codelineno-0-315" name="__codelineno-0-315"></a> <span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"nautobot.core.api.views.ModelViewSet"</span><span class="p">)</span>
|
|
5168
|
+
<a id="__codelineno-0-316" name="__codelineno-0-316"></a> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Deleting </span><span class="si">{</span><span class="n">model</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">verbose_name</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">instance</span><span class="si">}</span><span class="s2"> (PK: </span><span class="si">{</span><span class="n">instance</span><span class="o">.</span><span class="n">pk</span><span class="si">}</span><span class="s2">)"</span><span class="p">)</span>
|
|
5169
|
+
<a id="__codelineno-0-317" name="__codelineno-0-317"></a>
|
|
5170
|
+
<a id="__codelineno-0-318" name="__codelineno-0-318"></a> <span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">perform_destroy</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
|
|
5171
5171
|
</code></pre></div></td></tr></table></div>
|
|
5172
5172
|
</details>
|
|
5173
5173
|
|
|
@@ -5789,13 +5789,13 @@ to the end of <code>fields</code> if they are applicable to this model and this
|
|
|
5789
5789
|
|
|
5790
5790
|
<details class="quote">
|
|
5791
5791
|
<summary>Source code in <code>nautobot/core/api/views.py</code></summary>
|
|
5792
|
-
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-
|
|
5793
|
-
<span class="normal"><a href="#__codelineno-0-
|
|
5794
|
-
<span class="normal"><a href="#__codelineno-0-
|
|
5795
|
-
<span class="normal"><a href="#__codelineno-0-
|
|
5796
|
-
<a id="__codelineno-0-
|
|
5797
|
-
<a id="__codelineno-0-
|
|
5798
|
-
<a id="__codelineno-0-
|
|
5792
|
+
<div class="highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-321">321</a></span>
|
|
5793
|
+
<span class="normal"><a href="#__codelineno-0-322">322</a></span>
|
|
5794
|
+
<span class="normal"><a href="#__codelineno-0-323">323</a></span>
|
|
5795
|
+
<span class="normal"><a href="#__codelineno-0-324">324</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-321" name="__codelineno-0-321"></a><span class="k">class</span> <span class="nc">ReadOnlyModelViewSet</span><span class="p">(</span><span class="n">NautobotAPIVersionMixin</span><span class="p">,</span> <span class="n">ModelViewSetMixin</span><span class="p">,</span> <span class="n">ReadOnlyModelViewSet_</span><span class="p">):</span>
|
|
5796
|
+
<a id="__codelineno-0-322" name="__codelineno-0-322"></a><span class="w"> </span><span class="sd">"""</span>
|
|
5797
|
+
<a id="__codelineno-0-323" name="__codelineno-0-323"></a><span class="sd"> Extend DRF's ReadOnlyModelViewSet to support queryset restriction.</span>
|
|
5798
|
+
<a id="__codelineno-0-324" name="__codelineno-0-324"></a><span class="sd"> """</span>
|
|
5799
5799
|
</code></pre></div></td></tr></table></div>
|
|
5800
5800
|
</details>
|
|
5801
5801
|
|