diff --git a/src/ralph/admin/filters.py b/src/ralph/admin/filters.py
index 6a4bcf0719..a0ddcc0685 100644
--- a/src/ralph/admin/filters.py
+++ b/src/ralph/admin/filters.py
@@ -274,10 +274,25 @@ def choices(self, cl):
},)
-class TagsListFilter(TextListFilter):
- """Filter by taggit tags."""
- separators = " and ".join(list(SEARCH_AND_SEPARATORS_REGEX.pattern[1:-1]))
- multiple = False
+class TagsListFilter(SimpleListFilter):
+
+ title = _('Tags')
+ parameter_name = 'tags'
+ separators = ' or '.join(list(SEARCH_AND_SEPARATORS_REGEX.pattern[1:-1]))
+ template = 'admin/filters/text_filter.html'
+
+ def lookups(self, request, model_admin):
+ return (
+ (1, _('Tags')),
+ )
+
+ def choices(self, cl):
+ yield {
+ 'current_value': self.value() or '',
+ 'parameter_name': self.parameter_name,
+ 'separators': self.separators,
+ 'multiple': True,
+ }
def queryset(self, request, queryset):
if self.value():
@@ -471,7 +486,7 @@ def lookups(self, request, model_admin):
def choices(self, cl):
yield {
- 'selected': self.value() or False,
+ 'current_value': self.value() or '',
'parameter_name': self.parameter_name,
}
diff --git a/src/ralph/admin/templates/admin/filter.html b/src/ralph/admin/templates/admin/filter.html
deleted file mode 100644
index 62d2e0cca2..0000000000
--- a/src/ralph/admin/templates/admin/filter.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load i18n %}
-
- {% blocktrans with filter_title=title %}
- By {{ filter_title }}
- {% endblocktrans %}
-
-
diff --git a/src/ralph/admin/templates/admin/filters/text_filter.html b/src/ralph/admin/templates/admin/filters/text_filter.html
index 46172c05ee..d681667597 100644
--- a/src/ralph/admin/templates/admin/filters/text_filter.html
+++ b/src/ralph/admin/templates/admin/filters/text_filter.html
@@ -1,7 +1,9 @@
{% extends "admin/filters/_filter_base.html" %}
{% block filter_after_header %}
-
+ {% if i.separators %}
+
+ {% endif %}
{% endblock %}
{% block filter_choices %}
diff --git a/src/ralph/admin/templates/admin/includes/javascripts.html b/src/ralph/admin/templates/admin/includes/javascripts.html
index 99778d3f94..dd1e978780 100644
--- a/src/ralph/admin/templates/admin/includes/javascripts.html
+++ b/src/ralph/admin/templates/admin/includes/javascripts.html
@@ -42,7 +42,11 @@
$clone.find('select').each(function(index, item) {
$(item).val($original_selects.eq(index).val());
});
- $clone.appendTo($form);
+ $('input, select', $clone).each(function(i, item) {
+ var $item = $(item);
+ if($item.val())
+ $item.appendTo($form);
+ });
$form[0].submit();
});
diff --git a/src/ralph/admin/tests/tests_filters.py b/src/ralph/admin/tests/tests_filters.py
index 1ef781d177..e4e62233df 100644
--- a/src/ralph/admin/tests/tests_filters.py
+++ b/src/ralph/admin/tests/tests_filters.py
@@ -182,24 +182,20 @@ def test_text_filter_contains(self):
def test_tags_filter(self):
tags_filter = TagsListFilter(
- field=DataCenterAsset._meta.get_field('tags'),
request=None,
params={'tags': 'tag1 & tag2'},
model=DataCenterAsset,
model_admin=DataCenterAssetAdmin,
- field_path='tags'
)
queryset = tags_filter.queryset(None, DataCenterAsset.objects.all())
self.assertEqual(len(queryset), 1)
tags_filter = TagsListFilter(
- field=DataCenterAsset._meta.get_field('tags'),
request=None,
params={'tags': 'tag1'},
model=DataCenterAsset,
model_admin=DataCenterAssetAdmin,
- field_path='tags'
)
queryset = tags_filter.queryset(None, DataCenterAsset.objects.all())
diff --git a/src/ralph/back_office/admin.py b/src/ralph/back_office/admin.py
index 7858e91d38..88a1b454f1 100644
--- a/src/ralph/back_office/admin.py
+++ b/src/ralph/back_office/admin.py
@@ -108,7 +108,7 @@ class BackOfficeAssetAdmin(
'user__company', 'user__department', 'user__employee_id',
'property_of', 'invoice_no', 'invoice_date', 'order_no', 'provider',
'budget_info', 'depreciation_rate', 'depreciation_end_date',
- 'force_depreciation', LiquidatedStatusFilter, ('tags', TagsListFilter)
+ 'force_depreciation', LiquidatedStatusFilter, TagsListFilter
]
date_hierarchy = 'created'
list_select_related = [
diff --git a/src/ralph/data_center/admin.py b/src/ralph/data_center/admin.py
index 777d8540a0..0820820e21 100644
--- a/src/ralph/data_center/admin.py
+++ b/src/ralph/data_center/admin.py
@@ -233,8 +233,16 @@ class DataCenterAssetAdmin(
show_transition_history = True
resource_class = resources.DataCenterAssetResource
list_display = [
- 'hostname', 'status', 'barcode', 'model', 'sn', 'invoice_date',
- 'invoice_no', 'show_location', 'service_env',
+ 'hostname',
+ 'status',
+ 'barcode',
+ 'model',
+ 'sn',
+ 'invoice_date',
+ 'invoice_no',
+ 'show_location',
+ 'service_env',
+ 'configuration_path',
]
multiadd_summary_fields = list_display + ['rack']
one_of_mulitvalue_required = ['sn', 'barcode']
@@ -253,15 +261,20 @@ class DataCenterAssetAdmin(
'depreciation_end_date', 'force_depreciation', 'remarks',
'budget_info', 'rack', 'rack__server_room',
'rack__server_room__data_center', 'position', 'property_of',
- LiquidatedStatusFilter, IPFilter,
- ('tags', TagsListFilter)
+ LiquidatedStatusFilter, IPFilter, TagsListFilter
]
date_hierarchy = 'created'
list_select_related = [
- 'model', 'model__manufacturer', 'model__category', 'rack',
- 'rack__server_room', 'rack__server_room__data_center', 'service_env',
- 'service_env__service', 'service_env__environment',
- 'configuration_path__module',
+ 'model',
+ 'model__manufacturer',
+ 'model__category',
+ 'rack',
+ 'rack__server_room',
+ 'rack__server_room__data_center',
+ 'service_env',
+ 'service_env__service',
+ 'service_env__environment',
+ 'configuration_path',
]
raw_id_fields = [
'model', 'rack', 'service_env', 'parent', 'budget_info',
diff --git a/src/ralph/data_center/api/views.py b/src/ralph/data_center/api/views.py
index f168483e91..38dad751d4 100644
--- a/src/ralph/data_center/api/views.py
+++ b/src/ralph/data_center/api/views.py
@@ -48,7 +48,8 @@ class DataCenterAssetViewSet(BaseObjectViewSetMixin, RalphAPIViewSet):
select_related = DataCenterAssetAdmin.list_select_related + [
'service_env', 'service_env__service', 'service_env__environment',
'rack', 'rack__server_room', 'rack__server_room__data_center',
- 'property_of', 'budget_info', 'content_type'
+ 'property_of', 'budget_info', 'content_type',
+ 'configuration_path__module'
]
prefetch_related = base_object_descendant_prefetch_related + [
'connections',
diff --git a/src/ralph/data_center/migrations/0018_auto_20160729_1401.py b/src/ralph/data_center/migrations/0018_auto_20160729_1401.py
new file mode 100644
index 0000000000..58ce3857a9
--- /dev/null
+++ b/src/ralph/data_center/migrations/0018_auto_20160729_1401.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('data_center', '0017_auto_20160719_1530'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='rack',
+ name='server_room',
+ field=models.ForeignKey(verbose_name='server room', null=True, to='data_center.ServerRoom'),
+ ),
+ ]
diff --git a/src/ralph/data_center/models/physical.py b/src/ralph/data_center/models/physical.py
index 47c4c02f58..bff24c34a6 100644
--- a/src/ralph/data_center/models/physical.py
+++ b/src/ralph/data_center/models/physical.py
@@ -112,6 +112,11 @@ def __str__(self):
return self.name
+class ServerRoomManager(models.Manager):
+ def get_queryset(self):
+ return super().get_queryset().select_related('data_center')
+
+
class ServerRoom(NamedMixin.NonUnique, models.Model):
_allow_in_dashboard = True
@@ -126,6 +131,7 @@ class ServerRoom(NamedMixin.NonUnique, models.Model):
verbose_name=_('visualization grid rows number'),
default=20,
)
+ objects = ServerRoomManager()
def __str__(self):
return '{} ({})'.format(self.name, self.data_center.name)
@@ -172,7 +178,7 @@ class Rack(AdminAbsoluteUrlMixin, NamedMixin.NonUnique, models.Model):
server_room = models.ForeignKey(
ServerRoom, verbose_name=_('server room'),
null=True,
- blank=True,
+ blank=False,
)
server_room._autocomplete = False
server_room._filter_title = _('server room')
diff --git a/src/ralph/data_center/tests/test_view.py b/src/ralph/data_center/tests/test_view.py
index e69de29bb2..298f0053f1 100644
--- a/src/ralph/data_center/tests/test_view.py
+++ b/src/ralph/data_center/tests/test_view.py
@@ -0,0 +1,16 @@
+from django.core.urlresolvers import reverse
+from django.test import RequestFactory, TestCase
+
+from ralph.data_center.tests.factories import DataCenterAssetFullFactory
+from ralph.tests.mixins import ClientMixin, ReloadUrlsMixin
+
+
+class DataCentrAssetViewTest(ClientMixin, TestCase):
+ def test_changelist_view(self):
+ self.login_as_user()
+ DataCenterAssetFullFactory.create_batch(10)
+ with self.assertNumQueries(16):
+ self.client.get(
+ reverse('admin:data_center_datacenterasset_changelist'),
+ )
+
diff --git a/src/ralph/lib/mixins/models.py b/src/ralph/lib/mixins/models.py
index e0b57fa61f..c11450b47b 100644
--- a/src/ralph/lib/mixins/models.py
+++ b/src/ralph/lib/mixins/models.py
@@ -66,9 +66,13 @@ def save(self, update_last_seen=False, *args, **kwargs):
class AdminAbsoluteUrlMixin(object):
def get_absolute_url(self):
+ opts = self._meta
+ # support for proxy
+ if opts.proxy:
+ opts = opts.concrete_model._meta
return reverse(
'admin:{}_{}_change'.format(
- self._meta.app_label, self._meta.model_name
+ opts.app_label, opts.model_name
), args=(self.pk,)
)
diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py
index 5986888bfc..3ad0055f3e 100644
--- a/src/ralph/lib/polymorphic/models.py
+++ b/src/ralph/lib/polymorphic/models.py
@@ -149,6 +149,8 @@ def __new__(cls, name, bases, attrs):
for polymorphic_class in base_polymorphic:
# Set is_polymorphic flag for classes that use polymorphic
polymorphic_class.is_polymorphic = True
+ if new_class._meta.proxy:
+ continue
try:
polymorphic_class._polymorphic_descendants.append(new_class)
except AttributeError:
diff --git a/src/ralph/licences/admin.py b/src/ralph/licences/admin.py
index 2d9471294a..0cc89ef954 100644
--- a/src/ralph/licences/admin.py
+++ b/src/ralph/licences/admin.py
@@ -69,7 +69,7 @@ class LicenceAdmin(
'niw', 'sn', 'remarks', 'software', 'property_of',
'licence_type', 'valid_thru', 'order_no', 'invoice_no', 'invoice_date',
'budget_info', 'manufacturer', 'region', 'office_infrastructure',
- ('tags', TagsListFilter)
+ TagsListFilter
]
date_hierarchy = 'created'
list_display = [
diff --git a/src/ralph/supports/admin.py b/src/ralph/supports/admin.py
index 9811cb5b57..b450b6c267 100644
--- a/src/ralph/supports/admin.py
+++ b/src/ralph/supports/admin.py
@@ -44,7 +44,7 @@ class SupportAdmin(
list_filter = [
'contract_id', 'name', 'serial_no', 'price', 'remarks', 'description',
'support_type', 'budget_info', 'date_from', 'date_to', 'property_of',
- ('tags', TagsListFilter)
+ TagsListFilter
]
date_hierarchy = 'created'
list_display = [
diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py
index 2e698c7a2b..ea83834bd4 100644
--- a/src/ralph/virtual/admin.py
+++ b/src/ralph/virtual/admin.py
@@ -70,7 +70,7 @@ class VirtualServerAdmin(
search_fields = ['hostname', 'sn']
list_filter = [
'sn', 'hostname', 'service_env', IPFilter,
- 'parent', ('tags', TagsListFilter),
+ 'parent', TagsListFilter,
('configuration_path__module', TreeRelatedAutocompleteFilterWithDescendants) # noqa
]
list_display = [