Просмотр исходного кода

Added list and utility views for tags

Jeremy Stretch 7 лет назад
Родитель
Сommit
03a1c48b54

+ 23 - 1
netbox/extras/forms.py

@@ -4,12 +4,17 @@ from collections import OrderedDict
 
 from django import forms
 from django.contrib.contenttypes.models import ContentType
+from taggit.models import Tag
 
-from utilities.forms import BootstrapMixin, BulkEditForm, LaxURLField
+from utilities.forms import BootstrapMixin, BulkEditForm, LaxURLField, SlugField
 from .constants import CF_FILTER_DISABLED, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_INTEGER, CF_TYPE_SELECT, CF_TYPE_URL
 from .models import CustomField, CustomFieldValue, ImageAttachment
 
 
+#
+# Custom fields
+#
+
 def get_custom_fields_for_model(content_type, filterable_only=False, bulk_edit=False):
     """
     Retrieve all CustomFields applicable to the given ContentType
@@ -162,6 +167,23 @@ class CustomFieldFilterForm(forms.Form):
             self.fields[name] = field
 
 
+#
+# Tags
+#
+#
+
+class TagForm(BootstrapMixin, forms.ModelForm):
+    slug = SlugField()
+
+    class Meta:
+        model = Tag
+        fields = ['name', 'slug']
+
+
+#
+# Image attachments
+#
+
 class ImageAttachmentForm(BootstrapMixin, forms.ModelForm):
 
     class Meta:

+ 28 - 0
netbox/extras/tables.py

@@ -0,0 +1,28 @@
+from __future__ import unicode_literals
+
+import django_tables2 as tables
+from taggit.models import Tag
+
+from utilities.tables import BaseTable, ToggleColumn
+
+TAG_ACTIONS = """
+{% if perms.taggit.change_tag %}
+    <a href="{% url 'extras:tag_edit' slug=record.slug %}" class="btn btn-xs btn-warning"><i class="glyphicon glyphicon-pencil" aria-hidden="true"></i></a>
+{% endif %}
+{% if perms.taggit.delete_tag %}
+    <a href="{% url 'extras:tag_delete' slug=record.slug %}" class="btn btn-xs btn-danger"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></a>
+{% endif %}
+"""
+
+
+class TagTable(BaseTable):
+    pk = ToggleColumn()
+    actions = tables.TemplateColumn(
+        template_code=TAG_ACTIONS,
+        attrs={'td': {'class': 'text-right'}},
+        verbose_name=''
+    )
+
+    class Meta(BaseTable.Meta):
+        model = Tag
+        fields = ('pk', 'name', 'items')

+ 6 - 0
netbox/extras/urls.py

@@ -7,6 +7,12 @@ from extras import views
 app_name = 'extras'
 urlpatterns = [
 
+    # Tags
+    url(r'^tags/$', views.TagListView.as_view(), name='tag_list'),
+    url(r'^tags/(?P<slug>[\w-]+)/edit/$', views.TagEditView.as_view(), name='tag_edit'),
+    url(r'^tags/(?P<slug>[\w-]+)/delete/$', views.TagDeleteView.as_view(), name='tag_delete'),
+    url(r'^tags/delete/$', views.TagBulkDeleteView.as_view(), name='tag_bulk_delete'),
+
     # Image attachments
     url(r'^image-attachments/(?P<pk>\d+)/edit/$', views.ImageAttachmentEditView.as_view(), name='imageattachment_edit'),
     url(r'^image-attachments/(?P<pk>\d+)/delete/$', views.ImageAttachmentDeleteView.as_view(), name='imageattachment_delete'),

+ 39 - 3
netbox/extras/views.py

@@ -2,16 +2,52 @@ from __future__ import unicode_literals
 
 from django.contrib import messages
 from django.contrib.auth.mixins import PermissionRequiredMixin
+from django.db.models import Count
 from django.http import Http404
-from django.shortcuts import get_object_or_404, redirect, render
+from django.shortcuts import get_object_or_404, redirect, render, reverse
 from django.utils.safestring import mark_safe
 from django.views.generic import View
+from taggit.models import Tag
 
 from utilities.forms import ConfirmationForm
-from utilities.views import ObjectDeleteView, ObjectEditView
-from .forms import ImageAttachmentForm
+from utilities.views import BulkDeleteView, ObjectDeleteView, ObjectEditView, ObjectListView
+from .forms import ImageAttachmentForm, TagForm
 from .models import ImageAttachment, ReportResult, UserAction
 from .reports import get_report, get_reports
+from .tables import TagTable
+
+
+#
+# Tags
+#
+
+class TagListView(ObjectListView):
+    queryset = Tag.objects.annotate(items=Count('taggit_taggeditem_items')).order_by('name')
+    table = TagTable
+    template_name = 'extras/tag_list.html'
+
+
+class TagEditView(PermissionRequiredMixin, ObjectEditView):
+    permission_required = 'taggit.change_tag'
+    model = Tag
+    model_form = TagForm
+
+    def get_return_url(self, request, obj):
+        return reverse('extras:tag', kwargs={'slug': obj.slug})
+
+
+class TagDeleteView(PermissionRequiredMixin, ObjectDeleteView):
+    permission_required = 'taggit.delete_tag'
+    model = Tag
+    default_return_url = 'extras:tag_list'
+
+
+class TagBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
+    permission_required = 'circuits.delete_circuittype'
+    cls = Tag
+    queryset = Tag.objects.annotate(items=Count('taggit_taggeditem_items')).order_by('name')
+    table = TagTable
+    default_return_url = 'extras:tag_list'
 
 
 #

+ 11 - 0
netbox/templates/extras/tag_list.html

@@ -0,0 +1,11 @@
+{% extends '_base.html' %}
+{% load buttons %}
+
+{% block content %}
+<h1>{% block title %}Tags{% endblock %}</h1>
+<div class="row">
+	<div class="col-md-12">
+        {% include 'utilities/obj_table.html' with bulk_delete_url='extras:tag_bulk_delete' %}
+    </div>
+</div>
+{% endblock %}

+ 4 - 1
netbox/templates/inc/nav_menu.html

@@ -16,7 +16,7 @@
         <div id="navbar" class="navbar-collapse collapse">
             {% if request.user.is_authenticated or not settings.LOGIN_REQUIRED %}
             <ul class="nav navbar-nav">
-                <li class="dropdown{% if request.path|contains:'/dcim/sites/,/dcim/regions/,/tenancy/,/extras/reports/' %} active{% endif %}">
+                <li class="dropdown{% if request.path|contains:'/dcim/sites/,/dcim/regions/,/tenancy/,/extras/tags/,/extras/reports/' %} active{% endif %}">
                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Organization <span class="caret"></span></a>
                     <ul class="dropdown-menu">
                         <li class="dropdown-header">Sites</li>
@@ -60,6 +60,9 @@
                         </li>
                         <li class="divider"></li>
                         <li class="dropdown-header">Miscellaneous</li>
+                        <li>
+                            <a href="{% url 'extras:tag_list' %}">Tags</a>
+                        </li>
                         <li>
                             <a href="{% url 'extras:report_list' %}">Reports</a>
                         </li>