mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
Merge pull request #3069 from digitalocean/2647-caching
intial work on #2647 - caching
This commit is contained in:
commit
1877afc760
@ -1,6 +1,7 @@
|
||||
sudo: required
|
||||
services:
|
||||
- postgresql
|
||||
- redis-server
|
||||
addons:
|
||||
postgresql: "9.4"
|
||||
language: python
|
||||
|
@ -18,6 +18,10 @@ django-filter
|
||||
# https://github.com/django-mptt/django-mptt
|
||||
django-mptt
|
||||
|
||||
# Django caching using Redis
|
||||
# https://github.com/niwinz/django-redis
|
||||
django-redis
|
||||
|
||||
# Abstraction models for rendering and paginating HTML tables
|
||||
# https://github.com/jieter/django-tables2
|
||||
django-tables2
|
||||
|
@ -1,9 +1,12 @@
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import permission_required
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db import transaction
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
|
||||
from extras.models import Graph, GRAPH_TYPE_PROVIDER
|
||||
@ -32,6 +35,7 @@ class ProviderListView(PermissionRequiredMixin, ObjectListView):
|
||||
class ProviderView(PermissionRequiredMixin, View):
|
||||
permission_required = 'circuits.view_provider'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, slug):
|
||||
|
||||
provider = get_object_or_404(Provider, slug=slug)
|
||||
@ -147,6 +151,7 @@ class CircuitListView(PermissionRequiredMixin, ObjectListView):
|
||||
class CircuitView(PermissionRequiredMixin, View):
|
||||
permission_required = 'circuits.view_circuit'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
circuit = get_object_or_404(Circuit.objects.select_related('provider', 'type', 'tenant__group'), pk=pk)
|
||||
|
@ -13,6 +13,8 @@ from django.urls import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.http import is_safe_url
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
|
||||
from circuits.models import Circuit
|
||||
@ -195,6 +197,7 @@ class SiteListView(PermissionRequiredMixin, ObjectListView):
|
||||
class SiteView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_site'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, slug):
|
||||
|
||||
site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=slug)
|
||||
@ -353,6 +356,7 @@ class RackElevationListView(PermissionRequiredMixin, View):
|
||||
"""
|
||||
permission_required = 'dcim.view_rack'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
racks = Rack.objects.select_related(
|
||||
@ -392,6 +396,7 @@ class RackElevationListView(PermissionRequiredMixin, View):
|
||||
class RackView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_rack'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
||||
@ -570,6 +575,7 @@ class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
|
||||
class DeviceTypeView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_devicetype'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
devicetype = get_object_or_404(DeviceType, pk=pk)
|
||||
@ -910,6 +916,7 @@ class DeviceListView(PermissionRequiredMixin, ObjectListView):
|
||||
class DeviceView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_device'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device.objects.select_related(
|
||||
@ -991,6 +998,7 @@ class DeviceView(PermissionRequiredMixin, View):
|
||||
class DeviceInventoryView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_device'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
@ -1012,6 +1020,7 @@ class DeviceInventoryView(PermissionRequiredMixin, View):
|
||||
class DeviceStatusView(PermissionRequiredMixin, View):
|
||||
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
@ -1025,6 +1034,7 @@ class DeviceStatusView(PermissionRequiredMixin, View):
|
||||
class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
||||
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
@ -1042,6 +1052,7 @@ class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
||||
class DeviceConfigView(PermissionRequiredMixin, View):
|
||||
permission_required = ('dcim.view_device', 'dcim.napalm_read')
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
@ -1279,6 +1290,7 @@ class PowerOutletBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
class InterfaceView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_interface'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
interface = get_object_or_404(Interface, pk=pk)
|
||||
@ -1499,6 +1511,7 @@ class DeviceBayDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
class DeviceBayPopulateView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.change_devicebay'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device_bay = get_object_or_404(DeviceBay, pk=pk)
|
||||
@ -1533,6 +1546,7 @@ class DeviceBayPopulateView(PermissionRequiredMixin, View):
|
||||
class DeviceBayDepopulateView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.change_devicebay'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device_bay = get_object_or_404(DeviceBay, pk=pk)
|
||||
@ -1672,6 +1686,7 @@ class CableListView(PermissionRequiredMixin, ObjectListView):
|
||||
class CableView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_cable'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
cable = get_object_or_404(Cable, pk=pk)
|
||||
@ -1687,6 +1702,7 @@ class CableTraceView(PermissionRequiredMixin, View):
|
||||
"""
|
||||
permission_required = 'dcim.view_cable'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, model, pk):
|
||||
|
||||
obj = get_object_or_404(model, pk=pk)
|
||||
@ -1726,6 +1742,7 @@ class CableCreateView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
# Parse initial data manually to avoid setting field values as lists
|
||||
@ -2042,6 +2059,7 @@ class VirtualChassisCreateView(PermissionRequiredMixin, View):
|
||||
class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
permission_required = 'dcim.change_virtualchassis'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
virtual_chassis = get_object_or_404(VirtualChassis, pk=pk)
|
||||
@ -2110,6 +2128,7 @@ class VirtualChassisDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
class VirtualChassisAddMemberView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
permission_required = 'dcim.change_virtualchassis'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
virtual_chassis = get_object_or_404(VirtualChassis, pk=pk)
|
||||
@ -2164,6 +2183,7 @@ class VirtualChassisAddMemberView(PermissionRequiredMixin, GetReturnURLMixin, Vi
|
||||
class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
permission_required = 'dcim.change_virtualchassis'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk, virtual_chassis__isnull=False)
|
||||
@ -2227,6 +2247,7 @@ class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
|
||||
class PowerPanelView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_powerpanel'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
powerpanel = get_object_or_404(PowerPanel.objects.select_related('site', 'rack_group'), pk=pk)
|
||||
@ -2296,6 +2317,7 @@ class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
|
||||
class PowerFeedView(PermissionRequiredMixin, View):
|
||||
permission_required = 'dcim.view_powerfeed'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
powerfeed = get_object_or_404(PowerFeed.objects.select_related('power_panel', 'rack'), pk=pk)
|
||||
|
@ -7,6 +7,8 @@ from django.db.models import Count, Q
|
||||
from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
from django_tables2 import RequestConfig
|
||||
|
||||
@ -41,6 +43,7 @@ class TagListView(ObjectListView):
|
||||
|
||||
class TagView(View):
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, slug):
|
||||
|
||||
tag = get_object_or_404(Tag, slug=slug)
|
||||
@ -108,6 +111,7 @@ class ConfigContextListView(PermissionRequiredMixin, ObjectListView):
|
||||
class ConfigContextView(PermissionRequiredMixin, View):
|
||||
permission_required = 'extras.view_configcontext'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
configcontext = get_object_or_404(ConfigContext, pk=pk)
|
||||
@ -155,6 +159,7 @@ class ObjectConfigContextView(View):
|
||||
object_class = None
|
||||
base_template = None
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
obj = get_object_or_404(self.object_class, pk=pk)
|
||||
@ -187,6 +192,7 @@ class ObjectChangeListView(PermissionRequiredMixin, ObjectListView):
|
||||
class ObjectChangeView(PermissionRequiredMixin, View):
|
||||
permission_required = 'extras.view_objectchange'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
objectchange = get_object_or_404(ObjectChange, pk=pk)
|
||||
@ -209,6 +215,7 @@ class ObjectChangeLogView(View):
|
||||
Present a history of changes made to a particular object.
|
||||
"""
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, model, **kwargs):
|
||||
|
||||
# Get object my model and kwargs (e.g. slug='foo')
|
||||
@ -282,6 +289,7 @@ class ReportListView(PermissionRequiredMixin, View):
|
||||
"""
|
||||
permission_required = 'extras.view_reportresult'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
reports = get_reports()
|
||||
@ -306,6 +314,7 @@ class ReportView(PermissionRequiredMixin, View):
|
||||
"""
|
||||
permission_required = 'extras.view_reportresult'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, name):
|
||||
|
||||
# Retrieve the Report by "<module>.<report>"
|
||||
|
@ -3,6 +3,8 @@ from django.conf import settings
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db.models import Count, Q
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
from django_tables2 import RequestConfig
|
||||
|
||||
@ -125,6 +127,7 @@ class VRFListView(PermissionRequiredMixin, ObjectListView):
|
||||
class VRFView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_vrf'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
vrf = get_object_or_404(VRF.objects.all(), pk=pk)
|
||||
@ -319,6 +322,7 @@ class AggregateListView(PermissionRequiredMixin, ObjectListView):
|
||||
class AggregateView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_aggregate'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
aggregate = get_object_or_404(Aggregate, pk=pk)
|
||||
@ -456,6 +460,7 @@ class PrefixListView(PermissionRequiredMixin, ObjectListView):
|
||||
class PrefixView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_prefix'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
prefix = get_object_or_404(Prefix.objects.select_related(
|
||||
@ -500,6 +505,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
||||
class PrefixPrefixesView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_prefix'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||
@ -543,6 +549,7 @@ class PrefixPrefixesView(PermissionRequiredMixin, View):
|
||||
class PrefixIPAddressesView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_prefix'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||
@ -643,6 +650,7 @@ class IPAddressListView(PermissionRequiredMixin, ObjectListView):
|
||||
class IPAddressView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_ipaddress'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
ipaddress = get_object_or_404(IPAddress.objects.select_related('vrf__tenant', 'tenant'), pk=pk)
|
||||
@ -726,6 +734,7 @@ class IPAddressAssignView(PermissionRequiredMixin, View):
|
||||
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
form = forms.IPAddressAssignForm()
|
||||
@ -838,6 +847,7 @@ class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
class VLANGroupVLANsView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_vlangroup'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
vlan_group = get_object_or_404(VLANGroup.objects.all(), pk=pk)
|
||||
@ -888,6 +898,7 @@ class VLANListView(PermissionRequiredMixin, ObjectListView):
|
||||
class VLANView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_vlan'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
vlan = get_object_or_404(VLAN.objects.select_related(
|
||||
@ -906,6 +917,7 @@ class VLANView(PermissionRequiredMixin, View):
|
||||
class VLANMembersView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_vlan'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
vlan = get_object_or_404(VLAN.objects.all(), pk=pk)
|
||||
@ -984,6 +996,7 @@ class ServiceListView(PermissionRequiredMixin, ObjectListView):
|
||||
class ServiceView(PermissionRequiredMixin, View):
|
||||
permission_required = 'ipam.view_service'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
service = get_object_or_404(Service, pk=pk)
|
||||
|
@ -25,6 +25,16 @@ DATABASE = {
|
||||
# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SECRET_KEY
|
||||
SECRET_KEY = ''
|
||||
|
||||
# Redis database settings. The Redis database is used for caching and background processing such as webhooks
|
||||
REDIS = {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'PASSWORD': '',
|
||||
'DATABASE': 0,
|
||||
'DEFAULT_TIMEOUT': 300,
|
||||
'SSL': False,
|
||||
}
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
@ -50,6 +60,18 @@ BANNER_LOGIN = ''
|
||||
# BASE_PATH = 'netbox/'
|
||||
BASE_PATH = ''
|
||||
|
||||
# The fraction of entries that are culled when CACHE_MAX_ENTRIES is reached. The actual ratio is 1 / CACHE_CULL_FREQUENCY,
|
||||
# so set CACHE_CULL_FREQUENCY to 2 to cull half the entries when CACHE_MAX_ENTRIES is reached. This setting should be an
|
||||
# integer and defaults to 3
|
||||
CACHE_CULL_FREQUENCY = 3
|
||||
|
||||
# Max number of entries (unique pages) to store in the cache at a time.
|
||||
CACHE_MAX_ENTRIES = 300
|
||||
|
||||
# Cache timeout in seconds. Set to `None` to enforce an infinate timeout. Set to 0 to dissable caching by immediatly
|
||||
# expiring keys. Defaults to 900 (15 minutes)
|
||||
CACHE_TIMEOUT = 900
|
||||
|
||||
# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90)
|
||||
CHANGELOG_RETENTION = 90
|
||||
|
||||
@ -133,16 +155,6 @@ PAGINATE_COUNT = 50
|
||||
# prefer IPv4 instead.
|
||||
PREFER_IPV4 = False
|
||||
|
||||
# Redis database settings (optional). A Redis database is required only if the webhooks backend is enabled.
|
||||
REDIS = {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'PASSWORD': '',
|
||||
'DATABASE': 0,
|
||||
'DEFAULT_TIMEOUT': 300,
|
||||
'SSL': False,
|
||||
}
|
||||
|
||||
# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of
|
||||
# this setting is derived from the installed location.
|
||||
# REPORTS_ROOT = '/opt/netbox/netbox/reports'
|
||||
|
@ -28,7 +28,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# Import required configuration parameters
|
||||
ALLOWED_HOSTS = DATABASE = SECRET_KEY = None
|
||||
for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']:
|
||||
for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY', 'REDIS']:
|
||||
try:
|
||||
globals()[setting] = getattr(configuration, setting)
|
||||
except AttributeError:
|
||||
@ -44,6 +44,9 @@ BANNER_TOP = getattr(configuration, 'BANNER_TOP', '')
|
||||
BASE_PATH = getattr(configuration, 'BASE_PATH', '')
|
||||
if BASE_PATH:
|
||||
BASE_PATH = BASE_PATH.strip('/') + '/' # Enforce trailing slash only
|
||||
CACHE_TIMEOUT = getattr(configuration, 'CACHE_TIMEOUT', 900)
|
||||
CACHE_MAX_ENTRIES = getattr(configuration, 'CACHE_MAX_ENTRIES', 300)
|
||||
CACHE_CULL_FREQUENCY = getattr(configuration, 'CACHE_CULL_FREQUENCY', 3)
|
||||
CHANGELOG_RETENTION = getattr(configuration, 'CHANGELOG_RETENTION', 90)
|
||||
CORS_ORIGIN_ALLOW_ALL = getattr(configuration, 'CORS_ORIGIN_ALLOW_ALL', False)
|
||||
CORS_ORIGIN_REGEX_WHITELIST = getattr(configuration, 'CORS_ORIGIN_REGEX_WHITELIST', [])
|
||||
@ -157,6 +160,7 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.humanize',
|
||||
'corsheaders',
|
||||
'django_redis',
|
||||
'debug_toolbar',
|
||||
'django_filters',
|
||||
'django_tables2',
|
||||
@ -218,6 +222,31 @@ TEMPLATES = [
|
||||
},
|
||||
]
|
||||
|
||||
# Caching
|
||||
if REDIS_SSL:
|
||||
REDIS_CACHE_CON_STRING = 'rediss://'
|
||||
else:
|
||||
REDIS_CACHE_CON_STRING = 'redis://'
|
||||
|
||||
if REDIS_PASSWORD:
|
||||
REDIS_CACHE_CON_STRING = '{}@{}'.format(REDIS_PASSWORD, REDIS_CACHE_CON_STRING)
|
||||
|
||||
REDIS_CACHE_CON_STRING = '{}{}:{}/{}'.format(REDIS_CACHE_CON_STRING, REDIS_HOST, REDIS_PORT, REDIS_DATABASE)
|
||||
CACHE_BACKEND = 'django_redis.cache.RedisCache'
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
"BACKEND": CACHE_BACKEND,
|
||||
"LOCATION": REDIS_CACHE_CON_STRING,
|
||||
'TIMEOUT': CACHE_TIMEOUT,
|
||||
"OPTIONS": {
|
||||
"CLIENT_CLASS": "django_redis.client.DefaultClient",
|
||||
"MAX_ENTRIES": CACHE_MAX_ENTRIES,
|
||||
"CULL_FREQUENCY": CACHE_CULL_FREQUENCY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# WSGI
|
||||
WSGI_APPLICATION = 'netbox.wsgi.application'
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
|
@ -1,7 +1,10 @@
|
||||
from collections import OrderedDict
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import Count, F
|
||||
from django.shortcuts import render
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.reverse import reverse
|
||||
@ -160,6 +163,7 @@ SEARCH_TYPES = OrderedDict((
|
||||
class HomeView(View):
|
||||
template_name = 'home.html'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
connected_consoleports = ConsolePort.objects.filter(
|
||||
@ -219,6 +223,7 @@ class HomeView(View):
|
||||
|
||||
class SearchView(View):
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
# No query
|
||||
@ -272,6 +277,7 @@ class APIRootView(APIView):
|
||||
def get_view_name(self):
|
||||
return "API Root"
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, format=None):
|
||||
|
||||
return Response(OrderedDict((
|
||||
|
@ -1,5 +1,6 @@
|
||||
import base64
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import permission_required, login_required
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
@ -7,6 +8,7 @@ from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
|
||||
from dcim.models import Device
|
||||
@ -80,6 +82,7 @@ class SecretListView(PermissionRequiredMixin, ObjectListView):
|
||||
class SecretView(PermissionRequiredMixin, View):
|
||||
permission_required = 'secrets.view_secret'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
secret = get_object_or_404(Secret, pk=pk)
|
||||
|
@ -1,6 +1,9 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
|
||||
from circuits.models import Circuit
|
||||
@ -66,6 +69,7 @@ class TenantListView(PermissionRequiredMixin, ObjectListView):
|
||||
class TenantView(PermissionRequiredMixin, View):
|
||||
permission_required = 'tenancy.view_tenant'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, slug):
|
||||
|
||||
tenant = get_object_or_404(Tenant, slug=slug)
|
||||
|
@ -6,6 +6,8 @@ from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import ManyToManyField
|
||||
from django.http import Http404
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from rest_framework.exceptions import APIException
|
||||
from rest_framework.permissions import BasePermission
|
||||
from rest_framework.relations import PrimaryKeyRelatedField, RelatedField
|
||||
@ -248,6 +250,20 @@ class ModelViewSet(_ModelViewSet):
|
||||
# Fall back to the hard-coded serializer class
|
||||
return self.serializer_class
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def list(self, *args, **kwargs):
|
||||
"""
|
||||
Call to super to allow for caching
|
||||
"""
|
||||
return super().list(*args, **kwargs)
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def retrieve(self, *args, **kwargs):
|
||||
"""
|
||||
Call to super to allow for caching
|
||||
"""
|
||||
return super().retrieve(*args, **kwargs)
|
||||
|
||||
|
||||
class FieldChoicesViewSet(ViewSet):
|
||||
"""
|
||||
@ -284,9 +300,11 @@ class FieldChoicesViewSet(ViewSet):
|
||||
})
|
||||
self._fields[key] = choices
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def list(self, request):
|
||||
return Response(self._fields)
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def retrieve(self, request, pk):
|
||||
if pk not in self._fields:
|
||||
raise Http404
|
||||
|
@ -17,6 +17,8 @@ from django.urls import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.http import is_safe_url
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.decorators.csrf import requires_csrf_token
|
||||
from django.views.defaults import ERROR_500_TEMPLATE_NAME
|
||||
from django.views.generic import View
|
||||
@ -106,6 +108,7 @@ class ObjectListView(View):
|
||||
|
||||
return csv_data
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request):
|
||||
|
||||
model = self.queryset.model
|
||||
@ -713,6 +716,7 @@ class ComponentCreateView(View):
|
||||
model_form = None
|
||||
template_name = None
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
parent = get_object_or_404(self.parent_model, pk=pk)
|
||||
|
@ -1,9 +1,12 @@
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.db import transaction
|
||||
from django.db.models import Count
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.views.generic import View
|
||||
|
||||
from dcim.models import Device, Interface
|
||||
@ -106,6 +109,7 @@ class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
||||
class ClusterView(PermissionRequiredMixin, View):
|
||||
permission_required = 'virtualization.view_cluster'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
cluster = get_object_or_404(Cluster, pk=pk)
|
||||
@ -168,6 +172,7 @@ class ClusterAddDevicesView(PermissionRequiredMixin, View):
|
||||
form = forms.ClusterAddDevicesForm
|
||||
template_name = 'virtualization/cluster_add_devices.html'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
cluster = get_object_or_404(Cluster, pk=pk)
|
||||
@ -263,6 +268,7 @@ class VirtualMachineListView(PermissionRequiredMixin, ObjectListView):
|
||||
class VirtualMachineView(PermissionRequiredMixin, View):
|
||||
permission_required = 'virtualization.view_virtualmachine'
|
||||
|
||||
@method_decorator(cache_page(settings.CACHE_TIMEOUT))
|
||||
def get(self, request, pk):
|
||||
|
||||
virtualmachine = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk)
|
||||
|
@ -3,6 +3,7 @@ django-cors-headers==2.5.2
|
||||
django-debug-toolbar==1.11
|
||||
django-filter==2.1.0
|
||||
django-mptt==0.9.1
|
||||
django-redis==4.5.0
|
||||
django-tables2==2.0.6
|
||||
django-taggit==1.1.0
|
||||
django-taggit-serializer==0.1.7
|
||||
|
Loading…
Reference in New Issue
Block a user