mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 03:56:53 -06:00
commit
3ffe36e5ed
@ -1,7 +1,3 @@
|
|||||||
**The [2017 NetBox User Survey](https://goo.gl/forms/75HnNS2iE0Y1hVFH3) is open!** Please consider taking a moment to respond. Your feedback helps shape the pace and focus of NetBox development. The survey will remain open until 2017-03-31. Results will be published on the mailing list.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers.
|
NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers.
|
||||||
|
@ -1481,7 +1481,7 @@ class InterfaceConnectionForm(BootstrapMixin, forms.ModelForm):
|
|||||||
super(InterfaceConnectionForm, self).__init__(*args, **kwargs)
|
super(InterfaceConnectionForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Initialize interface A choices
|
# Initialize interface A choices
|
||||||
device_a_interfaces = Interface.objects.filter(device=device_a).exclude(
|
device_a_interfaces = Interface.objects.order_naturally().filter(device=device_a).exclude(
|
||||||
form_factor__in=VIRTUAL_IFACE_TYPES
|
form_factor__in=VIRTUAL_IFACE_TYPES
|
||||||
).select_related(
|
).select_related(
|
||||||
'circuit_termination', 'connected_as_a', 'connected_as_b'
|
'circuit_termination', 'connected_as_a', 'connected_as_b'
|
||||||
|
@ -1450,9 +1450,10 @@ def interfaceconnection_add(request, pk):
|
|||||||
))
|
))
|
||||||
if '_addanother' in request.POST:
|
if '_addanother' in request.POST:
|
||||||
base_url = reverse('dcim:interfaceconnection_add', kwargs={'pk': device.pk})
|
base_url = reverse('dcim:interfaceconnection_add', kwargs={'pk': device.pk})
|
||||||
|
device_b = interfaceconnection.interface_b.device
|
||||||
params = urlencode({
|
params = urlencode({
|
||||||
'rack_b': interfaceconnection.interface_b.device.rack.pk,
|
'rack_b': device_b.rack.pk if device_b.rack else '',
|
||||||
'device_b': interfaceconnection.interface_b.device.pk,
|
'device_b': device_b.pk,
|
||||||
})
|
})
|
||||||
return HttpResponseRedirect('{}?{}'.format(base_url, params))
|
return HttpResponseRedirect('{}?{}'.format(base_url, params))
|
||||||
else:
|
else:
|
||||||
|
@ -56,13 +56,15 @@ ACTION_EDIT = 3
|
|||||||
ACTION_BULK_EDIT = 4
|
ACTION_BULK_EDIT = 4
|
||||||
ACTION_DELETE = 5
|
ACTION_DELETE = 5
|
||||||
ACTION_BULK_DELETE = 6
|
ACTION_BULK_DELETE = 6
|
||||||
|
ACTION_BULK_CREATE = 7
|
||||||
ACTION_CHOICES = (
|
ACTION_CHOICES = (
|
||||||
(ACTION_CREATE, 'created'),
|
(ACTION_CREATE, 'created'),
|
||||||
|
(ACTION_BULK_CREATE, 'bulk created'),
|
||||||
(ACTION_IMPORT, 'imported'),
|
(ACTION_IMPORT, 'imported'),
|
||||||
(ACTION_EDIT, 'modified'),
|
(ACTION_EDIT, 'modified'),
|
||||||
(ACTION_BULK_EDIT, 'bulk edited'),
|
(ACTION_BULK_EDIT, 'bulk edited'),
|
||||||
(ACTION_DELETE, 'deleted'),
|
(ACTION_DELETE, 'deleted'),
|
||||||
(ACTION_BULK_DELETE, 'bulk deleted')
|
(ACTION_BULK_DELETE, 'bulk deleted'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -328,6 +330,9 @@ class UserActionManager(models.Manager):
|
|||||||
def log_import(self, user, content_type, message=''):
|
def log_import(self, user, content_type, message=''):
|
||||||
self.log_bulk_action(user, content_type, ACTION_IMPORT, message)
|
self.log_bulk_action(user, content_type, ACTION_IMPORT, message)
|
||||||
|
|
||||||
|
def log_bulk_create(self, user, content_type, message=''):
|
||||||
|
self.log_bulk_action(user, content_type, ACTION_BULK_CREATE, message)
|
||||||
|
|
||||||
def log_bulk_edit(self, user, content_type, message=''):
|
def log_bulk_edit(self, user, content_type, message=''):
|
||||||
self.log_bulk_action(user, content_type, ACTION_BULK_EDIT, message)
|
self.log_bulk_action(user, content_type, ACTION_BULK_EDIT, message)
|
||||||
|
|
||||||
@ -358,7 +363,7 @@ class UserAction(models.Model):
|
|||||||
return u'{} {} {}'.format(self.user, self.get_action_display(), self.content_type)
|
return u'{} {} {}'.format(self.user, self.get_action_display(), self.content_type)
|
||||||
|
|
||||||
def icon(self):
|
def icon(self):
|
||||||
if self.action in [ACTION_CREATE, ACTION_IMPORT]:
|
if self.action in [ACTION_CREATE, ACTION_BULK_CREATE, ACTION_IMPORT]:
|
||||||
return mark_safe('<i class="glyphicon glyphicon-plus text-success"></i>')
|
return mark_safe('<i class="glyphicon glyphicon-plus text-success"></i>')
|
||||||
elif self.action in [ACTION_EDIT, ACTION_BULK_EDIT]:
|
elif self.action in [ACTION_EDIT, ACTION_BULK_EDIT]:
|
||||||
return mark_safe('<i class="glyphicon glyphicon-pencil text-warning"></i>')
|
return mark_safe('<i class="glyphicon glyphicon-pencil text-warning"></i>')
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
import netaddr
|
import netaddr
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@ -295,7 +296,12 @@ def aggregate(request, pk):
|
|||||||
prefix_table = tables.PrefixTable(child_prefixes)
|
prefix_table = tables.PrefixTable(child_prefixes)
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
prefix_table.base_columns['pk'].visible = True
|
prefix_table.base_columns['pk'].visible = True
|
||||||
RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(prefix_table)
|
|
||||||
|
paginate = {
|
||||||
|
'klass': EnhancedPaginator,
|
||||||
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
|
}
|
||||||
|
RequestConfig(request, paginate).configure(prefix_table)
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
# Compile permissions list for rendering the object table
|
||||||
permissions = {
|
permissions = {
|
||||||
@ -427,7 +433,12 @@ def prefix(request, pk):
|
|||||||
child_prefix_table = tables.PrefixTable(child_prefixes)
|
child_prefix_table = tables.PrefixTable(child_prefixes)
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
child_prefix_table.base_columns['pk'].visible = True
|
child_prefix_table.base_columns['pk'].visible = True
|
||||||
RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(child_prefix_table)
|
|
||||||
|
paginate = {
|
||||||
|
'klass': EnhancedPaginator,
|
||||||
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
|
}
|
||||||
|
RequestConfig(request, paginate).configure(child_prefix_table)
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
# Compile permissions list for rendering the object table
|
||||||
permissions = {
|
permissions = {
|
||||||
@ -500,7 +511,12 @@ def prefix_ipaddresses(request, pk):
|
|||||||
ip_table = tables.IPAddressTable(ipaddresses)
|
ip_table = tables.IPAddressTable(ipaddresses)
|
||||||
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
|
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
|
||||||
ip_table.base_columns['pk'].visible = True
|
ip_table.base_columns['pk'].visible = True
|
||||||
RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(ip_table)
|
|
||||||
|
paginate = {
|
||||||
|
'klass': EnhancedPaginator,
|
||||||
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
|
}
|
||||||
|
RequestConfig(request, paginate).configure(ip_table)
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
# Compile permissions list for rendering the object table
|
||||||
permissions = {
|
permissions = {
|
||||||
|
@ -12,7 +12,7 @@ except ImportError:
|
|||||||
"the documentation.")
|
"the documentation.")
|
||||||
|
|
||||||
|
|
||||||
VERSION = '1.9.3'
|
VERSION = '1.9.4'
|
||||||
|
|
||||||
# Import local configuration
|
# Import local configuration
|
||||||
for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']:
|
for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']:
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<div id="navbar" class="navbar-collapse collapse">
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
{% if request.user.is_authenticated or not settings.LOGIN_REQUIRED %}
|
{% if request.user.is_authenticated or not settings.LOGIN_REQUIRED %}
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="dropdown{% if request.path|startswith:'/dcim/sites/' or 'tenancy' in request.path %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/dcim/sites/,/dcim/regions/,/tenancy/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Organization <span class="caret"></span></a>
|
<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">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'dcim:site_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Sites</a></li>
|
<li><a href="{% url 'dcim:site_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Sites</a></li>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/dcim/rack' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/dcim/rack' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Racks <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Racks <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'dcim:rack_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Racks</a></li>
|
<li><a href="{% url 'dcim:rack_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Racks</a></li>
|
||||||
@ -74,7 +74,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/dcim/device' or request.path|startswith:'/dcim/manufacturers/' or request.path|startswith:'/dcim/platforms/' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/dcim/device,/dcim/manufacturers/,/dcim/platforms/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Devices <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Devices <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'dcim:device_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Devices</a></li>
|
<li><a href="{% url 'dcim:device_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Devices</a></li>
|
||||||
@ -110,7 +110,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/dcim/console-connections/' or request.path|startswith:'/dcim/power-connections/' or request.path|startswith:'/dcim/interface-connections/' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/dcim/console-connections/,/dcim/power-connections/,/dcim/interface-connections/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Connections <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Connections <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'dcim:console_connections_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Console Connections</a></li>
|
<li><a href="{% url 'dcim:console_connections_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Console Connections</a></li>
|
||||||
@ -133,7 +133,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/ipam/' and not request.path|startswith:'/ipam/vlan' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/ipam/' and not request.path|contains:'/ipam/vlan' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">IP Space <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">IP Space <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'ipam:ipaddress_list' %}"><i class="fa fa-search" aria-hidden="true"></i> IP Addresses</a></li>
|
<li><a href="{% url 'ipam:ipaddress_list' %}"><i class="fa fa-search" aria-hidden="true"></i> IP Addresses</a></li>
|
||||||
@ -179,7 +179,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/ipam/vlan' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/ipam/vlan' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">VLANs <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">VLANs <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'ipam:vlan_list' %}"><i class="fa fa-search" aria-hidden="true"></i> VLANs</a></li>
|
<li><a href="{% url 'ipam:vlan_list' %}"><i class="fa fa-search" aria-hidden="true"></i> VLANs</a></li>
|
||||||
@ -199,7 +199,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown{% if request.path|startswith:'/circuits/' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/circuits/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Circuits <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Circuits <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'circuits:provider_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Providers</a></li>
|
<li><a href="{% url 'circuits:provider_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Providers</a></li>
|
||||||
@ -223,7 +223,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li class="dropdown{% if request.path|startswith:'/secrets/' %} active{% endif %}">
|
<li class="dropdown{% if request.path|contains:'/secrets/' %} active{% endif %}">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Secrets <span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Secrets <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'secrets:secret_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Secrets</a></li>
|
<li><a href="{% url 'secrets:secret_list' %}"><i class="fa fa-search" aria-hidden="true"></i> Secrets</a></li>
|
||||||
|
@ -43,12 +43,14 @@
|
|||||||
{% render_field form.set_as_primary %}
|
{% render_field form.set_as_primary %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if form.custom_fields %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>Custom Fields</strong></div>
|
<div class="panel-heading"><strong>Custom Fields</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% render_custom_fields form %}
|
{% render_custom_fields form %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-9 col-md-offset-3">
|
<div class="col-md-9 col-md-offset-3">
|
||||||
<button type="submit" name="_create" class="btn btn-primary">Create</button>
|
<button type="submit" name="_create" class="btn btn-primary">Create</button>
|
||||||
|
@ -216,12 +216,12 @@
|
|||||||
<small>{{ resv.user }} · {{ resv.created }}</small>
|
<small>{{ resv.user }} · {{ resv.created }}</small>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
{% if perms.change_rackreservation %}
|
{% if perms.dcim.change_rackreservation %}
|
||||||
<a href="{% url 'dcim:rackreservation_edit' pk=resv.pk %}" class="btn btn-warning btn-xs" title="Edit reservation">
|
<a href="{% url 'dcim:rackreservation_edit' pk=resv.pk %}" class="btn btn-warning btn-xs" title="Edit reservation">
|
||||||
<i class="glyphicon glyphicon-pencil" aria-hidden="true"></i>
|
<i class="glyphicon glyphicon-pencil" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.delete_rackreservation %}
|
{% if perms.dcim.delete_rackreservation %}
|
||||||
<a href="{% url 'dcim:rackreservation_delete' pk=resv.pk %}" class="btn btn-danger btn-xs" title="Delete reservation">
|
<a href="{% url 'dcim:rackreservation_delete' pk=resv.pk %}" class="btn btn-danger btn-xs" title="Delete reservation">
|
||||||
<i class="glyphicon glyphicon-trash" aria-hidden="true"></i>
|
<i class="glyphicon glyphicon-trash" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -5,7 +5,8 @@ from django.core.paginator import Paginator, Page
|
|||||||
class EnhancedPaginator(Paginator):
|
class EnhancedPaginator(Paginator):
|
||||||
|
|
||||||
def __init__(self, object_list, per_page, **kwargs):
|
def __init__(self, object_list, per_page, **kwargs):
|
||||||
per_page = getattr(settings, 'PAGINATE_COUNT', 50)
|
if not isinstance(per_page, int) or per_page < 1:
|
||||||
|
per_page = getattr(settings, 'PAGINATE_COUNT', 50)
|
||||||
super(EnhancedPaginator, self).__init__(object_list, per_page, **kwargs)
|
super(EnhancedPaginator, self).__init__(object_list, per_page, **kwargs)
|
||||||
|
|
||||||
def _get_page(self, *args, **kwargs):
|
def _get_page(self, *args, **kwargs):
|
||||||
|
@ -45,11 +45,11 @@ def gfm(value):
|
|||||||
|
|
||||||
|
|
||||||
@register.filter()
|
@register.filter()
|
||||||
def startswith(value, arg):
|
def contains(value, arg):
|
||||||
"""
|
"""
|
||||||
Test whether a string starts with the given argument
|
Test whether a value contains any of a given set of strings. `arg` should be a comma-separated list of strings.
|
||||||
"""
|
"""
|
||||||
return str(value).startswith(arg)
|
return any(s in value for s in arg.split(','))
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from django_tables2 import RequestConfig
|
from django_tables2 import RequestConfig
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
@ -101,7 +102,13 @@ class ObjectListView(View):
|
|||||||
table = self.table(self.queryset)
|
table = self.table(self.queryset)
|
||||||
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
||||||
table.base_columns['pk'].visible = True
|
table.base_columns['pk'].visible = True
|
||||||
RequestConfig(request, paginate={'klass': EnhancedPaginator}).configure(table)
|
|
||||||
|
# Apply the request context
|
||||||
|
paginate = {
|
||||||
|
'klass': EnhancedPaginator,
|
||||||
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
|
}
|
||||||
|
RequestConfig(request, paginate).configure(table)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'table': table,
|
'table': table,
|
||||||
@ -327,7 +334,9 @@ class BulkAddView(View):
|
|||||||
form.add_error(None, e)
|
form.add_error(None, e)
|
||||||
|
|
||||||
if not form.errors:
|
if not form.errors:
|
||||||
messages.success(request, u"Added {} {}.".format(len(new_objs), self.model._meta.verbose_name_plural))
|
msg = u"Added {} {}".format(len(new_objs), self.model._meta.verbose_name_plural)
|
||||||
|
messages.success(request, msg)
|
||||||
|
UserAction.objects.log_bulk_create(request.user, ContentType.objects.get_for_model(self.model), msg)
|
||||||
if '_addanother' in request.POST:
|
if '_addanother' in request.POST:
|
||||||
return redirect(request.path)
|
return redirect(request.path)
|
||||||
return redirect(self.default_return_url)
|
return redirect(self.default_return_url)
|
||||||
|
Loading…
Reference in New Issue
Block a user