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

Merge pull request #1572 from digitalocean/develop

Release v2.1.6
Jeremy Stretch 8 лет назад
Родитель
Сommit
7cb287d6c6

+ 1 - 1
netbox/ipam/tables.py

@@ -71,7 +71,7 @@ IPADDRESS_LINK = """
 {% if record.pk %}
 {% if record.pk %}
     <a href="{{ record.get_absolute_url }}">{{ record.address }}</a>
     <a href="{{ record.get_absolute_url }}">{{ record.address }}</a>
 {% elif perms.ipam.add_ipaddress %}
 {% elif perms.ipam.add_ipaddress %}
-    <a href="{% url 'ipam:ipaddress_add' %}?address={{ record.1 }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}" class="btn btn-xs btn-success">{% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available</a>
+    <a href="{% url 'ipam:ipaddress_add' %}?address={{ record.1 }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}{% if prefix.tenant %}&tenant={{ prefix.tenant.pk }}{% endif %}" class="btn btn-xs btn-success">{% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available</a>
 {% else %}
 {% else %}
     {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available
     {% if record.0 <= 65536 %}{{ record.0 }}{% else %}Many{% endif %} IP{{ record.0|pluralize }} available
 {% endif %}
 {% endif %}

+ 2 - 2
netbox/netbox/settings.py

@@ -13,7 +13,7 @@ except ImportError:
     )
     )
 
 
 
 
-VERSION = '2.1.5'
+VERSION = '2.1.6'
 
 
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
 
@@ -228,7 +228,7 @@ REST_FRAMEWORK = {
         'utilities.api.TokenAuthentication',
         'utilities.api.TokenAuthentication',
     ),
     ),
     'DEFAULT_FILTER_BACKENDS': (
     'DEFAULT_FILTER_BACKENDS': (
-        'rest_framework.filters.DjangoFilterBackend',
+        'django_filters.rest_framework.DjangoFilterBackend',
     ),
     ),
     'DEFAULT_PAGINATION_CLASS': 'utilities.api.OptionalLimitOffsetPagination',
     'DEFAULT_PAGINATION_CLASS': 'utilities.api.OptionalLimitOffsetPagination',
     'DEFAULT_PERMISSION_CLASSES': (
     'DEFAULT_PERMISSION_CLASSES': (

+ 3 - 3
netbox/netbox/views.py

@@ -14,7 +14,7 @@ from circuits.models import Circuit, Provider
 from circuits.tables import CircuitTable, ProviderTable
 from circuits.tables import CircuitTable, ProviderTable
 from dcim.filters import DeviceFilter, DeviceTypeFilter, RackFilter, SiteFilter
 from dcim.filters import DeviceFilter, DeviceTypeFilter, RackFilter, SiteFilter
 from dcim.models import ConsolePort, Device, DeviceType, InterfaceConnection, PowerPort, Rack, Site
 from dcim.models import ConsolePort, Device, DeviceType, InterfaceConnection, PowerPort, Rack, Site
-from dcim.tables import DeviceTable, DeviceTypeTable, RackTable, SiteTable
+from dcim.tables import DeviceDetailTable, DeviceTypeTable, RackTable, SiteTable
 from extras.models import TopologyMap, UserAction
 from extras.models import TopologyMap, UserAction
 from ipam.filters import AggregateFilter, IPAddressFilter, PrefixFilter, VLANFilter, VRFFilter
 from ipam.filters import AggregateFilter, IPAddressFilter, PrefixFilter, VLANFilter, VRFFilter
 from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
 from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
@@ -64,10 +64,10 @@ SEARCH_TYPES = OrderedDict((
     }),
     }),
     ('device', {
     ('device', {
         'queryset': Device.objects.select_related(
         'queryset': Device.objects.select_related(
-            'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack'
+            'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
         ),
         ),
         'filter': DeviceFilter,
         'filter': DeviceFilter,
-        'table': DeviceTable,
+        'table': DeviceDetailTable,
         'url': 'dcim:device_list',
         'url': 'dcim:device_list',
     }),
     }),
     # IPAM
     # IPAM

+ 1 - 1
netbox/templates/ipam/inc/prefix_header.html

@@ -23,7 +23,7 @@
 </div>
 </div>
 <div class="pull-right">
 <div class="pull-right">
     {% if perms.ipam.add_ipaddress %}
     {% if perms.ipam.add_ipaddress %}
-		<a href="{% url 'ipam:ipaddress_add' %}?address={{ prefix.prefix }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}" class="btn btn-success">
+		<a href="{% url 'ipam:ipaddress_add' %}?address={{ prefix.prefix }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}{% if prefix.tenant %}&tenant={{ prefix.tenant.pk }}{% endif %}" class="btn btn-success">
 			<span class="fa fa-plus" aria-hidden="true"></span>
 			<span class="fa fa-plus" aria-hidden="true"></span>
 			Add an IP Address
 			Add an IP Address
 		</a>
 		</a>

+ 14 - 7
netbox/utilities/api.py

@@ -4,13 +4,12 @@ from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 
 
 from rest_framework import authentication, exceptions
 from rest_framework import authentication, exceptions
-from rest_framework.compat import is_authenticated
 from rest_framework.exceptions import APIException
 from rest_framework.exceptions import APIException
 from rest_framework.pagination import LimitOffsetPagination
 from rest_framework.pagination import LimitOffsetPagination
 from rest_framework.permissions import BasePermission, DjangoModelPermissions, SAFE_METHODS
 from rest_framework.permissions import BasePermission, DjangoModelPermissions, SAFE_METHODS
 from rest_framework.renderers import BrowsableAPIRenderer
 from rest_framework.renderers import BrowsableAPIRenderer
 from rest_framework.serializers import Field, ModelSerializer, ValidationError
 from rest_framework.serializers import Field, ModelSerializer, ValidationError
-from rest_framework.views import get_view_name as drf_get_view_name
+from rest_framework.utils import formatting
 
 
 from users.models import Token
 from users.models import Token
 
 
@@ -75,7 +74,7 @@ class IsAuthenticatedOrLoginNotRequired(BasePermission):
     def has_permission(self, request, view):
     def has_permission(self, request, view):
         if not settings.LOGIN_REQUIRED:
         if not settings.LOGIN_REQUIRED:
             return True
             return True
-        return request.user and is_authenticated(request.user)
+        return request.user.is_authenticated()
 
 
 
 
 #
 #
@@ -228,10 +227,18 @@ def get_view_name(view_cls, suffix=None):
     Derive the view name from its associated model, if it has one. Fall back to DRF's built-in `get_view_name`.
     Derive the view name from its associated model, if it has one. Fall back to DRF's built-in `get_view_name`.
     """
     """
     if hasattr(view_cls, 'queryset'):
     if hasattr(view_cls, 'queryset'):
+        # Determine the model name from the queryset.
         name = view_cls.queryset.model._meta.verbose_name
         name = view_cls.queryset.model._meta.verbose_name
         name = ' '.join([w[0].upper() + w[1:] for w in name.split()])  # Capitalize each word
         name = ' '.join([w[0].upper() + w[1:] for w in name.split()])  # Capitalize each word
-        if suffix:
-            name = "{} {}".format(name, suffix)
-        return name
 
 
-    return drf_get_view_name(view_cls, suffix)
+    else:
+        # Replicate DRF's built-in behavior.
+        name = view_cls.__name__
+        name = formatting.remove_trailing_string(name, 'View')
+        name = formatting.remove_trailing_string(name, 'ViewSet')
+        name = formatting.camelcase_to_spaces(name)
+
+    if suffix:
+        name += ' ' + suffix
+
+    return name