Coverage for utilities/templatetags/tabs.py: 23%

31 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1from django import template 

2from django.urls.exceptions import NoReverseMatch 

3from django.utils.module_loading import import_string 

4 

5from netbox.registry import registry 

6from utilities.views import get_action_url 

7 

8__all__ = ( 

9 'model_view_tabs', 

10) 

11 

12register = template.Library() 

13 

14 

15# 

16# Object detail view tabs 

17# 

18 

19@register.inclusion_tag('tabs/model_view_tabs.html', takes_context=True) 

20def model_view_tabs(context, instance): 

21 app_label = instance._meta.app_label 

22 model_name = instance._meta.model_name 

23 user = context['request'].user 

24 tabs = [] 

25 

26 # Retrieve registered views for this model 

27 try: 

28 views = registry['views'][app_label][model_name] 

29 except KeyError: 

30 # No views have been registered for this model 

31 views = [] 

32 

33 # Compile a list of tabs to be displayed in the UI 

34 for config in views: 

35 view = import_string(config['view']) if type(config['view']) is str else config['view'] 

36 if tab := getattr(view, 'tab', None): 

37 if tab.permission and not user.has_perm(tab.permission): 

38 continue 

39 

40 if attrs := tab.render(instance): 

41 active_tab = context.get('tab') 

42 try: 

43 url = get_action_url(instance, action=config['name'], kwargs={'pk': instance.pk}) 

44 except NoReverseMatch: 

45 # No URL has been registered for this view; skip 

46 continue 

47 tabs.append({ 

48 'name': config['name'], 

49 'url': url, 

50 'label': attrs['label'], 

51 'badge': attrs['badge'], 

52 'weight': attrs['weight'], 

53 'is_active': active_tab and active_tab == tab, 

54 }) 

55 

56 # Order tabs by weight 

57 tabs = sorted(tabs, key=lambda x: x['weight']) 

58 

59 return { 

60 'tabs': tabs, 

61 }