1
1
import django_filters
2
+ from core .models import ObjectChange
3
+ from core .tables import ObjectChangeTable
4
+ from django .contrib .contenttypes .models import ContentType
2
5
from django .contrib .postgres .fields import ArrayField
3
- from django .db .models import JSONField
6
+ from django .db .models import JSONField , Q
4
7
from django .shortcuts import get_object_or_404 , render
5
8
from django .urls import reverse
9
+ from django .utils .translation import gettext_lazy as _
10
+ from django .views .generic import View
6
11
from extras .choices import CustomFieldUIVisibleChoices
12
+ from extras .forms import JournalEntryForm
13
+ from extras .models import JournalEntry
14
+ from extras .tables import JournalEntryTable
7
15
from netbox .filtersets import BaseFilterSet
8
16
from netbox .forms import NetBoxModelBulkEditForm , NetBoxModelFilterSetForm
9
17
from netbox .views import generic
10
18
from netbox .views .generic .mixins import TableMixin
11
19
from utilities .forms import ConfirmationForm
12
20
from utilities .htmx import htmx_partial
13
- from utilities .views import get_viewname , register_model_view
21
+ from utilities .views import (ConditionalLoginRequiredMixin , ViewTab ,
22
+ get_viewname , register_model_view )
14
23
15
24
from netbox_custom_objects .tables import CustomObjectTable
16
25
@@ -120,7 +129,7 @@ def get_table(self, data, request, bulk_actions=True):
120
129
#
121
130
122
131
123
- @register_model_view (CustomObjectType , ' list' , path = '' , detail = False )
132
+ @register_model_view (CustomObjectType , " list" , path = "" , detail = False )
124
133
class CustomObjectTypeListView (generic .ObjectListView ):
125
134
queryset = CustomObjectType .objects .all ()
126
135
filterset = filtersets .CustomObjectTypeFilterSet
@@ -146,7 +155,7 @@ def get_extra_context(self, request, instance):
146
155
}
147
156
148
157
149
- @register_model_view (CustomObjectType , ' add' , detail = False )
158
+ @register_model_view (CustomObjectType , " add" , detail = False )
150
159
@register_model_view (CustomObjectType , "edit" )
151
160
class CustomObjectTypeEditView (generic .ObjectEditView ):
152
161
queryset = CustomObjectType .objects .all ()
@@ -164,6 +173,7 @@ def _get_dependent_objects(self, obj):
164
173
dependent_objects [model ] = list (model .objects .all ())
165
174
return dependent_objects
166
175
176
+
167
177
#
168
178
# Custom Object Type Fields
169
179
#
@@ -177,7 +187,7 @@ class CustomObjectTypeFieldEditView(generic.ObjectEditView):
177
187
178
188
@register_model_view (CustomObjectTypeField , "delete" )
179
189
class CustomObjectTypeFieldDeleteView (generic .ObjectDeleteView ):
180
- template_name = ' netbox_custom_objects/field_delete.html'
190
+ template_name = " netbox_custom_objects/field_delete.html"
181
191
queryset = CustomObjectTypeField .objects .all ()
182
192
183
193
def get_return_url (self , request , obj = None ):
@@ -195,56 +205,64 @@ def get(self, request, *args, **kwargs):
195
205
196
206
model = obj .custom_object_type .get_model ()
197
207
kwargs = {
198
- f' { obj .name } __isnull' : False ,
208
+ f" { obj .name } __isnull" : False ,
199
209
}
200
210
num_dependent_objects = model .objects .filter (** kwargs ).count ()
201
211
202
212
# If this is an HTMX request, return only the rendered deletion form as modal content
203
213
if htmx_partial (request ):
204
- viewname = get_viewname (self .queryset .model , action = 'delete' )
205
- form_url = reverse (viewname , kwargs = {'pk' : obj .pk })
206
- return render (request , 'htmx/delete_form.html' , {
207
- 'object' : obj ,
208
- 'object_type' : self .queryset .model ._meta .verbose_name ,
209
- 'form' : form ,
210
- 'form_url' : form_url ,
211
- 'num_dependent_objects' : num_dependent_objects ,
212
- ** self .get_extra_context (request , obj ),
213
- })
214
+ viewname = get_viewname (self .queryset .model , action = "delete" )
215
+ form_url = reverse (viewname , kwargs = {"pk" : obj .pk })
216
+ return render (
217
+ request ,
218
+ "htmx/delete_form.html" ,
219
+ {
220
+ "object" : obj ,
221
+ "object_type" : self .queryset .model ._meta .verbose_name ,
222
+ "form" : form ,
223
+ "form_url" : form_url ,
224
+ "num_dependent_objects" : num_dependent_objects ,
225
+ ** self .get_extra_context (request , obj ),
226
+ },
227
+ )
214
228
215
- return render (request , self .template_name , {
216
- 'object' : obj ,
217
- 'form' : form ,
218
- 'return_url' : self .get_return_url (request , obj ),
219
- 'num_dependent_objects' : num_dependent_objects ,
220
- ** self .get_extra_context (request , obj ),
221
- })
229
+ return render (
230
+ request ,
231
+ self .template_name ,
232
+ {
233
+ "object" : obj ,
234
+ "form" : form ,
235
+ "return_url" : self .get_return_url (request , obj ),
236
+ "num_dependent_objects" : num_dependent_objects ,
237
+ ** self .get_extra_context (request , obj ),
238
+ },
239
+ )
222
240
223
241
def _get_dependent_objects (self , obj ):
224
242
dependent_objects = super ()._get_dependent_objects (obj )
225
243
model = obj .custom_object_type .get_model ()
226
244
kwargs = {
227
- f' { obj .name } __isnull' : False ,
245
+ f" { obj .name } __isnull" : False ,
228
246
}
229
247
dependent_objects [model ] = list (model .objects .filter (** kwargs ))
230
248
return dependent_objects
231
249
232
250
233
- @register_model_view (CustomObjectType , ' bulk_import' , path = ' import' , detail = False )
251
+ @register_model_view (CustomObjectType , " bulk_import" , path = " import" , detail = False )
234
252
class CustomObjectTypeBulkImportView (generic .BulkImportView ):
235
253
queryset = CustomObjectType .objects .all ()
236
254
model_form = forms .CustomObjectTypeImportForm
237
255
238
256
239
- @register_model_view (CustomObjectType , ' bulk_edit' , path = ' edit' , detail = False )
257
+ @register_model_view (CustomObjectType , " bulk_edit" , path = " edit" , detail = False )
240
258
class CustomObjectTypeBulkEditView (generic .BulkEditView ):
241
259
queryset = CustomObjectType .objects .all ()
242
260
filterset = filtersets .CustomObjectTypeFilterSet
243
261
table = tables .CustomObjectTypeTable
244
262
form = forms .CustomObjectTypeBulkEditForm
245
263
246
264
247
- @register_model_view (CustomObjectType , ' bulk_delete' , path = ' delete' , detail = False )
265
+ @register_model_view (CustomObjectType , " bulk_delete" , path = " delete" , detail = False )
248
266
class CustomObjectTypeBulkDeleteView (generic .BulkDeleteView ):
249
267
queryset = CustomObjectType .objects .all ()
250
268
filterset = filtersets .CustomObjectTypeFilterSet
@@ -271,8 +289,8 @@ def get_queryset(self, request):
271
289
if self .queryset :
272
290
return self .queryset
273
291
custom_object_type = self .kwargs .get ("custom_object_type" , None )
274
- self .custom_object_type = get_object_or_404 (CustomObjectType ,
275
- name__iexact = custom_object_type
292
+ self .custom_object_type = get_object_or_404 (
293
+ CustomObjectType , name__iexact = custom_object_type
276
294
)
277
295
model = self .custom_object_type .get_model ()
278
296
return model .objects .all ()
@@ -354,16 +372,22 @@ class CustomObjectView(generic.ObjectView):
354
372
355
373
def get_queryset (self , request ):
356
374
custom_object_type = self .kwargs .get ("custom_object_type" , None )
357
- object_type = get_object_or_404 (CustomObjectType , name__iexact = custom_object_type )
375
+ object_type = get_object_or_404 (
376
+ CustomObjectType , name__iexact = custom_object_type
377
+ )
358
378
model = object_type .get_model ()
359
379
return model .objects .all ()
360
380
361
381
def get_object (self , ** kwargs ):
362
382
custom_object_type = self .kwargs .get ("custom_object_type" , None )
363
- object_type = get_object_or_404 (CustomObjectType , name__iexact = custom_object_type )
383
+ object_type = get_object_or_404 (
384
+ CustomObjectType , name__iexact = custom_object_type
385
+ )
364
386
model = object_type .get_model ()
365
387
# Filter out custom_object_type from kwargs for the object lookup
366
- lookup_kwargs = {k : v for k , v in self .kwargs .items () if k != "custom_object_type" }
388
+ lookup_kwargs = {
389
+ k : v for k , v in self .kwargs .items () if k != "custom_object_type"
390
+ }
367
391
return get_object_or_404 (model .objects .all (), ** lookup_kwargs )
368
392
369
393
def get_extra_context (self , request , instance ):
@@ -394,7 +418,9 @@ def get_object(self, **kwargs):
394
418
if self .object :
395
419
return self .object
396
420
custom_object_type = self .kwargs .pop ("custom_object_type" , None )
397
- object_type = get_object_or_404 (CustomObjectType , name__iexact = custom_object_type )
421
+ object_type = get_object_or_404 (
422
+ CustomObjectType , name__iexact = custom_object_type
423
+ )
398
424
model = object_type .get_model ()
399
425
if not self .kwargs .get ("pk" , None ):
400
426
# We're creating a new object
@@ -420,7 +446,9 @@ def get_form(self, model):
420
446
}
421
447
422
448
# Process custom object type fields (with grouping)
423
- for field in self .object .custom_object_type .fields .all ().order_by ('group_name' , 'weight' , 'name' ):
449
+ for field in self .object .custom_object_type .fields .all ().order_by (
450
+ "group_name" , "weight" , "name"
451
+ ):
424
452
field_type = field_types .FIELD_TYPE_CLASS [field .type ]()
425
453
try :
426
454
field_name = field .name
@@ -454,7 +482,9 @@ def custom_init(self, *args, **kwargs):
454
482
forms .NetBoxModelForm .__init__ (self , * args , ** kwargs )
455
483
# Set the grouping info as instance attributes from the outer scope
456
484
self .custom_object_type_fields = attrs ["custom_object_type_fields" ]
457
- self .custom_object_type_field_groups = attrs ["custom_object_type_field_groups" ]
485
+ self .custom_object_type_field_groups = attrs [
486
+ "custom_object_type_field_groups"
487
+ ]
458
488
459
489
form_class .__init__ = custom_init
460
490
@@ -479,7 +509,9 @@ def get_object(self, **kwargs):
479
509
if self .object :
480
510
return self .object
481
511
custom_object_type = self .kwargs .pop ("custom_object_type" , None )
482
- object_type = get_object_or_404 (CustomObjectType , name__iexact = custom_object_type )
512
+ object_type = get_object_or_404 (
513
+ CustomObjectType , name__iexact = custom_object_type
514
+ )
483
515
model = object_type .get_model ()
484
516
return get_object_or_404 (model .objects .all (), ** self .kwargs )
485
517
0 commit comments