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 = [