From cf4c6f6e3d2ea83635ded8ca5a84288f86e2c547 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Thu, 25 Apr 2024 12:07:18 +0200 Subject: [PATCH 01/45] Update to Django 1.9 --- requirements/base.txt | 7 +++---- src/ralph/access_cards/admin.py | 3 ++- src/ralph/accessories/admin.py | 3 ++- src/ralph/accessories/models.py | 2 +- src/ralph/accounts/admin.py | 5 +++-- src/ralph/accounts/models.py | 2 +- src/ralph/admin/__init__.py | 21 -------------------- src/ralph/admin/apps.py | 3 ++- src/ralph/admin/autocomplete.py | 4 ++-- src/ralph/admin/m2m.py | 2 +- src/ralph/admin/mixins.py | 5 +++-- src/ralph/admin/widgets.py | 4 ++-- src/ralph/assets/admin.py | 5 +++-- src/ralph/assets/models/assets.py | 2 +- src/ralph/assets/models/base.py | 2 +- src/ralph/assets/views.py | 2 +- src/ralph/attachments/models.py | 4 ++-- src/ralph/back_office/admin.py | 7 ++++--- src/ralph/configuration_management/models.py | 2 +- src/ralph/dashboards/admin.py | 3 ++- src/ralph/data_center/admin.py | 6 ++++-- src/ralph/data_center/forms.py | 2 +- src/ralph/data_importer/models.py | 4 ++-- src/ralph/deployment/admin.py | 3 ++- src/ralph/dhcp/admin.py | 5 +++-- src/ralph/domains/admin.py | 3 ++- src/ralph/domains/models/domains.py | 2 +- src/ralph/lib/custom_fields/admin.py | 3 ++- src/ralph/lib/custom_fields/fields.py | 13 ++++++++---- src/ralph/lib/custom_fields/models.py | 4 ++-- src/ralph/lib/mixins/fields.py | 6 +++--- src/ralph/lib/permissions/__init__.py | 9 --------- src/ralph/lib/permissions/api.py | 2 +- src/ralph/lib/permissions/apps.py | 1 + src/ralph/lib/table/__init__.py | 3 --- src/ralph/lib/template/loaders.py | 4 ++-- src/ralph/lib/transitions/admin.py | 3 ++- src/ralph/lib/transitions/checks.py | 2 +- src/ralph/lib/transitions/views.py | 4 ++-- src/ralph/licences/admin.py | 3 ++- src/ralph/licences/models.py | 4 ++-- src/ralph/networks/admin.py | 5 +++-- src/ralph/networks/forms.py | 2 +- src/ralph/networks/views.py | 4 ++-- src/ralph/operations/admin.py | 3 ++- src/ralph/reports/admin.py | 3 ++- src/ralph/security/models.py | 2 +- src/ralph/security/views.py | 3 ++- src/ralph/settings/base.py | 12 +++++------ src/ralph/settings/local.template | 4 ++-- src/ralph/settings/test.py | 2 +- src/ralph/sim_cards/admin.py | 3 ++- src/ralph/ssl_certificates/admin.py | 3 ++- src/ralph/supports/admin.py | 3 ++- src/ralph/tests/mixins.py | 2 +- src/ralph/trade_marks/admin.py | 3 ++- src/ralph/urls/base.py | 2 +- src/ralph/virtual/admin.py | 7 ++++--- src/ralph/virtual/models.py | 4 ++-- 59 files changed, 119 insertions(+), 122 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index a1a56cad95..2f76f21cb2 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,6 +1,6 @@ -r openstack.txt -r hermes.txt -Django==1.8.19 +Django==1.9.13 dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 @@ -8,13 +8,12 @@ django-import-export==0.4.2 django-money==0.15.1 py-moneyed==1.2 django-mptt==0.8.7 -django-reversion==1.8.6 +django-reversion==1.10.0 django-rq==2.0 django-sitetree==1.7.0 -django-taggit==0.17.1 +django-taggit==0.18.1 django-taggit-serializer==0.1.5 django-threadlocals==0.8 -django-transaction-hooks==0.2 # it's merged to Django 1.9 - remove this when Django version will be bumped to 1.9 django-cryptography==0.3 djangorestframework==3.2.2 djangorestframework_xml==1.2.0 diff --git a/src/ralph/access_cards/admin.py b/src/ralph/access_cards/admin.py index 7cc76b4abb..f56105b955 100644 --- a/src/ralph/access_cards/admin.py +++ b/src/ralph/access_cards/admin.py @@ -1,7 +1,8 @@ from django.utils.translation import ugettext_lazy as _ from ralph.access_cards.models import AccessCard, AccessZone -from ralph.admin import RalphAdmin, RalphMPTTAdmin, register +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin +from ralph.admin.decorators import register from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/accessories/admin.py b/src/ralph/accessories/admin.py index 6afc1ace73..4fa10d5721 100644 --- a/src/ralph/accessories/admin.py +++ b/src/ralph/accessories/admin.py @@ -1,7 +1,8 @@ from django.utils.translation import ugettext_lazy as _ from ralph.accessories.models import Accessory, AccessoryUser -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/accessories/models.py b/src/ralph/accessories/models.py index a1eb6a0ec9..9f582b9e0d 100644 --- a/src/ralph/accessories/models.py +++ b/src/ralph/accessories/models.py @@ -213,7 +213,7 @@ def free(self): free._permission_field = 'number_bought' -@reversion.register() +# @reversion.register() class AccessoryUser(models.Model): accessory = models.ForeignKey(Accessory) user = models.ForeignKey( diff --git a/src/ralph/accounts/admin.py b/src/ralph/accounts/admin.py index 9012a9aee3..f7b605476c 100644 --- a/src/ralph/accounts/admin.py +++ b/src/ralph/accounts/admin.py @@ -14,12 +14,13 @@ from django.utils.translation import ugettext_lazy as _ from ralph.accounts.models import RalphUser, Region, Team -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.helpers import getattr_dunder from ralph.admin.mixins import RalphAdminFormMixin from ralph.admin.views.extra import RalphDetailView from ralph.back_office.models import BackOfficeAsset, BackOfficeAssetStatus -from ralph.lib.table import Table +from ralph.lib.table.table import Table from ralph.lib.transitions.models import TransitionsHistory from ralph.licences.models import Licence from ralph.sim_cards.models import SIMCard diff --git a/src/ralph/accounts/models.py b/src/ralph/accounts/models.py index 4aca57acc1..bfd3a8286d 100644 --- a/src/ralph/accounts/models.py +++ b/src/ralph/accounts/models.py @@ -13,7 +13,7 @@ from ralph.admin.autocomplete import AutocompleteTooltipMixin from ralph.lib.mixins.models import AdminAbsoluteUrlMixin, NamedMixin -from ralph.lib.permissions import ( +from ralph.lib.permissions.models import ( PermByFieldMixin, PermissionsForObjectMixin, user_permission diff --git a/src/ralph/admin/__init__.py b/src/ralph/admin/__init__.py index a584458339..ac25e79c80 100644 --- a/src/ralph/admin/__init__.py +++ b/src/ralph/admin/__init__.py @@ -1,22 +1 @@ -from ralph.admin.sites import ralph_site -from ralph.admin.mixins import ( - RalphAdmin, - RalphAdminForm, - RalphMPTTAdmin, - RalphStackedInline, - RalphTabularInline, -) -from ralph.admin.decorators import register - default_app_config = 'ralph.admin.apps.RalphAdminConfig' - -__all__ = [ - 'ralph_site', - 'default_app_config', - 'register', - 'RalphAdmin', - 'RalphAdminForm', - 'RalphMPTTAdmin', - 'RalphStackedInline', - 'RalphTabularInline', -] diff --git a/src/ralph/admin/apps.py b/src/ralph/admin/apps.py index ff3cf25b7b..e5b701d881 100644 --- a/src/ralph/admin/apps.py +++ b/src/ralph/admin/apps.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ralph.admin.filters import register_custom_filters + from ralph.apps import RalphAppConfig @@ -9,5 +9,6 @@ class RalphAdminConfig(RalphAppConfig): verbose_name = 'Ralph Admin' def ready(self): + from ralph.admin.filters import register_custom_filters register_custom_filters() super().ready() diff --git a/src/ralph/admin/autocomplete.py b/src/ralph/admin/autocomplete.py index d012dcc46c..bfbcfcebfc 100644 --- a/src/ralph/admin/autocomplete.py +++ b/src/ralph/admin/autocomplete.py @@ -4,10 +4,10 @@ from functools import reduce from dj.choices import Choices +from django.apps import apps from django.conf.urls import url from django.core.exceptions import FieldDoesNotExist from django.db.models import Manager, Q -from django.db.models.loading import get_model from django.http import Http404, HttpResponseBadRequest, JsonResponse from django.views.generic import View @@ -164,7 +164,7 @@ class AutocompleteList(SuggestView): def dispatch(self, request, *args, **kwargs): try: - model = get_model(kwargs['app'], kwargs['model']) + model = apps.get_model(kwargs['app'], kwargs['model']) except LookupError: return HttpResponseBadRequest('Model not found') diff --git a/src/ralph/admin/m2m.py b/src/ralph/admin/m2m.py index bf9c77566a..29f373e88c 100644 --- a/src/ralph/admin/m2m.py +++ b/src/ralph/admin/m2m.py @@ -55,7 +55,7 @@ class AuthorAdmin(admin.ModelAdmin): from django.utils.text import get_text_list from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphStackedInline, RalphTabularInline +from ralph.admin.mixins import RalphStackedInline, RalphTabularInline from ralph.admin.mixins import RalphAdminForm diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index de146bf8cc..bab5dbdf33 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -21,7 +21,8 @@ from import_export.admin import ImportExportModelAdmin from import_export.widgets import ForeignKeyWidget from mptt.admin import MPTTAdminForm, MPTTModelAdmin -from reversion import VersionAdmin + +from reversion.admin import VersionAdmin from ralph.admin import widgets from ralph.admin.autocomplete import AjaxAutocompleteMixin @@ -473,8 +474,8 @@ class RalphAdmin( PermissionAdminMixin, RalphAdminImportExportMixin, AjaxAutocompleteMixin, + VersionAdmin, RalphAdminMixin, - VersionAdmin ): @property def media(self): diff --git a/src/ralph/admin/widgets.py b/src/ralph/admin/widgets.py index ceb554c1b9..659e4f063b 100644 --- a/src/ralph/admin/widgets.py +++ b/src/ralph/admin/widgets.py @@ -8,11 +8,11 @@ from urllib import parse from django import forms +from django.apps import apps from django.contrib.admin.templatetags.admin_static import static from django.contrib.admin.views.main import TO_FIELD_VAR from django.core.exceptions import FieldDoesNotExist from django.core.urlresolvers import reverse -from django.db.models.loading import get_model from django.forms.utils import flatatt from django.template import loader from django.template.context import RenderContext @@ -232,7 +232,7 @@ def get_search_fields(self): limit_models = getattr(self.field, 'limit_models', []) if limit_models: polymorphic_models = [ - get_model(*i.split('.')) for i in limit_models + apps.get_model(*i.split('.')) for i in limit_models ] search_fields_tooltip = defaultdict(list) diff --git a/src/ralph/assets/admin.py b/src/ralph/assets/admin.py index 6ff1b39fa9..9585bf6881 100644 --- a/src/ralph/assets/admin.py +++ b/src/ralph/assets/admin.py @@ -2,7 +2,8 @@ from django.db.models import Count from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphMPTTAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.views.extra import RalphDetailView from ralph.assets.models.assets import ( Asset, @@ -34,7 +35,7 @@ ) from ralph.data_importer import resources from ralph.lib.custom_fields.admin import CustomFieldValueAdminMixin -from ralph.lib.table import Table, TableWithUrl +from ralph.lib.table.table import Table, TableWithUrl from ralph.security.views import ScanStatusInTableMixin diff --git a/src/ralph/assets/models/assets.py b/src/ralph/assets/models/assets.py index a4ae5b4eb8..ea7c14142c 100644 --- a/src/ralph/assets/models/assets.py +++ b/src/ralph/assets/models/assets.py @@ -31,7 +31,7 @@ PriceMixin, TimeStampMixin ) -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin from ralph.lib.permissions.models import PermissionsBase logger = logging.getLogger(__name__) diff --git a/src/ralph/assets/models/base.py b/src/ralph/assets/models/base.py index 681a58adbe..323409046b 100644 --- a/src/ralph/assets/models/base.py +++ b/src/ralph/assets/models/base.py @@ -11,7 +11,7 @@ WithCustomFieldsMixin ) from ralph.lib.mixins.models import TaggableMixin, TimeStampMixin -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin from ralph.lib.permissions.models import PermissionsBase from ralph.lib.polymorphic.models import ( Polymorphic, diff --git a/src/ralph/assets/views.py b/src/ralph/assets/views.py index b869aeefe8..9ebf25c303 100644 --- a/src/ralph/assets/views.py +++ b/src/ralph/assets/views.py @@ -1,6 +1,6 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphTabularInline +from ralph.admin.mixins import RalphTabularInline from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.assets.models.components import ( Disk, diff --git a/src/ralph/attachments/models.py b/src/ralph/attachments/models.py index b5223f8a8c..d34e9415da 100644 --- a/src/ralph/attachments/models.py +++ b/src/ralph/attachments/models.py @@ -3,7 +3,7 @@ import string from django.conf import settings -from django.contrib.contenttypes import generic +from django.contrib.contenttypes import fields from django.contrib.contenttypes.models import ContentType from django.core.files.base import ContentFile from django.db import models, transaction @@ -169,7 +169,7 @@ class AttachmentItem(models.Model): attachment = models.ForeignKey(Attachment, related_name='items') content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() - content_object = generic.GenericForeignKey('content_type', 'object_id') + content_object = fields.GenericForeignKey('content_type', 'object_id') objects = AttachmentItemManager() diff --git a/src/ralph/back_office/admin.py b/src/ralph/back_office/admin.py index 0dfd71084b..4bf1801cbd 100644 --- a/src/ralph/back_office/admin.py +++ b/src/ralph/back_office/admin.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- from django import forms +from django.apps import apps from django.conf import settings -from django.db.models.loading import get_model from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import LiquidatedStatusFilter, TagsListFilter from ralph.admin.mixins import BulkEditChangeListMixin from ralph.admin.sites import ralph_site @@ -217,7 +218,7 @@ class BackOfficeAssetBulkForm(Form): queryset=Licence.objects.all(), label=_('licences'), required=False, widget=AutocompleteWidget( - field=get_model( + field=apps.get_model( 'licences.BaseObjectLicence' )._meta.get_field('licence'), admin_site=ralph_site, diff --git a/src/ralph/configuration_management/models.py b/src/ralph/configuration_management/models.py index ce14bc4a61..4be83267e2 100644 --- a/src/ralph/configuration_management/models.py +++ b/src/ralph/configuration_management/models.py @@ -5,7 +5,7 @@ from ralph.assets.models import BaseObject from ralph.lib.mixins.models import TimeStampMixin -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin class SCMCheckResult(Choices): diff --git a/src/ralph/dashboards/admin.py b/src/ralph/dashboards/admin.py index e4e93d17ae..93b9fcb5ce 100644 --- a/src/ralph/dashboards/admin.py +++ b/src/ralph/dashboards/admin.py @@ -7,7 +7,8 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.mixins import RalphAdminForm from ralph.dashboards.models import Dashboard, Graph diff --git a/src/ralph/data_center/admin.py b/src/ralph/data_center/admin.py index 943a461f5a..ae4702dbb7 100644 --- a/src/ralph/data_center/admin.py +++ b/src/ralph/data_center/admin.py @@ -10,7 +10,9 @@ from django.db.models import Prefetch, Q from django.utils.translation import ugettext_lazy as _ -from ralph.admin import filters, RalphAdmin, RalphTabularInline, register +from ralph.admin import filters +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import ( BaseObjectHostnameFilter, ChoicesListFilter, @@ -60,7 +62,7 @@ from ralph.data_importer import resources from ralph.deployment.mixins import ActiveDeploymentMessageMixin from ralph.lib.custom_fields.admin import CustomFieldValueAdminMixin -from ralph.lib.table import Table +from ralph.lib.table.table import Table from ralph.lib.transitions.admin import TransitionAdminMixin from ralph.licences.models import BaseObjectLicence from ralph.networks.forms import SimpleNetworkWithManagementIPForm diff --git a/src/ralph/data_center/forms.py b/src/ralph/data_center/forms.py index 234ac737de..f205e43c8d 100644 --- a/src/ralph/data_center/forms.py +++ b/src/ralph/data_center/forms.py @@ -13,7 +13,7 @@ class DataCenterAssetForm(PriceFormMixin, AssetFormMixin, RalphAdminForm): MODEL_TYPE = ObjectModelType.data_center - management_ip = forms.IPAddressField(required=False) + management_ip = forms.GenericIPAddressField(required=False, protocol='IPv4') management_hostname = CharFormFieldWithAutoStrip(required=False) ip_fields = ['management_ip', 'management_hostname'] diff --git a/src/ralph/data_importer/models.py b/src/ralph/data_importer/models.py index e4c01317d2..9c88794a04 100644 --- a/src/ralph/data_importer/models.py +++ b/src/ralph/data_importer/models.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.contrib.contenttypes import generic +from django.contrib.contenttypes import fields from django.contrib.contenttypes.models import ContentType from django.db import models @@ -20,7 +20,7 @@ class ImportedObjects(TimeStampMixin, models.Model): old_ci_uid = models.CharField( max_length=255, db_index=True, null=True, blank=True ) - object = generic.GenericForeignKey('content_type', 'object_pk') + object = fields.GenericForeignKey('content_type', 'object_pk') def __str__(self): return "{} - {}".format( diff --git a/src/ralph/deployment/admin.py b/src/ralph/deployment/admin.py index b0f1ef616a..db907b9ede 100644 --- a/src/ralph/deployment/admin.py +++ b/src/ralph/deployment/admin.py @@ -1,6 +1,7 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.deployment.forms import PrebootConfigurationForm from ralph.deployment.models import ( Deployment, diff --git a/src/ralph/dhcp/admin.py b/src/ralph/dhcp/admin.py index abb465765f..48cf7f3537 100644 --- a/src/ralph/dhcp/admin.py +++ b/src/ralph/dhcp/admin.py @@ -2,14 +2,15 @@ from django.template.defaultfilters import date, timesince_filter from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.dhcp.models import ( DHCPServer, DNSServer, DNSServerGroup, DNSServerGroupOrder ) -from ralph.lib.table import TableWithUrl +from ralph.lib.table.table import TableWithUrl @register(DHCPServer) diff --git a/src/ralph/domains/admin.py b/src/ralph/domains/admin.py index 7b41d73a8a..66c4ffc20f 100644 --- a/src/ralph/domains/admin.py +++ b/src/ralph/domains/admin.py @@ -2,7 +2,8 @@ from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import DateListFilter from ralph.attachments.admin import AttachmentsMixin from ralph.data_importer.resources import DomainContractResource, DomainResource diff --git a/src/ralph/domains/models/domains.py b/src/ralph/domains/models/domains.py index fe8f7edf40..5e490a936d 100644 --- a/src/ralph/domains/models/domains.py +++ b/src/ralph/domains/models/domains.py @@ -14,7 +14,7 @@ PriceMixin, TimeStampMixin ) -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin class DomainRegistrant( diff --git a/src/ralph/lib/custom_fields/admin.py b/src/ralph/lib/custom_fields/admin.py index 1320b75aec..3caae171e8 100644 --- a/src/ralph/lib/custom_fields/admin.py +++ b/src/ralph/lib/custom_fields/admin.py @@ -3,7 +3,8 @@ from django.contrib.admin.utils import unquote from django.contrib.contenttypes.models import ContentType -from ralph.admin import RalphAdmin, register +from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin from ralph.admin.mixins import RalphGenericTabularInline from ralph.lib.custom_fields.forms import ( CustomFieldValueForm, diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index 926e8b6f11..1730aac67d 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -5,7 +5,6 @@ from django.contrib.contenttypes.fields import ( create_generic_related_manager, GenericRelation, - ReverseGenericRelatedObjectsDescriptor ) from django.contrib.contenttypes.models import ContentType from django.db import connection, models @@ -148,9 +147,15 @@ def values_list(self, *fields): ) -class ReverseGenericRelatedObjectsWithInheritanceDescriptor( - ReverseGenericRelatedObjectsDescriptor -): +class ReverseGenericRelatedObjectsWithInheritanceDescriptor(): + + def __init__(self, field, for_concrete_model=True): + """ + imported from ReverseGenericRelatedObjectsDescriptor + """ + self.field = field + self.for_concrete_model = for_concrete_model + def __get__(self, instance, instance_type=None): """ Overwrite of ReverseGenericRelatedObjectsDescriptor's __get__ diff --git a/src/ralph/lib/custom_fields/models.py b/src/ralph/lib/custom_fields/models.py index cd5970531d..5f2b8e665d 100644 --- a/src/ralph/lib/custom_fields/models.py +++ b/src/ralph/lib/custom_fields/models.py @@ -4,7 +4,7 @@ from dj.choices import Choices from django import forms from django.contrib.auth.models import Group -from django.contrib.contenttypes import generic +from django.contrib.contenttypes import fields from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -132,7 +132,7 @@ class CustomFieldValue(TimeStampMixin, models.Model): value = models.CharField(max_length=CUSTOM_FIELD_VALUE_MAX_LENGTH) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField(db_index=True) - object = generic.GenericForeignKey('content_type', 'object_id') + object = fields.GenericForeignKey('content_type', 'object_id') objects = models.Manager() # generic relation has to use specific manager (queryset) diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index 995cb30513..02194bf78d 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -2,12 +2,12 @@ import netaddr from django import forms +from django.apps import apps from django.conf import settings from django.contrib.admin.widgets import AdminTextInputWidget from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import models -from django.db.models.loading import get_model from django.forms.utils import flatatt from django.utils import six from django.utils.html import format_html, smart_urlquote @@ -227,7 +227,7 @@ def limit_choices(self): """ if self.limit_models: content_types = ContentType.objects.get_for_models( - *[get_model(*i.split('.')) for i in self.limit_models] + *[apps.get_model(*i.split('.')) for i in self.limit_models] ) return {'content_type__in': content_types.values()} @@ -237,7 +237,7 @@ def get_limit_models(self): """ Returns Model class list from limit_models. """ - return [get_model(model) for model in self.limit_models] + return [apps.get_model(model) for model in self.limit_models] class TagWidget(forms.TextInput): diff --git a/src/ralph/lib/permissions/__init__.py b/src/ralph/lib/permissions/__init__.py index 501f22b4b9..e69de29bb2 100644 --- a/src/ralph/lib/permissions/__init__.py +++ b/src/ralph/lib/permissions/__init__.py @@ -1,9 +0,0 @@ -from ralph.lib.permissions.models import ( - PermByFieldMixin, - PermissionsForObjectMixin, - user_permission -) - -default_app_config = 'ralph.lib.permissions.apps.PermissionAppConfig' - -__all__ = ['PermByFieldMixin', 'PermissionsForObjectMixin', 'user_permission'] diff --git a/src/ralph/lib/permissions/api.py b/src/ralph/lib/permissions/api.py index ae637eddac..9ddecc0066 100644 --- a/src/ralph/lib/permissions/api.py +++ b/src/ralph/lib/permissions/api.py @@ -11,7 +11,7 @@ from rest_framework.filters import BaseFilterBackend from rest_framework.permissions import IsAuthenticated as DRFIsAuthenticated -from ralph.lib.permissions import PermByFieldMixin, PermissionsForObjectMixin +from ralph.lib.permissions.models import PermByFieldMixin, PermissionsForObjectMixin ADD_PERM = ['%(app_label)s.add_%(model_name)s'] CHANGE_PERM = ['%(app_label)s.change_%(model_name)s'] diff --git a/src/ralph/lib/permissions/apps.py b/src/ralph/lib/permissions/apps.py index ddc88f5886..24d71b3487 100644 --- a/src/ralph/lib/permissions/apps.py +++ b/src/ralph/lib/permissions/apps.py @@ -11,6 +11,7 @@ class PermissionAppConfig(AppConfig): verbose_name = 'Permissions' def ready(self): + default_app_config = 'ralph.lib.permissions.apps.PermissionAppConfig' post_migrate.disconnect( dispatch_uid='django.contrib.auth.management.create_permissions' ) diff --git a/src/ralph/lib/table/__init__.py b/src/ralph/lib/table/__init__.py index 64ccbba1a4..e69de29bb2 100644 --- a/src/ralph/lib/table/__init__.py +++ b/src/ralph/lib/table/__init__.py @@ -1,3 +0,0 @@ -from ralph.lib.table.table import Table, TableWithUrl - -__all__ = ['Table', 'TableWithUrl'] diff --git a/src/ralph/lib/template/loaders.py b/src/ralph/lib/template/loaders.py index 6d0c71a502..64fe48e662 100644 --- a/src/ralph/lib/template/loaders.py +++ b/src/ralph/lib/template/loaders.py @@ -3,7 +3,7 @@ from os.path import abspath, dirname, join from django.apps import apps -from django.template import TemplateDoesNotExist +from django.template.loader import TemplateDoesNotExist from django.template.loaders.base import Loader as BaseLoader @@ -50,7 +50,7 @@ def get_template_path(self, template_name, template_dirs=None): template_parts = template_name.split(":", 1) if len(template_parts) != 2: - raise TemplateDoesNotExist() + raise TemplateDoesNotExist(template_name) app_label, template_name = template_parts app = apps.get_app_config(app_label) diff --git a/src/ralph/lib/transitions/admin.py b/src/ralph/lib/transitions/admin.py index 2230cf6897..41398b3923 100644 --- a/src/ralph/lib/transitions/admin.py +++ b/src/ralph/lib/transitions/admin.py @@ -9,7 +9,8 @@ from django.utils.functional import curry from django.utils.http import urlencode -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.views.extra import RalphDetailView from ralph.helpers import get_model_view_url_name from ralph.lib.transitions.forms import TransitionForm diff --git a/src/ralph/lib/transitions/checks.py b/src/ralph/lib/transitions/checks.py index e0ed14e64d..7d05a4b874 100644 --- a/src/ralph/lib/transitions/checks.py +++ b/src/ralph/lib/transitions/checks.py @@ -2,7 +2,7 @@ from django.core.checks import Error from django.db.utils import DatabaseError -from django.template.base import TemplateDoesNotExist +from django.template.loader import TemplateDoesNotExist from django.template.loader import get_template diff --git a/src/ralph/lib/transitions/views.py b/src/ralph/lib/transitions/views.py index 84ebf3c4b9..4b88e5b9cb 100644 --- a/src/ralph/lib/transitions/views.py +++ b/src/ralph/lib/transitions/views.py @@ -2,9 +2,9 @@ from itertools import repeat from django import forms +from django.apps import apps from django.contrib import messages from django.core.urlresolvers import reverse -from django.db.models.loading import get_model from django.db.transaction import atomic, non_atomic_requests from django.http import ( Http404, @@ -95,7 +95,7 @@ def form_fields_from_actions(self): autocomplete_model = options.get('autocomplete_model', False) model = self.obj if autocomplete_model: - model = get_model(autocomplete_model) + model = apps.get_model(autocomplete_model) if autocomplete_field: field = model._meta.get_field(autocomplete_field) diff --git a/src/ralph/licences/admin.py b/src/ralph/licences/admin.py index 70013ae94d..1fa34c4dc6 100644 --- a/src/ralph/licences/admin.py +++ b/src/ralph/licences/admin.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import TagsListFilter from ralph.admin.mixins import BulkEditChangeListMixin from ralph.admin.views.extra import RalphDetailViewAdmin diff --git a/src/ralph/licences/models.py b/src/ralph/licences/models.py index 92f5a9ca32..a227f64a02 100644 --- a/src/ralph/licences/models.py +++ b/src/ralph/licences/models.py @@ -19,7 +19,7 @@ NamedMixin, PriceMixin ) -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin from ralph.lib.polymorphic.models import PolymorphicQuerySet @@ -313,7 +313,7 @@ def get_autocomplete_queryset(cls): ) -@reversion.register() +# @reversion.register() class BaseObjectLicence(models.Model): licence = models.ForeignKey(Licence) base_object = BaseObjectForeignKey( diff --git a/src/ralph/networks/admin.py b/src/ralph/networks/admin.py index 8427cb318d..dcb31f3fd8 100644 --- a/src/ralph/networks/admin.py +++ b/src/ralph/networks/admin.py @@ -4,7 +4,8 @@ from django.utils.html import escape from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.filters import RelatedAutocompleteFieldListFilter from ralph.admin.helpers import CastToInteger from ralph.admin.mixins import RalphMPTTAdmin @@ -12,7 +13,7 @@ from ralph.assets.models import BaseObject from ralph.data_importer import resources from ralph.lib.mixins.admin import ParentChangeMixin -from ralph.lib.table import TableWithUrl +from ralph.lib.table.table import TableWithUrl from ralph.networks.filters import ( ContainsIPAddressFilter, IPRangeFilter, diff --git a/src/ralph/networks/forms.py b/src/ralph/networks/forms.py index 67b880b665..5f7fd3a87e 100755 --- a/src/ralph/networks/forms.py +++ b/src/ralph/networks/forms.py @@ -99,7 +99,7 @@ class SimpleNetworkForm(EthernetLockDeleteForm): modified/deleted. """ hostname = CharFormFieldWithAutoStrip(label='Hostname', required=False) - address = forms.IPAddressField(label='IP address', required=False) + address = forms.GenericIPAddressField(label='IP address', required=False, protocol='IPv4') ip_fields = ['hostname', 'address'] diff --git a/src/ralph/networks/views.py b/src/ralph/networks/views.py index a1ad126206..347653f0d8 100644 --- a/src/ralph/networks/views.py +++ b/src/ralph/networks/views.py @@ -1,10 +1,10 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphTabularInline +from ralph.admin.mixins import RalphTabularInline from ralph.admin.m2m import RalphTabularM2MInline from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.assets.models.components import Ethernet -from ralph.lib.table import TableWithUrl +from ralph.lib.table.table import TableWithUrl from ralph.networks.forms import NetworkForm, NetworkInlineFormset from ralph.networks.models import Network diff --git a/src/ralph/operations/admin.py b/src/ralph/operations/admin.py index 127cbf6525..42f448d275 100644 --- a/src/ralph/operations/admin.py +++ b/src/ralph/operations/admin.py @@ -5,7 +5,8 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphMPTTAdmin, register +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin +from ralph.admin.decorators import register from ralph.admin.mixins import RalphAdminForm from ralph.admin.views.main import RalphChangeList from ralph.admin.widgets import AdminDateTimeWidget diff --git a/src/ralph/reports/admin.py b/src/ralph/reports/admin.py index c63af43a9d..dc0a8393f2 100644 --- a/src/ralph/reports/admin.py +++ b/src/ralph/reports/admin.py @@ -1,4 +1,5 @@ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.reports.forms import ReportTemplateFormset from ralph.reports.models import Report, ReportLanguage, ReportTemplate diff --git a/src/ralph/security/models.py b/src/ralph/security/models.py index 2e58d7f686..2940ff8715 100644 --- a/src/ralph/security/models.py +++ b/src/ralph/security/models.py @@ -11,7 +11,7 @@ TaggableMixin, TimeStampMixin ) -from ralph.lib.permissions import PermByFieldMixin +from ralph.lib.permissions.models import PermByFieldMixin def any_exceeded(vulnerabilties): diff --git a/src/ralph/security/views.py b/src/ralph/security/views.py index 03d7123445..8f0b0c0038 100644 --- a/src/ralph/security/views.py +++ b/src/ralph/security/views.py @@ -7,7 +7,8 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.helpers import get_admin_url from ralph.admin.sites import ralph_site from ralph.admin.views.extra import RalphDetailView diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 62be387907..5fa055bad3 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -56,10 +56,11 @@ def get_sentinels(sentinels_string): # Application definition INSTALLED_APPS = ( + 'django.contrib.contenttypes', + 'taggit', + 'django.contrib.auth', 'ralph.admin', 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', 'django.contrib.humanize', 'django.contrib.sessions', 'django.contrib.messages', @@ -98,12 +99,11 @@ def get_sentinels(sentinels_string): 'ralph.lib.transitions', 'ralph.lib.permissions', 'ralph.lib.custom_fields', - 'ralph.lib.hooks', - 'ralph.notifications', + # 'ralph.lib.hooks', + # 'ralph.notifications', 'ralph.ssl_certificates', 'rest_framework', 'rest_framework.authtoken', - 'taggit', 'taggit_serializer', 'djmoney', ) @@ -169,7 +169,7 @@ def get_sentinels(sentinels_string): DATABASES = { 'default': { - 'ENGINE': os.environ.get('DATABASE_ENGINE', 'transaction_hooks.backends.mysql'), # noqa + 'ENGINE': os.environ.get('DATABASE_ENGINE', 'django.db.backends.mysql'), # noqa 'NAME': os.environ.get('DATABASE_NAME', 'ralph_ng'), 'USER': os.environ.get('DATABASE_USER', 'ralph_ng'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'ralph_ng') or None, diff --git a/src/ralph/settings/local.template b/src/ralph/settings/local.template index cd4cdf0c18..fe205aaf91 100644 --- a/src/ralph/settings/local.template +++ b/src/ralph/settings/local.template @@ -2,7 +2,7 @@ from ralph.settings.dev import * # noqa DATABASES = { 'default': { - 'ENGINE': 'transaction_hooks.backends.mysql', + 'ENGINE': 'django.db.backends.mysql', 'NAME': os.environ.get('DATABASE_NAME', 'ralph_ng'), 'USER': os.environ.get('DATABASE_USER', 'ralph_ng'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'ralph_ng') or None, @@ -11,7 +11,7 @@ DATABASES = { 'ATOMIC_REQUESTS': True, 'TEST': { 'NAME': 'test_ralph_ng', - 'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2', + 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'USER': os.environ.get('DATABASE_USER', 'ralph_ng'), 'PASSWORD': os.environ.get('DATABASE_PASSWORD', 'ralph_ng') or None, 'HOST': os.environ.get('DATABASE_HOST', '127.0.0.1'), diff --git a/src/ralph/settings/test.py b/src/ralph/settings/test.py index 2d65b0c153..72aa5910ca 100644 --- a/src/ralph/settings/test.py +++ b/src/ralph/settings/test.py @@ -10,7 +10,7 @@ TEST_DB_ENGINE = os.environ.get('TEST_DB_ENGINE', 'mysql') if TEST_DB_ENGINE == 'psql': DATABASES['default'].update({ - 'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2', + 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'PORT': os.environ.get('DATABASE_PORT', 5432), 'OPTIONS': {}, }) diff --git a/src/ralph/sim_cards/admin.py b/src/ralph/sim_cards/admin.py index b201ffd2b1..f2a48a836d 100644 --- a/src/ralph/sim_cards/admin.py +++ b/src/ralph/sim_cards/admin.py @@ -1,6 +1,7 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.mixins import BulkEditChangeListMixin, RalphAdminMixin from ralph.admin.views.multiadd import MulitiAddAdminMixin from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/ssl_certificates/admin.py b/src/ralph/ssl_certificates/admin.py index 78769d24f8..65a04a9d11 100644 --- a/src/ralph/ssl_certificates/admin.py +++ b/src/ralph/ssl_certificates/admin.py @@ -1,6 +1,7 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.filters import DateListFilter from ralph.attachments.admin import AttachmentsMixin from ralph.ssl_certificates.forms import SSLCertificateForm diff --git a/src/ralph/supports/admin.py b/src/ralph/supports/admin.py index 9b334433fe..0327c9b6d0 100644 --- a/src/ralph/supports/admin.py +++ b/src/ralph/supports/admin.py @@ -4,7 +4,8 @@ from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import TagsListFilter from ralph.admin.helpers import generate_html_link from ralph.admin.mixins import BulkEditChangeListMixin diff --git a/src/ralph/tests/mixins.py b/src/ralph/tests/mixins.py index 2b69e81ad9..2a054b08c7 100644 --- a/src/ralph/tests/mixins.py +++ b/src/ralph/tests/mixins.py @@ -4,7 +4,7 @@ from django.conf import settings from django.core.urlresolvers import clear_url_caches -from django.utils.importlib import import_module +from importlib import import_module from ralph.tests.factories import UserFactory diff --git a/src/ralph/trade_marks/admin.py b/src/ralph/trade_marks/admin.py index 3e301b0c7b..e0be597a14 100644 --- a/src/ralph/trade_marks/admin.py +++ b/src/ralph/trade_marks/admin.py @@ -3,7 +3,8 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import ( ChoicesListFilter, custom_title_filter, diff --git a/src/ralph/urls/base.py b/src/ralph/urls/base.py index ff910b006e..44d40da9d7 100644 --- a/src/ralph/urls/base.py +++ b/src/ralph/urls/base.py @@ -3,7 +3,7 @@ from rest_framework.authtoken import views from sitetree.sitetreeapp import SiteTree # noqa -from ralph.admin import ralph_site as admin +from ralph.admin.sites import ralph_site as admin from ralph.api import router from ralph.health_check import status_health, status_ping diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index 811d94394f..42b53b4a22 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -6,7 +6,8 @@ from django.db.models import Count, Prefetch from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphAdminForm, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphAdminForm, RalphTabularInline +from ralph.admin.decorators import register from ralph.admin.filters import BaseObjectHostnameFilter, TagsListFilter from ralph.assets.models import BaseObject from ralph.assets.models.components import Ethernet @@ -50,7 +51,7 @@ class CloudHostSecurityInfoView(SecurityInfo): url_name = 'security_cloudhost_security_info' -@register(VirtualServerType) +# @register(VirtualServerType) class VirtualServerTypeForm(RalphAdmin): pass @@ -255,7 +256,7 @@ class CloudHostSCMInfo(SCMCheckInfo): url_name = 'cloudhost_scm_info' -@register(CloudHost) +# @register(CloudHost) class CloudHostAdmin( SCMStatusCheckInChangeListMixin, ScanStatusInChangeListMixin, CustomFieldValueAdminMixin, RalphAdmin diff --git a/src/ralph/virtual/models.py b/src/ralph/virtual/models.py index bde08a2e70..e2cd25a1fc 100644 --- a/src/ralph/virtual/models.py +++ b/src/ralph/virtual/models.py @@ -203,7 +203,7 @@ def save(self, *args, **kwargs): pass super(CloudHost, self).save(*args, **kwargs) - cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type') + # cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type') cloudprovider = models.ForeignKey(CloudProvider) cloudprovider._autocomplete = False @@ -364,7 +364,7 @@ class VirtualServer( unique=True, ) # TODO: remove this field - cluster = models.ForeignKey(Cluster, blank=True, null=True) + # cluster = models.ForeignKey(Cluster, blank=True, null=True) previous_dc_host_update_fields = ['hostname'] _allow_in_dashboard = True From d0d75115c5dc6825ee41520a2fdf41b04628da90 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 29 Apr 2024 09:40:19 +0200 Subject: [PATCH 02/45] Fix some tests --- src/ralph/accessories/models.py | 4 ++-- src/ralph/accounts/views.py | 2 +- src/ralph/admin/tests/tests_functional.py | 2 +- src/ralph/api/serializers.py | 2 +- src/ralph/api/tests/test_serializers.py | 2 +- src/ralph/data_center/tests/test_view.py | 2 +- src/ralph/data_importer/tests/test_export.py | 2 +- src/ralph/lib/custom_fields/fields.py | 17 ++++++----------- src/ralph/lib/mixins/fields.py | 6 ++++-- src/ralph/lib/table/tests.py | 2 +- src/ralph/lib/transitions/models.py | 2 +- src/ralph/licences/models.py | 4 ++-- src/ralph/settings/base.py | 2 +- src/ralph/signals.py | 4 ++-- src/ralph/tests/admin.py | 3 ++- src/ralph/virtual/admin.py | 4 ++-- src/ralph/virtual/models.py | 4 ++-- 17 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/ralph/accessories/models.py b/src/ralph/accessories/models.py index 9f582b9e0d..fd3d382efa 100644 --- a/src/ralph/accessories/models.py +++ b/src/ralph/accessories/models.py @@ -1,4 +1,4 @@ -import reversion +from reversion import revisions as reversion from dj.choices import Choices from django import forms from django.conf import settings @@ -213,7 +213,7 @@ def free(self): free._permission_field = 'number_bought' -# @reversion.register() +@reversion.register() class AccessoryUser(models.Model): accessory = models.ForeignKey(Accessory) user = models.ForeignKey( diff --git a/src/ralph/accounts/views.py b/src/ralph/accounts/views.py index 643673a4fe..cffc8a491f 100644 --- a/src/ralph/accounts/views.py +++ b/src/ralph/accounts/views.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from datetime import date -import reversion +from reversion import revisions as reversion from django.conf import settings from django.contrib import messages from django.core.urlresolvers import reverse diff --git a/src/ralph/admin/tests/tests_functional.py b/src/ralph/admin/tests/tests_functional.py index 8dcd18e7ed..0c9c1d057c 100644 --- a/src/ralph/admin/tests/tests_functional.py +++ b/src/ralph/admin/tests/tests_functional.py @@ -6,7 +6,7 @@ from django.test import RequestFactory, TestCase from django.views.generic import View -from ralph.admin import RalphAdmin +from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register_extra_view from ralph.admin.sites import ralph_site from ralph.admin.views.extra import RalphDetailView, RalphListView diff --git a/src/ralph/api/serializers.py b/src/ralph/api/serializers.py index 045daa2880..8d393c87c5 100644 --- a/src/ralph/api/serializers.py +++ b/src/ralph/api/serializers.py @@ -3,7 +3,7 @@ import operator from functools import reduce -import reversion +from reversion import revisions as reversion from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import NON_FIELD_ERRORS, ObjectDoesNotExist from django.db import transaction diff --git a/src/ralph/api/tests/test_serializers.py b/src/ralph/api/tests/test_serializers.py index e1fe028588..dcc95ffb46 100644 --- a/src/ralph/api/tests/test_serializers.py +++ b/src/ralph/api/tests/test_serializers.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -import reversion +from reversion import revisions as reversion from dj.choices import Choices from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse diff --git a/src/ralph/data_center/tests/test_view.py b/src/ralph/data_center/tests/test_view.py index 620824f490..d78cb117e2 100644 --- a/src/ralph/data_center/tests/test_view.py +++ b/src/ralph/data_center/tests/test_view.py @@ -39,7 +39,7 @@ class DataCenterAssetViewTest(ClientMixin, TestCase): def test_changelist_view(self): self.login_as_user() DataCenterAssetFullFactory.create_batch(10) - with self.assertNumQueries(18): + with self.assertNumQueries(16): self.client.get( reverse('admin:data_center_datacenterasset_changelist'), ) diff --git a/src/ralph/data_importer/tests/test_export.py b/src/ralph/data_importer/tests/test_export.py index 6eec5bef33..e420f175ac 100644 --- a/src/ralph/data_importer/tests/test_export.py +++ b/src/ralph/data_importer/tests/test_export.py @@ -7,7 +7,7 @@ from django.test.utils import CaptureQueriesContext from ralph.accounts.tests.factories import UserFactory -from ralph.admin import ralph_site +from ralph.admin.sites import ralph_site from ralph.data_center.models import DataCenterAsset from ralph.data_center.tests.factories import DataCenterAssetFullFactory from ralph.licences.models import Licence diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index 1730aac67d..5b2228082c 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -111,7 +111,7 @@ def _clone(self, klass=None, setup=False, **kwargs): '_prioritize': self._prioritize, '_prioritize_model_or_instance': self._prioritize_model_or_instance, }) - return super()._clone(klass, setup, **kwargs) + return super()._clone(**kwargs) def prioritize(self, model_or_instance): self._prioritize = True @@ -166,10 +166,12 @@ def __get__(self, instance, instance_type=None): if instance is None: return self rel_model = self.field.rel.to + rel_model.model = self.field.rel.to + rel_model.field = self.field # difference here comparing to Django! superclass = rel_model.inherited_objects.__class__ RelatedManager = create_generic_related_manager_with_inheritance( - superclass + superclass, rel_model ) qn = connection.ops.quote_name @@ -180,20 +182,13 @@ def __get__(self, instance, instance_type=None): join_cols = self.field.get_joining_columns(reverse_join=True)[0] manager = RelatedManager( - model=rel_model, instance=instance, - source_col_name=qn(join_cols[0]), - target_col_name=qn(join_cols[1]), - content_type=content_type, - content_type_field_name=self.field.content_type_field_name, - object_id_field_name=self.field.object_id_field_name, - prefetch_cache_name=self.field.attname, ) return manager -def create_generic_related_manager_with_inheritance(superclass): # noqa: C901 +def create_generic_related_manager_with_inheritance(superclass, rel): # noqa: C901 """ Extension to Django's create_generic_related_manager. @@ -204,7 +199,7 @@ def create_generic_related_manager_with_inheritance(superclass): # noqa: C901 with inheritance of more than one instance """ # get Django's GenericRelatedObject manager first - manager = create_generic_related_manager(superclass) + manager = create_generic_related_manager(superclass, rel) class GenericRelatedObjectWithInheritanceManager(manager): def __init__(self, *args, **kwargs): diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index 02194bf78d..05d5f595e6 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -73,9 +73,11 @@ def clean(self, value, model_instance): # in UD. class NUMPFieldMixIn(object): - def __init__(self, fields_to_ignore, *args, **kwargs): + def __init__(self, *args, **kwargs): + fields_to_ignore = kwargs.pop('fields_to_ignore', None) super(NUMPFieldMixIn, self).__init__(*args, **kwargs) - self.fields_to_ignore = fields_to_ignore + self.fields_to_ignore = fields_to_ignore if fields_to_ignore is not None else ('help_text', 'verbose_name') + def deconstruct(self): name, path, args, kwargs = super(NUMPFieldMixIn, self).deconstruct() diff --git a/src/ralph/lib/table/tests.py b/src/ralph/lib/table/tests.py index 3881ac110a..7b7f280d04 100644 --- a/src/ralph/lib/table/tests.py +++ b/src/ralph/lib/table/tests.py @@ -1,6 +1,6 @@ from django.test import TestCase -from ralph.lib.table import Table +from ralph.lib.table.table import Table from ralph.tests.models import Foo diff --git a/src/ralph/lib/transitions/models.py b/src/ralph/lib/transitions/models.py index 209f1fdd14..034daa10c2 100644 --- a/src/ralph/lib/transitions/models.py +++ b/src/ralph/lib/transitions/models.py @@ -4,7 +4,7 @@ import logging from collections import defaultdict -import reversion +from reversion import revisions as reversion from dj.choices import Choices from django import forms from django.conf import settings diff --git a/src/ralph/licences/models.py b/src/ralph/licences/models.py index a227f64a02..9632c24da1 100644 --- a/src/ralph/licences/models.py +++ b/src/ralph/licences/models.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """SAM module models.""" -import reversion +from reversion import revisions as reversion from django.conf import settings from django.core.exceptions import ValidationError from django.db import models @@ -313,7 +313,7 @@ def get_autocomplete_queryset(cls): ) -# @reversion.register() +@reversion.register() class BaseObjectLicence(models.Model): licence = models.ForeignKey(Licence) base_object = BaseObjectForeignKey( diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 5fa055bad3..57fef60ec5 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -9,7 +9,7 @@ from ralph.settings.hooks import HOOKS_CONFIGURATION # noqa: F401 - +SILENCED_SYSTEM_CHECKS = ['models.E006'] # TODO fix def bool_from_env(var, default: bool=False) -> bool: """Helper for converting env string into boolean. diff --git a/src/ralph/signals.py b/src/ralph/signals.py index 6f7b106f76..830d52d5cb 100644 --- a/src/ralph/signals.py +++ b/src/ralph/signals.py @@ -1,4 +1,4 @@ -from django.db import connection +from django.db import transaction from django.db.models.signals import post_save from django.dispatch import receiver @@ -54,4 +54,4 @@ def wrapper(): # TODO(mkurek): replace connection by transaction after upgrading to # Django 1.9 - connection.on_commit(wrapper) + transaction.on_commit(wrapper) diff --git a/src/ralph/tests/admin.py b/src/ralph/tests/admin.py index bcb229fc10..0c79f68c0b 100644 --- a/src/ralph/tests/admin.py +++ b/src/ralph/tests/admin.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin +from ralph.admin.decorators import register from ralph.admin.m2m import RalphTabularM2MInline from ralph.attachments.admin import AttachmentsMixin from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index 42b53b4a22..38c5f27088 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -51,7 +51,7 @@ class CloudHostSecurityInfoView(SecurityInfo): url_name = 'security_cloudhost_security_info' -# @register(VirtualServerType) +@register(VirtualServerType) class VirtualServerTypeForm(RalphAdmin): pass @@ -256,7 +256,7 @@ class CloudHostSCMInfo(SCMCheckInfo): url_name = 'cloudhost_scm_info' -# @register(CloudHost) +@register(CloudHost) class CloudHostAdmin( SCMStatusCheckInChangeListMixin, ScanStatusInChangeListMixin, CustomFieldValueAdminMixin, RalphAdmin diff --git a/src/ralph/virtual/models.py b/src/ralph/virtual/models.py index e2cd25a1fc..bde08a2e70 100644 --- a/src/ralph/virtual/models.py +++ b/src/ralph/virtual/models.py @@ -203,7 +203,7 @@ def save(self, *args, **kwargs): pass super(CloudHost, self).save(*args, **kwargs) - # cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type') + cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type') cloudprovider = models.ForeignKey(CloudProvider) cloudprovider._autocomplete = False @@ -364,7 +364,7 @@ class VirtualServer( unique=True, ) # TODO: remove this field - # cluster = models.ForeignKey(Cluster, blank=True, null=True) + cluster = models.ForeignKey(Cluster, blank=True, null=True) previous_dc_host_update_fields = ['hostname'] _allow_in_dashboard = True From c5d72e6d8f8afb5a4bc329ba5f3ec2785a27e220 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 29 Apr 2024 16:41:41 +0200 Subject: [PATCH 03/45] Fix sitetree --- src/ralph/admin/templates/admin/includes/javascripts.html | 2 +- src/ralph/settings/base.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ralph/admin/templates/admin/includes/javascripts.html b/src/ralph/admin/templates/admin/includes/javascripts.html index db63e10e57..4e6cdbdcde 100644 --- a/src/ralph/admin/templates/admin/includes/javascripts.html +++ b/src/ralph/admin/templates/admin/includes/javascripts.html @@ -3,7 +3,7 @@ - + diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 57fef60ec5..a665bb666a 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -99,8 +99,8 @@ def get_sentinels(sentinels_string): 'ralph.lib.transitions', 'ralph.lib.permissions', 'ralph.lib.custom_fields', - # 'ralph.lib.hooks', - # 'ralph.notifications', + 'ralph.lib.hooks', + 'ralph.notifications', 'ralph.ssl_certificates', 'rest_framework', 'rest_framework.authtoken', From 6543ef46b088c6d295edd9ebffad74c0797e1107 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Tue, 30 Apr 2024 13:25:24 +0200 Subject: [PATCH 04/45] Fix permissions --- src/ralph/lib/mixins/tests/test_models.py | 2 +- src/ralph/lib/permissions/__init__.py | 1 + src/ralph/lib/permissions/apps.py | 6 ++---- src/ralph/lib/permissions/views.py | 5 +++-- src/ralph/virtual/management/commands/openstack_sync.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ralph/lib/mixins/tests/test_models.py b/src/ralph/lib/mixins/tests/test_models.py index 1a9f55fd71..e5b3182b74 100644 --- a/src/ralph/lib/mixins/tests/test_models.py +++ b/src/ralph/lib/mixins/tests/test_models.py @@ -8,5 +8,5 @@ class AdminUrlTestCase(TestCase): def test_returned_url(self): obj = Foo.objects.create(bar='test') self.assertEqual( - '/tests/foo/{}/'.format(obj.pk), obj.get_absolute_url() + '/tests/foo/{}/change/'.format(obj.pk), obj.get_absolute_url() ) diff --git a/src/ralph/lib/permissions/__init__.py b/src/ralph/lib/permissions/__init__.py index e69de29bb2..5fa2a65554 100644 --- a/src/ralph/lib/permissions/__init__.py +++ b/src/ralph/lib/permissions/__init__.py @@ -0,0 +1 @@ +default_app_config = 'ralph.lib.permissions.apps.PermissionAppConfig' diff --git a/src/ralph/lib/permissions/apps.py b/src/ralph/lib/permissions/apps.py index 24d71b3487..ab8929b3e1 100644 --- a/src/ralph/lib/permissions/apps.py +++ b/src/ralph/lib/permissions/apps.py @@ -2,16 +2,14 @@ from django.apps import AppConfig from django.db.models.signals import post_migrate -from ralph.lib.permissions.models import create_permissions -from ralph.lib.permissions.views import update_extra_view_permissions - class PermissionAppConfig(AppConfig): name = 'ralph.lib.permissions' verbose_name = 'Permissions' def ready(self): - default_app_config = 'ralph.lib.permissions.apps.PermissionAppConfig' + from ralph.lib.permissions.models import create_permissions + from ralph.lib.permissions.views import update_extra_view_permissions post_migrate.disconnect( dispatch_uid='django.contrib.auth.management.create_permissions' ) diff --git a/src/ralph/lib/permissions/views.py b/src/ralph/lib/permissions/views.py index 753f2af948..98320bad6a 100644 --- a/src/ralph/lib/permissions/views.py +++ b/src/ralph/lib/permissions/views.py @@ -70,8 +70,9 @@ def update_extra_view_permissions(sender, **kwargs): logger.info('Updating extra views permissions...') admin_classes = {} for model, admin_class in ralph_site._registry.items(): - for change_view in admin_class.change_views: - admin_classes[change_view] = model + if admin_class.change_views: + for change_view in admin_class.change_views: + admin_classes[change_view] = model old_permission = Permission.objects.filter( codename__startswith='can_view_extra_' diff --git a/src/ralph/virtual/management/commands/openstack_sync.py b/src/ralph/virtual/management/commands/openstack_sync.py index 2b4f1de923..8189c55509 100644 --- a/src/ralph/virtual/management/commands/openstack_sync.py +++ b/src/ralph/virtual/management/commands/openstack_sync.py @@ -5,7 +5,7 @@ from enum import auto, Enum from functools import lru_cache -import reversion as revisions +from reversion import revisions from django.conf import settings from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from django.core.management.base import BaseCommand From 4d7d82d8987d1a61c81726e38430766864534f46 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Thu, 2 May 2024 10:47:13 +0200 Subject: [PATCH 05/45] Fix RalphAdminChecks --- src/ralph/admin/mixins.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index bab5dbdf33..ea6597e73d 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -169,29 +169,28 @@ class RalphAdminChecks(admin.checks.ModelAdminChecks): ('contenttypes', 'ContentType'.lower()) ) - def check(self, cls, model, **kwargs): - errors = super().check(cls, model, **kwargs) - errors.extend(self._check_absolute_url(cls, model)) + def check(self, model, **kwargs): + errors = super().check(model, **kwargs) + errors.extend(self._check_absolute_url(model.model)) return errors - def _check_form(self, cls, model): + def _check_form(self, model): """ Check if form subclasses RalphAdminFormMixin """ - result = super()._check_form(cls, model) + result = super()._check_form(model) if ( - hasattr(cls, 'form') and - not issubclass(cls.form, RalphAdminFormMixin) + hasattr(model, 'form') and not issubclass(model.form, RalphAdminFormMixin) ): result += admin.checks.must_inherit_from( parent='RalphAdminFormMixin', option='form', - obj=cls, + obj=model, id='admin.E016' ) return result - def _check_absolute_url(self, cls, model): + def _check_absolute_url(self, model): """ Check if model inherit from AdminAbsoluteUrlMixin """ @@ -474,8 +473,8 @@ class RalphAdmin( PermissionAdminMixin, RalphAdminImportExportMixin, AjaxAutocompleteMixin, - VersionAdmin, RalphAdminMixin, + VersionAdmin, ): @property def media(self): From 3f09ecc9d7badf863e92538006317fb00242f08f Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Thu, 2 May 2024 11:18:53 +0200 Subject: [PATCH 06/45] Fix isort --- src/ralph/access_cards/admin.py | 2 +- src/ralph/accessories/admin.py | 2 +- src/ralph/accessories/models.py | 3 ++- src/ralph/accounts/admin.py | 3 +-- src/ralph/accounts/views.py | 2 +- src/ralph/admin/m2m.py | 7 +++++-- src/ralph/admin/mixins.py | 3 ++- src/ralph/admin/tests/tests_functional.py | 2 +- src/ralph/api/serializers.py | 3 ++- src/ralph/api/tests/test_serializers.py | 2 +- src/ralph/assets/admin.py | 2 +- src/ralph/assets/models/assets.py | 3 +-- src/ralph/assets/models/base.py | 3 +-- src/ralph/back_office/admin.py | 7 +++++-- src/ralph/dashboards/admin.py | 3 +-- src/ralph/data_center/admin.py | 7 +++++-- src/ralph/deployment/admin.py | 2 +- src/ralph/dhcp/admin.py | 2 +- src/ralph/domains/admin.py | 2 +- src/ralph/lib/custom_fields/admin.py | 3 +-- src/ralph/lib/custom_fields/fields.py | 11 ++--------- src/ralph/lib/mixins/fields.py | 1 - src/ralph/lib/permissions/api.py | 5 ++++- src/ralph/lib/transitions/admin.py | 2 +- src/ralph/lib/transitions/checks.py | 4 +--- src/ralph/lib/transitions/models.py | 2 +- src/ralph/licences/admin.py | 7 +++++-- src/ralph/licences/models.py | 2 +- src/ralph/networks/admin.py | 3 +-- src/ralph/networks/forms.py | 6 +++++- src/ralph/networks/views.py | 2 +- src/ralph/operations/admin.py | 3 +-- src/ralph/reports/admin.py | 2 +- src/ralph/security/views.py | 3 +-- src/ralph/sim_cards/admin.py | 7 +++++-- src/ralph/ssl_certificates/admin.py | 2 +- src/ralph/supports/admin.py | 7 +++++-- src/ralph/tests/admin.py | 2 +- src/ralph/tests/mixins.py | 2 +- src/ralph/trade_marks/admin.py | 2 +- src/ralph/virtual/admin.py | 5 +++-- .../virtual/management/commands/openstack_sync.py | 2 +- 42 files changed, 78 insertions(+), 67 deletions(-) diff --git a/src/ralph/access_cards/admin.py b/src/ralph/access_cards/admin.py index f56105b955..3554a175b0 100644 --- a/src/ralph/access_cards/admin.py +++ b/src/ralph/access_cards/admin.py @@ -1,8 +1,8 @@ from django.utils.translation import ugettext_lazy as _ from ralph.access_cards.models import AccessCard, AccessZone -from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/accessories/admin.py b/src/ralph/accessories/admin.py index 4fa10d5721..f7c32eb480 100644 --- a/src/ralph/accessories/admin.py +++ b/src/ralph/accessories/admin.py @@ -1,8 +1,8 @@ from django.utils.translation import ugettext_lazy as _ from ralph.accessories.models import Accessory, AccessoryUser -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.lib.transitions.admin import TransitionAdminMixin diff --git a/src/ralph/accessories/models.py b/src/ralph/accessories/models.py index fd3d382efa..28d2eadf7d 100644 --- a/src/ralph/accessories/models.py +++ b/src/ralph/accessories/models.py @@ -1,4 +1,3 @@ -from reversion import revisions as reversion from dj.choices import Choices from django import forms from django.conf import settings @@ -8,6 +7,7 @@ from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ from mptt.fields import TreeForeignKey +from reversion import revisions as reversion from ralph.accounts.models import RalphUser, Regionalizable from ralph.assets.models import Category, Manufacturer @@ -18,6 +18,7 @@ from ralph.lib.transitions.fields import TransitionField from ralph.lib.transitions.models import TransitionWorkflowBaseWithPermissions + _SELECT_USED_ACCESSORY_QUERY = """ SELECT COALESCE(SUM({assignment_table}.{quantity_column}), 0) FROM {assignment_table} diff --git a/src/ralph/accounts/admin.py b/src/ralph/accounts/admin.py index f7b605476c..869daa1b68 100644 --- a/src/ralph/accounts/admin.py +++ b/src/ralph/accounts/admin.py @@ -14,10 +14,9 @@ from django.utils.translation import ugettext_lazy as _ from ralph.accounts.models import RalphUser, Region, Team -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register from ralph.admin.helpers import getattr_dunder -from ralph.admin.mixins import RalphAdminFormMixin +from ralph.admin.mixins import RalphAdmin, RalphAdminFormMixin from ralph.admin.views.extra import RalphDetailView from ralph.back_office.models import BackOfficeAsset, BackOfficeAssetStatus from ralph.lib.table.table import Table diff --git a/src/ralph/accounts/views.py b/src/ralph/accounts/views.py index cffc8a491f..acfa754752 100644 --- a/src/ralph/accounts/views.py +++ b/src/ralph/accounts/views.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from datetime import date -from reversion import revisions as reversion from django.conf import settings from django.contrib import messages from django.core.urlresolvers import reverse @@ -9,6 +8,7 @@ from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext_lazy as _ from django.views.generic import View +from reversion import revisions as reversion from ralph.accounts.admin import ( AssetList, diff --git a/src/ralph/admin/m2m.py b/src/ralph/admin/m2m.py index 29f373e88c..a1d6f5339d 100644 --- a/src/ralph/admin/m2m.py +++ b/src/ralph/admin/m2m.py @@ -55,8 +55,11 @@ class AuthorAdmin(admin.ModelAdmin): from django.utils.text import get_text_list from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphStackedInline, RalphTabularInline -from ralph.admin.mixins import RalphAdminForm +from ralph.admin.mixins import ( + RalphAdminForm, + RalphStackedInline, + RalphTabularInline +) class BaseInlineM2MFormset(BaseInlineFormSet): diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index ea6597e73d..ea446ec631 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -180,7 +180,8 @@ def _check_form(self, model): """ result = super()._check_form(model) if ( - hasattr(model, 'form') and not issubclass(model.form, RalphAdminFormMixin) + hasattr(model, 'form') and + not issubclass(model.form, RalphAdminFormMixin) ): result += admin.checks.must_inherit_from( parent='RalphAdminFormMixin', diff --git a/src/ralph/admin/tests/tests_functional.py b/src/ralph/admin/tests/tests_functional.py index 0c9c1d057c..edad1e2c98 100644 --- a/src/ralph/admin/tests/tests_functional.py +++ b/src/ralph/admin/tests/tests_functional.py @@ -6,8 +6,8 @@ from django.test import RequestFactory, TestCase from django.views.generic import View -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register_extra_view +from ralph.admin.mixins import RalphAdmin from ralph.admin.sites import ralph_site from ralph.admin.views.extra import RalphDetailView, RalphListView from ralph.admin.views.main import RalphChangeList diff --git a/src/ralph/api/serializers.py b/src/ralph/api/serializers.py index 8d393c87c5..781a6fd775 100644 --- a/src/ralph/api/serializers.py +++ b/src/ralph/api/serializers.py @@ -3,7 +3,6 @@ import operator from functools import reduce -from reversion import revisions as reversion from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import NON_FIELD_ERRORS, ObjectDoesNotExist from django.db import transaction @@ -14,10 +13,12 @@ ValidationError as RestFrameworkValidationError from rest_framework.settings import api_settings from rest_framework.utils import model_meta +from reversion import revisions as reversion from taggit_serializer.serializers import ( TaggitSerializer, TagListSerializerField ) + from ralph.api.fields import AbsoluteUrlField, ReversedChoiceField from ralph.api.relations import RalphHyperlinkedRelatedField, RalphRelatedField from ralph.lib.mixins.models import AdminAbsoluteUrlMixin, TaggableMixin diff --git a/src/ralph/api/tests/test_serializers.py b/src/ralph/api/tests/test_serializers.py index dcc95ffb46..5cb6cc9c9c 100644 --- a/src/ralph/api/tests/test_serializers.py +++ b/src/ralph/api/tests/test_serializers.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from reversion import revisions as reversion from dj.choices import Choices from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse from rest_framework.test import APIClient, APIRequestFactory +from reversion import revisions as reversion from ralph.accounts.tests.factories import RegionFactory from ralph.api.relations import RalphHyperlinkedRelatedField, RalphRelatedField diff --git a/src/ralph/assets/admin.py b/src/ralph/assets/admin.py index 9585bf6881..d6a05abffc 100644 --- a/src/ralph/assets/admin.py +++ b/src/ralph/assets/admin.py @@ -2,8 +2,8 @@ from django.db.models import Count from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin, RalphTabularInline from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin, RalphTabularInline from ralph.admin.views.extra import RalphDetailView from ralph.assets.models.assets import ( Asset, diff --git a/src/ralph/assets/models/assets.py b/src/ralph/assets/models/assets.py index ea7c14142c..3e7abecdf8 100644 --- a/src/ralph/assets/models/assets.py +++ b/src/ralph/assets/models/assets.py @@ -31,8 +31,7 @@ PriceMixin, TimeStampMixin ) -from ralph.lib.permissions.models import PermByFieldMixin -from ralph.lib.permissions.models import PermissionsBase +from ralph.lib.permissions.models import PermByFieldMixin, PermissionsBase logger = logging.getLogger(__name__) diff --git a/src/ralph/assets/models/base.py b/src/ralph/assets/models/base.py index 323409046b..53c985f867 100644 --- a/src/ralph/assets/models/base.py +++ b/src/ralph/assets/models/base.py @@ -11,8 +11,7 @@ WithCustomFieldsMixin ) from ralph.lib.mixins.models import TaggableMixin, TimeStampMixin -from ralph.lib.permissions.models import PermByFieldMixin -from ralph.lib.permissions.models import PermissionsBase +from ralph.lib.permissions.models import PermByFieldMixin, PermissionsBase from ralph.lib.polymorphic.models import ( Polymorphic, PolymorphicBase, diff --git a/src/ralph/back_office/admin.py b/src/ralph/back_office/admin.py index 4bf1801cbd..0664f43841 100644 --- a/src/ralph/back_office/admin.py +++ b/src/ralph/back_office/admin.py @@ -4,10 +4,13 @@ from django.conf import settings from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import LiquidatedStatusFilter, TagsListFilter -from ralph.admin.mixins import BulkEditChangeListMixin +from ralph.admin.mixins import ( + BulkEditChangeListMixin, + RalphAdmin, + RalphTabularInline +) from ralph.admin.sites import ralph_site from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.admin.views.multiadd import MulitiAddAdminMixin diff --git a/src/ralph/dashboards/admin.py b/src/ralph/dashboards/admin.py index 93b9fcb5ce..8f269f6829 100644 --- a/src/ralph/dashboards/admin.py +++ b/src/ralph/dashboards/admin.py @@ -7,9 +7,8 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register -from ralph.admin.mixins import RalphAdminForm +from ralph.admin.mixins import RalphAdmin, RalphAdminForm from ralph.dashboards.models import Dashboard, Graph diff --git a/src/ralph/data_center/admin.py b/src/ralph/data_center/admin.py index ae4702dbb7..327c0b315d 100644 --- a/src/ralph/data_center/admin.py +++ b/src/ralph/data_center/admin.py @@ -11,7 +11,6 @@ from django.utils.translation import ugettext_lazy as _ from ralph.admin import filters -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import ( BaseObjectHostnameFilter, @@ -26,7 +25,11 @@ ) from ralph.admin.helpers import generate_html_link from ralph.admin.m2m import RalphTabularM2MInline -from ralph.admin.mixins import BulkEditChangeListMixin +from ralph.admin.mixins import ( + BulkEditChangeListMixin, + RalphAdmin, + RalphTabularInline +) from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.admin.views.main import RalphChangeList from ralph.admin.views.multiadd import MulitiAddAdminMixin diff --git a/src/ralph/deployment/admin.py b/src/ralph/deployment/admin.py index db907b9ede..21f9110bf6 100644 --- a/src/ralph/deployment/admin.py +++ b/src/ralph/deployment/admin.py @@ -1,7 +1,7 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin from ralph.deployment.forms import PrebootConfigurationForm from ralph.deployment.models import ( Deployment, diff --git a/src/ralph/dhcp/admin.py b/src/ralph/dhcp/admin.py index 48cf7f3537..63f51073b4 100644 --- a/src/ralph/dhcp/admin.py +++ b/src/ralph/dhcp/admin.py @@ -2,8 +2,8 @@ from django.template.defaultfilters import date, timesince_filter from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.dhcp.models import ( DHCPServer, DNSServer, diff --git a/src/ralph/domains/admin.py b/src/ralph/domains/admin.py index 66c4ffc20f..d710b91cd2 100644 --- a/src/ralph/domains/admin.py +++ b/src/ralph/domains/admin.py @@ -2,9 +2,9 @@ from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import DateListFilter +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.attachments.admin import AttachmentsMixin from ralph.data_importer.resources import DomainContractResource, DomainResource from ralph.domains.forms import DomainContractForm, DomainForm diff --git a/src/ralph/lib/custom_fields/admin.py b/src/ralph/lib/custom_fields/admin.py index 3caae171e8..e5ea708cca 100644 --- a/src/ralph/lib/custom_fields/admin.py +++ b/src/ralph/lib/custom_fields/admin.py @@ -4,8 +4,7 @@ from django.contrib.contenttypes.models import ContentType from ralph.admin.decorators import register -from ralph.admin.mixins import RalphAdmin -from ralph.admin.mixins import RalphGenericTabularInline +from ralph.admin.mixins import RalphAdmin, RalphGenericTabularInline from ralph.lib.custom_fields.forms import ( CustomFieldValueForm, CustomFieldValueFormSet, diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index 5b2228082c..c5c8580dbb 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -4,10 +4,10 @@ from django.contrib.contenttypes.fields import ( create_generic_related_manager, - GenericRelation, + GenericRelation ) from django.contrib.contenttypes.models import ContentType -from django.db import connection, models +from django.db import models from django.db.models.fields.related import OneToOneRel from ralph.admin.helpers import get_field_by_relation_path, getattr_dunder @@ -174,13 +174,6 @@ def __get__(self, instance, instance_type=None): superclass, rel_model ) - qn = connection.ops.quote_name - content_type = ContentType.objects.db_manager( - instance._state.db - ).get_for_model( - instance, for_concrete_model=self.for_concrete_model) - - join_cols = self.field.get_joining_columns(reverse_join=True)[0] manager = RelatedManager( instance=instance, ) diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index 05d5f595e6..72dcdf7e65 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -78,7 +78,6 @@ def __init__(self, *args, **kwargs): super(NUMPFieldMixIn, self).__init__(*args, **kwargs) self.fields_to_ignore = fields_to_ignore if fields_to_ignore is not None else ('help_text', 'verbose_name') - def deconstruct(self): name, path, args, kwargs = super(NUMPFieldMixIn, self).deconstruct() diff --git a/src/ralph/lib/permissions/api.py b/src/ralph/lib/permissions/api.py index 9ddecc0066..7fc5d83bb5 100644 --- a/src/ralph/lib/permissions/api.py +++ b/src/ralph/lib/permissions/api.py @@ -11,7 +11,10 @@ from rest_framework.filters import BaseFilterBackend from rest_framework.permissions import IsAuthenticated as DRFIsAuthenticated -from ralph.lib.permissions.models import PermByFieldMixin, PermissionsForObjectMixin +from ralph.lib.permissions.models import ( + PermByFieldMixin, + PermissionsForObjectMixin +) ADD_PERM = ['%(app_label)s.add_%(model_name)s'] CHANGE_PERM = ['%(app_label)s.change_%(model_name)s'] diff --git a/src/ralph/lib/transitions/admin.py b/src/ralph/lib/transitions/admin.py index 41398b3923..1efa0b7cea 100644 --- a/src/ralph/lib/transitions/admin.py +++ b/src/ralph/lib/transitions/admin.py @@ -9,8 +9,8 @@ from django.utils.functional import curry from django.utils.http import urlencode -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin from ralph.admin.views.extra import RalphDetailView from ralph.helpers import get_model_view_url_name from ralph.lib.transitions.forms import TransitionForm diff --git a/src/ralph/lib/transitions/checks.py b/src/ralph/lib/transitions/checks.py index 7d05a4b874..6fdf8f4b4d 100644 --- a/src/ralph/lib/transitions/checks.py +++ b/src/ralph/lib/transitions/checks.py @@ -2,9 +2,7 @@ from django.core.checks import Error from django.db.utils import DatabaseError -from django.template.loader import TemplateDoesNotExist -from django.template.loader import get_template - +from django.template.loader import get_template, TemplateDoesNotExist logger = logging.getLogger(__name__) diff --git a/src/ralph/lib/transitions/models.py b/src/ralph/lib/transitions/models.py index 034daa10c2..61e8daa75c 100644 --- a/src/ralph/lib/transitions/models.py +++ b/src/ralph/lib/transitions/models.py @@ -4,7 +4,6 @@ import logging from collections import defaultdict -from reversion import revisions as reversion from dj.choices import Choices from django import forms from django.conf import settings @@ -25,6 +24,7 @@ from django.utils.text import slugify from django.utils.translation import ugettext_lazy as _ from django_extensions.db.fields.json import JSONField +from reversion import revisions as reversion from ralph.admin.helpers import ( get_content_type_for_model, diff --git a/src/ralph/licences/admin.py b/src/ralph/licences/admin.py index 1fa34c4dc6..f8c9873d0e 100644 --- a/src/ralph/licences/admin.py +++ b/src/ralph/licences/admin.py @@ -1,10 +1,13 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import TagsListFilter -from ralph.admin.mixins import BulkEditChangeListMixin +from ralph.admin.mixins import ( + BulkEditChangeListMixin, + RalphAdmin, + RalphTabularInline +) from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.assets.invoice_report import InvoiceReportMixin from ralph.attachments.admin import AttachmentsMixin diff --git a/src/ralph/licences/models.py b/src/ralph/licences/models.py index 9632c24da1..d0e2383d86 100644 --- a/src/ralph/licences/models.py +++ b/src/ralph/licences/models.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- """SAM module models.""" -from reversion import revisions as reversion from django.conf import settings from django.core.exceptions import ValidationError from django.db import models from django.db.models import Prefetch, Sum from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ +from reversion import revisions as reversion from ralph.accounts.models import Regionalizable from ralph.admin.helpers import getattr_dunder diff --git a/src/ralph/networks/admin.py b/src/ralph/networks/admin.py index dcb31f3fd8..5768860210 100644 --- a/src/ralph/networks/admin.py +++ b/src/ralph/networks/admin.py @@ -4,11 +4,10 @@ from django.utils.html import escape from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register from ralph.admin.filters import RelatedAutocompleteFieldListFilter from ralph.admin.helpers import CastToInteger -from ralph.admin.mixins import RalphMPTTAdmin +from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin from ralph.admin.views.main import RalphChangeList from ralph.assets.models import BaseObject from ralph.data_importer import resources diff --git a/src/ralph/networks/forms.py b/src/ralph/networks/forms.py index 5f7fd3a87e..7dd62f47f4 100755 --- a/src/ralph/networks/forms.py +++ b/src/ralph/networks/forms.py @@ -99,7 +99,11 @@ class SimpleNetworkForm(EthernetLockDeleteForm): modified/deleted. """ hostname = CharFormFieldWithAutoStrip(label='Hostname', required=False) - address = forms.GenericIPAddressField(label='IP address', required=False, protocol='IPv4') + address = forms.GenericIPAddressField( + label='IP address', + required=False, + protocol='IPv4' + ) ip_fields = ['hostname', 'address'] diff --git a/src/ralph/networks/views.py b/src/ralph/networks/views.py index 347653f0d8..b85deedce4 100644 --- a/src/ralph/networks/views.py +++ b/src/ralph/networks/views.py @@ -1,7 +1,7 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphTabularInline from ralph.admin.m2m import RalphTabularM2MInline +from ralph.admin.mixins import RalphTabularInline from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.assets.models.components import Ethernet from ralph.lib.table.table import TableWithUrl diff --git a/src/ralph/operations/admin.py b/src/ralph/operations/admin.py index 42f448d275..b127ba052a 100644 --- a/src/ralph/operations/admin.py +++ b/src/ralph/operations/admin.py @@ -5,9 +5,8 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphMPTTAdmin from ralph.admin.decorators import register -from ralph.admin.mixins import RalphAdminForm +from ralph.admin.mixins import RalphAdmin, RalphAdminForm, RalphMPTTAdmin from ralph.admin.views.main import RalphChangeList from ralph.admin.widgets import AdminDateTimeWidget from ralph.assets.models import BaseObject diff --git a/src/ralph/reports/admin.py b/src/ralph/reports/admin.py index dc0a8393f2..6df109fc11 100644 --- a/src/ralph/reports/admin.py +++ b/src/ralph/reports/admin.py @@ -1,5 +1,5 @@ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.reports.forms import ReportTemplateFormset from ralph.reports.models import Report, ReportLanguage, ReportTemplate diff --git a/src/ralph/security/views.py b/src/ralph/security/views.py index 8f0b0c0038..9c5d293411 100644 --- a/src/ralph/security/views.py +++ b/src/ralph/security/views.py @@ -7,14 +7,13 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.helpers import get_admin_url +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.sites import ralph_site from ralph.admin.views.extra import RalphDetailView from ralph.security.models import SecurityScan, Vulnerability - logger = logging.getLogger(__name__) diff --git a/src/ralph/sim_cards/admin.py b/src/ralph/sim_cards/admin.py index f2a48a836d..7e5e60f849 100644 --- a/src/ralph/sim_cards/admin.py +++ b/src/ralph/sim_cards/admin.py @@ -1,8 +1,11 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register -from ralph.admin.mixins import BulkEditChangeListMixin, RalphAdminMixin +from ralph.admin.mixins import ( + BulkEditChangeListMixin, + RalphAdmin, + RalphAdminMixin +) from ralph.admin.views.multiadd import MulitiAddAdminMixin from ralph.lib.transitions.admin import TransitionAdminMixin from ralph.sim_cards.forms import SIMCardForm diff --git a/src/ralph/ssl_certificates/admin.py b/src/ralph/ssl_certificates/admin.py index 65a04a9d11..c2d6a16e31 100644 --- a/src/ralph/ssl_certificates/admin.py +++ b/src/ralph/ssl_certificates/admin.py @@ -1,8 +1,8 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register from ralph.admin.filters import DateListFilter +from ralph.admin.mixins import RalphAdmin from ralph.attachments.admin import AttachmentsMixin from ralph.ssl_certificates.forms import SSLCertificateForm from ralph.ssl_certificates.models import SSLCertificate diff --git a/src/ralph/supports/admin.py b/src/ralph/supports/admin.py index 0327c9b6d0..db220a4c0a 100644 --- a/src/ralph/supports/admin.py +++ b/src/ralph/supports/admin.py @@ -4,11 +4,14 @@ from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import TagsListFilter from ralph.admin.helpers import generate_html_link -from ralph.admin.mixins import BulkEditChangeListMixin +from ralph.admin.mixins import ( + BulkEditChangeListMixin, + RalphAdmin, + RalphTabularInline +) from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.attachments.admin import AttachmentsMixin from ralph.data_importer import resources diff --git a/src/ralph/tests/admin.py b/src/ralph/tests/admin.py index 0c79f68c0b..743cef0e4c 100644 --- a/src/ralph/tests/admin.py +++ b/src/ralph/tests/admin.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin from ralph.admin.decorators import register from ralph.admin.m2m import RalphTabularM2MInline +from ralph.admin.mixins import RalphAdmin from ralph.attachments.admin import AttachmentsMixin from ralph.lib.transitions.admin import TransitionAdminMixin from ralph.networks.views import NetworkInline diff --git a/src/ralph/tests/mixins.py b/src/ralph/tests/mixins.py index 2a054b08c7..aedd084143 100644 --- a/src/ralph/tests/mixins.py +++ b/src/ralph/tests/mixins.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- import sys from imp import reload +from importlib import import_module from django.conf import settings from django.core.urlresolvers import clear_url_caches -from importlib import import_module from ralph.tests.factories import UserFactory diff --git a/src/ralph/trade_marks/admin.py b/src/ralph/trade_marks/admin.py index e0be597a14..1da56f0073 100644 --- a/src/ralph/trade_marks/admin.py +++ b/src/ralph/trade_marks/admin.py @@ -3,7 +3,6 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import ( ChoicesListFilter, @@ -11,6 +10,7 @@ DateListFilter, RelatedAutocompleteFieldListFilter ) +from ralph.admin.mixins import RalphAdmin, RalphTabularInline from ralph.admin.views.extra import RalphDetailViewAdmin from ralph.attachments.admin import AttachmentsMixin from ralph.trade_marks.forms import ( diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index 38c5f27088..b4a6f18b8d 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -6,9 +6,9 @@ from django.db.models import Count, Prefetch from django.utils.translation import ugettext_lazy as _ -from ralph.admin.mixins import RalphAdmin, RalphAdminForm, RalphTabularInline from ralph.admin.decorators import register from ralph.admin.filters import BaseObjectHostnameFilter, TagsListFilter +from ralph.admin.mixins import RalphAdmin, RalphAdminForm, RalphTabularInline from ralph.assets.models import BaseObject from ralph.assets.models.components import Ethernet from ralph.assets.views import ComponentsAdminView, RalphDetailViewAdmin @@ -34,7 +34,8 @@ CloudProject, CloudProvider, VirtualServer, - VirtualServerType) + VirtualServerType +) if settings.ENABLE_DNSAAS_INTEGRATION: from ralph.dns.views import DNSView diff --git a/src/ralph/virtual/management/commands/openstack_sync.py b/src/ralph/virtual/management/commands/openstack_sync.py index 8189c55509..20dfd27bf2 100644 --- a/src/ralph/virtual/management/commands/openstack_sync.py +++ b/src/ralph/virtual/management/commands/openstack_sync.py @@ -5,11 +5,11 @@ from enum import auto, Enum from functools import lru_cache -from reversion import revisions from django.conf import settings from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from django.core.management.base import BaseCommand from django.db import IntegrityError, transaction +from reversion import revisions from ralph.data_center.models.physical import DataCenterAsset from ralph.lib.openstack.client import ( From a5210741021faa38d0dbe91c8aacf4776d76e3ab Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Thu, 2 May 2024 12:31:28 +0200 Subject: [PATCH 07/45] Fix user_password_change and bump pyflakes --- requirements/code_style.txt | 3 ++- src/ralph/accounts/admin.py | 5 +++-- src/ralph/lib/mixins/fields.py | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/requirements/code_style.txt b/requirements/code_style.txt index 65148d97ee..52e99b140f 100644 --- a/requirements/code_style.txt +++ b/requirements/code_style.txt @@ -1,2 +1,3 @@ flake8==3.0.4 -isort==4.2.5 \ No newline at end of file +isort==4.2.5 +pyflakes==1.5.0 diff --git a/src/ralph/accounts/admin.py b/src/ralph/accounts/admin.py index 869daa1b68..becc75c4f1 100644 --- a/src/ralph/accounts/admin.py +++ b/src/ralph/accounts/admin.py @@ -12,6 +12,7 @@ from django.forms.models import model_to_dict from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ +from reversion import revisions as reversion from ralph.accounts.models import RalphUser, Region, Team from ralph.admin.decorators import register @@ -338,8 +339,8 @@ def user_change_password(self, request, id, form_url=''): if not self.has_change_permission(request, obj=user): raise PermissionDenied - - return super().user_change_password(request, id, form_url) + with reversion.create_revision(): + return super().user_change_password(request, id, form_url) @register(Group) diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index 72dcdf7e65..30978cd9e6 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -76,7 +76,9 @@ class NUMPFieldMixIn(object): def __init__(self, *args, **kwargs): fields_to_ignore = kwargs.pop('fields_to_ignore', None) super(NUMPFieldMixIn, self).__init__(*args, **kwargs) - self.fields_to_ignore = fields_to_ignore if fields_to_ignore is not None else ('help_text', 'verbose_name') + self.fields_to_ignore = fields_to_ignore if ( + fields_to_ignore is not None + ) else ('help_text', 'verbose_name') def deconstruct(self): name, path, args, kwargs = super(NUMPFieldMixIn, self).deconstruct() From 3028f8debe3ab1e055a00d4bb97b727d58ec0f83 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Thu, 2 May 2024 15:46:57 +0200 Subject: [PATCH 08/45] Fix some tests and flake --- src/ralph/data_center/tests/test_view.py | 7 ++++--- src/ralph/data_importer/tests/test_fields.py | 6 +++--- src/ralph/lib/metrics/middlewares.py | 8 ++++---- src/ralph/lib/transitions/views.py | 2 +- src/ralph/settings/base.py | 4 +++- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/ralph/data_center/tests/test_view.py b/src/ralph/data_center/tests/test_view.py index d78cb117e2..d4df78e0f2 100644 --- a/src/ralph/data_center/tests/test_view.py +++ b/src/ralph/data_center/tests/test_view.py @@ -39,7 +39,7 @@ class DataCenterAssetViewTest(ClientMixin, TestCase): def test_changelist_view(self): self.login_as_user() DataCenterAssetFullFactory.create_batch(10) - with self.assertNumQueries(16): + with self.assertNumQueries(20): self.client.get( reverse('admin:data_center_datacenterasset_changelist'), ) @@ -54,7 +54,7 @@ def test_changelist_view(self): VirtualServerFullFactory.create_batch(5) CloudHostFullFactory.create_batch(4) ClusterFactory.create_batch(4) - with self.assertNumQueries(19): + with self.assertNumQueries(21): result = self.client.get( reverse('admin:data_center_dchost_changelist'), ) @@ -323,7 +323,8 @@ def test_should_add_physical_hosts_to_dictionary(self): def test_should_add_clusters_to_dictionary(self): cluster = ContentType.objects.get_for_model(Cluster) self.view.object.clusters.add( - BaseObjectCluster(cluster=ClusterFactory()) + BaseObjectCluster(cluster=ClusterFactory()), + bulk=False ) related_objects = {} self.view._add_clusters(related_objects) diff --git a/src/ralph/data_importer/tests/test_fields.py b/src/ralph/data_importer/tests/test_fields.py index 0074ab16d2..f5474d2818 100644 --- a/src/ralph/data_importer/tests/test_fields.py +++ b/src/ralph/data_importer/tests/test_fields.py @@ -134,7 +134,7 @@ def test_through_field_only_add(self): self.assertEqual(self.licence.base_objects.all().count(), 4) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -151,7 +151,7 @@ def test_through_field_only_remove(self): self.assertEqual(self.licence.base_objects.all().count(), 1) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -172,7 +172,7 @@ def test_through_field_add_and_remove(self): ) self.assertEqual(self.licence.base_objects.all().count(), 3) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) diff --git a/src/ralph/lib/metrics/middlewares.py b/src/ralph/lib/metrics/middlewares.py index bd20592578..ca1a0a377a 100644 --- a/src/ralph/lib/metrics/middlewares.py +++ b/src/ralph/lib/metrics/middlewares.py @@ -53,8 +53,8 @@ class QueryLogEntry: - sql: str - duration: float + sql: str # noqa + duration: float # noqa def __init__(self, sql: str, duration: float): self.sql = sql, @@ -164,8 +164,8 @@ def _collect_metrics(self, request, response): # processing time end_resources, end_time = getrusage(RUSAGE_SELF), time.monotonic() real_time = (end_time - request._request_start_time) * 1000 - sys_time = (end_resources.ru_stime - request._start_resources.ru_stime) * 1000 - user_time = (end_resources.ru_utime - request._start_resources.ru_utime) * 1000 + sys_time = (end_resources.ru_stime - request._start_resources.ru_stime) * 1000 # noqa + user_time = (end_resources.ru_utime - request._start_resources.ru_utime) * 1000 # noqa cpu_time = sys_time + user_time queries_time = sum(stat.duration for stat in query_stats) * 1000 diff --git a/src/ralph/lib/transitions/views.py b/src/ralph/lib/transitions/views.py index 4b88e5b9cb..4b2b91aca8 100644 --- a/src/ralph/lib/transitions/views.py +++ b/src/ralph/lib/transitions/views.py @@ -76,7 +76,7 @@ def _objects_are_valid(self): def get_template_names(self): template_names = super().get_template_names() - template_names.insert(0, self.transition.template_name) + template_names.insert(1, self.transition.template_name) return template_names @property diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index a665bb666a..c22855e0bb 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -9,7 +9,9 @@ from ralph.settings.hooks import HOOKS_CONFIGURATION # noqa: F401 -SILENCED_SYSTEM_CHECKS = ['models.E006'] # TODO fix +SILENCED_SYSTEM_CHECKS = ['models.E006'] # TODO fix + + def bool_from_env(var, default: bool=False) -> bool: """Helper for converting env string into boolean. From 1fabbf626a015cc5c61b555924d2d327b202efc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 11:26:36 +0200 Subject: [PATCH 09/45] Fix lookup --- src/ralph/admin/mixins.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index ea446ec631..95491c0985 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -213,6 +213,9 @@ def _check_absolute_url(self, model): class DashboardChangelistMixin(object): + # TODO(Django-1.11) remove and check if test_patch_deadline_filters_hosts passes + def lookup_allowed(self, *args, **kwargs): + return True def _is_graph_preview_view(self, request): return request.GET.get('graph-query', '') From 7afc62193539a247d199a6f86b56c5eeabde1aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 11:34:21 +0200 Subject: [PATCH 10/45] Add missing migrations --- .../migrations/0007_auto_20240506_1128.py | 21 ++++++++++++ .../migrations/0035_auto_20240506_1128.py | 22 ++++++++++++ .../migrations/0007_auto_20240506_1128.py | 34 +++++++++++++++++++ .../migrations/0003_auto_20240506_1133.py | 34 +++++++++++++++++++ .../migrations/0007_auto_20240506_1128.py | 22 ++++++++++++ .../migrations/0009_auto_20240506_1128.py | 22 ++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 src/ralph/accounts/migrations/0007_auto_20240506_1128.py create mode 100644 src/ralph/assets/migrations/0035_auto_20240506_1128.py create mode 100644 src/ralph/deployment/migrations/0007_auto_20240506_1128.py create mode 100644 src/ralph/lib/polymorphic/tests/migrations/0003_auto_20240506_1133.py create mode 100644 src/ralph/licences/migrations/0007_auto_20240506_1128.py create mode 100644 src/ralph/supports/migrations/0009_auto_20240506_1128.py diff --git a/src/ralph/accounts/migrations/0007_auto_20240506_1128.py b/src/ralph/accounts/migrations/0007_auto_20240506_1128.py new file mode 100644 index 0000000000..80aef8bd63 --- /dev/null +++ b/src/ralph/accounts/migrations/0007_auto_20240506_1128.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:28 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0006_remove_ralphuser_gender'), + ] + + operations = [ + migrations.AlterField( + model_name='ralphuser', + name='username', + field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username'), + ), + ] diff --git a/src/ralph/assets/migrations/0035_auto_20240506_1128.py b/src/ralph/assets/migrations/0035_auto_20240506_1128.py new file mode 100644 index 0000000000..d503f760cb --- /dev/null +++ b/src/ralph/assets/migrations/0035_auto_20240506_1128.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:28 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0034_auto_20240304_1511'), + ] + + operations = [ + migrations.AlterModelManagers( + name='baseobject', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/deployment/migrations/0007_auto_20240506_1128.py b/src/ralph/deployment/migrations/0007_auto_20240506_1128.py new file mode 100644 index 0000000000..45d73d537c --- /dev/null +++ b/src/ralph/deployment/migrations/0007_auto_20240506_1128.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:28 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('deployment', '0006_auto_20211019_1456'), + ] + + operations = [ + migrations.AlterModelManagers( + name='prebootconfiguration', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='prebootfile', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='prebootitem', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/lib/polymorphic/tests/migrations/0003_auto_20240506_1133.py b/src/ralph/lib/polymorphic/tests/migrations/0003_auto_20240506_1133.py new file mode 100644 index 0000000000..dc2ce82887 --- /dev/null +++ b/src/ralph/lib/polymorphic/tests/migrations/0003_auto_20240506_1133.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:33 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('polymorphic_tests', '0002_somem2mmodel'), + ] + + operations = [ + migrations.AlterModelManagers( + name='polymorphicmodelbasetest', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='polymorphicmodeltest', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='polymorphicmodeltest2', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/licences/migrations/0007_auto_20240506_1128.py b/src/ralph/licences/migrations/0007_auto_20240506_1128.py new file mode 100644 index 0000000000..f3d89135f9 --- /dev/null +++ b/src/ralph/licences/migrations/0007_auto_20240506_1128.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:28 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('licences', '0006_auto_20200909_1115'), + ] + + operations = [ + migrations.AlterModelManagers( + name='licence', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/supports/migrations/0009_auto_20240506_1128.py b/src/ralph/supports/migrations/0009_auto_20240506_1128.py new file mode 100644 index 0000000000..5638dab1a2 --- /dev/null +++ b/src/ralph/supports/migrations/0009_auto_20240506_1128.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 11:28 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('supports', '0008_auto_20200909_1012'), + ] + + operations = [ + migrations.AlterModelManagers( + name='support', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] From b64efa44186d8902ef478f9bc49cbda7be82fc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 11:40:50 +0200 Subject: [PATCH 11/45] Fix flake --- src/ralph/admin/mixins.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index 95491c0985..23a0b7d5d0 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -213,7 +213,8 @@ def _check_absolute_url(self, model): class DashboardChangelistMixin(object): - # TODO(Django-1.11) remove and check if test_patch_deadline_filters_hosts passes + # TODO(Django-1.11) remove and check if + # test_patch_deadline_filters_hosts passes def lookup_allowed(self, *args, **kwargs): return True From a07bc6ce4603bf05cbdefc6d0134a99864e6c2b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 13:18:18 +0200 Subject: [PATCH 12/45] Fix managers in migrations. Fix error with content type id --- .../migrations/0035_auto_20240506_1128.py | 4 +++- src/ralph/data_importer/tests/test_fields.py | 6 +++--- .../migrations/0007_auto_20240506_1128.py | 8 +++++--- src/ralph/lib/custom_fields/fields.py | 3 +-- src/ralph/lib/polymorphic/models.py | 18 ++++++++++++------ .../migrations/0007_auto_20240506_1128.py | 4 +++- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/ralph/assets/migrations/0035_auto_20240506_1128.py b/src/ralph/assets/migrations/0035_auto_20240506_1128.py index d503f760cb..3f252879a4 100644 --- a/src/ralph/assets/migrations/0035_auto_20240506_1128.py +++ b/src/ralph/assets/migrations/0035_auto_20240506_1128.py @@ -5,6 +5,8 @@ from django.db import migrations import django.db.models.manager +from ralph.assets.models.base import BaseObjectPolymorphicQuerySet + class Migration(migrations.Migration): @@ -16,7 +18,7 @@ class Migration(migrations.Migration): migrations.AlterModelManagers( name='baseobject', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), ], ), ] diff --git a/src/ralph/data_importer/tests/test_fields.py b/src/ralph/data_importer/tests/test_fields.py index f5474d2818..0074ab16d2 100644 --- a/src/ralph/data_importer/tests/test_fields.py +++ b/src/ralph/data_importer/tests/test_fields.py @@ -134,7 +134,7 @@ def test_through_field_only_add(self): self.assertEqual(self.licence.base_objects.all().count(), 4) self.assertCountEqual( - [bo.pk for bo in self.licence.base_objects.all()], ids + self.licence.base_objects.values_list('pk', flat=True), ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -151,7 +151,7 @@ def test_through_field_only_remove(self): self.assertEqual(self.licence.base_objects.all().count(), 1) self.assertCountEqual( - [bo.pk for bo in self.licence.base_objects.all()], ids + self.licence.base_objects.values_list('pk', flat=True), ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -172,7 +172,7 @@ def test_through_field_add_and_remove(self): ) self.assertEqual(self.licence.base_objects.all().count(), 3) self.assertCountEqual( - [bo.pk for bo in self.licence.base_objects.all()], ids + self.licence.base_objects.values_list('pk', flat=True), ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) diff --git a/src/ralph/deployment/migrations/0007_auto_20240506_1128.py b/src/ralph/deployment/migrations/0007_auto_20240506_1128.py index 45d73d537c..7b5fa219c1 100644 --- a/src/ralph/deployment/migrations/0007_auto_20240506_1128.py +++ b/src/ralph/deployment/migrations/0007_auto_20240506_1128.py @@ -5,6 +5,8 @@ from django.db import migrations import django.db.models.manager +from ralph.lib.polymorphic.models import PolymorphicQuerySet + class Migration(migrations.Migration): @@ -16,19 +18,19 @@ class Migration(migrations.Migration): migrations.AlterModelManagers( name='prebootconfiguration', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', PolymorphicQuerySet.as_manager()), ], ), migrations.AlterModelManagers( name='prebootfile', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', PolymorphicQuerySet.as_manager()), ], ), migrations.AlterModelManagers( name='prebootitem', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', PolymorphicQuerySet.as_manager()), ], ), ] diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index c5c8580dbb..ac34fb95bd 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -147,8 +147,7 @@ def values_list(self, *fields): ) -class ReverseGenericRelatedObjectsWithInheritanceDescriptor(): - +class ReverseGenericRelatedObjectsWithInheritanceDescriptor: def __init__(self, field, for_concrete_model=True): """ imported from ReverseGenericRelatedObjectsDescriptor diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index 5a6aca2f2e..af2f304dbb 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -42,22 +42,28 @@ def iterator(self): """ # if this is final-level model, don't check for descendants - just # return original queryset result + if not getattr(self.model, '_polymorphic_descendants', []): yield from super().iterator() return result = [] - content_types_ids = set() + content_types_ids = set() # type: set[int] select_related = None + if self.query.select_related: select_related = self.query.select_related self.query.select_related = False + objs = [obj for obj in super().iterator()] + for obj in objs: + try: + content_types_ids.add(obj.content_type_id) + result.append(( + obj.content_type_id, obj.pk) + ) + except: # noqa + pass - for obj in super().iterator(): - content_types_ids.add(obj.content_type_id) - result.append(( - obj.content_type_id, obj.pk) - ) # store original order of items by PK pks_order = [r[1] for r in result] # WARNING! sorting result (by content type) breaks original order of diff --git a/src/ralph/licences/migrations/0007_auto_20240506_1128.py b/src/ralph/licences/migrations/0007_auto_20240506_1128.py index f3d89135f9..a5fd4d835f 100644 --- a/src/ralph/licences/migrations/0007_auto_20240506_1128.py +++ b/src/ralph/licences/migrations/0007_auto_20240506_1128.py @@ -5,6 +5,8 @@ from django.db import migrations import django.db.models.manager +from ralph.assets.models.base import BaseObjectPolymorphicQuerySet + class Migration(migrations.Migration): @@ -16,7 +18,7 @@ class Migration(migrations.Migration): migrations.AlterModelManagers( name='licence', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), ], ), ] From dcfcb53914eb484d41b73d007be5e1f72954d503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 13:21:57 +0200 Subject: [PATCH 13/45] Fix --- .../migrations/0036_auto_20240506_1321.py | 22 ++++++++++++ .../migrations/0008_auto_20240506_1321.py | 34 +++++++++++++++++++ src/ralph/lib/polymorphic/models.py | 2 +- .../migrations/0008_auto_20240506_1321.py | 22 ++++++++++++ .../migrations/0009_auto_20240506_1128.py | 4 ++- .../migrations/0010_auto_20240506_1321.py | 22 ++++++++++++ 6 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 src/ralph/assets/migrations/0036_auto_20240506_1321.py create mode 100644 src/ralph/deployment/migrations/0008_auto_20240506_1321.py create mode 100644 src/ralph/licences/migrations/0008_auto_20240506_1321.py create mode 100644 src/ralph/supports/migrations/0010_auto_20240506_1321.py diff --git a/src/ralph/assets/migrations/0036_auto_20240506_1321.py b/src/ralph/assets/migrations/0036_auto_20240506_1321.py new file mode 100644 index 0000000000..6ecaccce69 --- /dev/null +++ b/src/ralph/assets/migrations/0036_auto_20240506_1321.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 13:21 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0035_auto_20240506_1128'), + ] + + operations = [ + migrations.AlterModelManagers( + name='baseobject', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/deployment/migrations/0008_auto_20240506_1321.py b/src/ralph/deployment/migrations/0008_auto_20240506_1321.py new file mode 100644 index 0000000000..e7187ea0b7 --- /dev/null +++ b/src/ralph/deployment/migrations/0008_auto_20240506_1321.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 13:21 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('deployment', '0007_auto_20240506_1128'), + ] + + operations = [ + migrations.AlterModelManagers( + name='prebootconfiguration', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='prebootfile', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + migrations.AlterModelManagers( + name='prebootitem', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index af2f304dbb..ea7ef776fe 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -33,7 +33,7 @@ def __init__(self, *args, **kwargs): self._polymorphic_filter_kwargs = {} super().__init__(*args, **kwargs) - def iterator(self): + def iterator(self): # noqa """ Override iterator: - Iterate for all objects and collected ID diff --git a/src/ralph/licences/migrations/0008_auto_20240506_1321.py b/src/ralph/licences/migrations/0008_auto_20240506_1321.py new file mode 100644 index 0000000000..ce411d4063 --- /dev/null +++ b/src/ralph/licences/migrations/0008_auto_20240506_1321.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 13:21 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('licences', '0007_auto_20240506_1128'), + ] + + operations = [ + migrations.AlterModelManagers( + name='licence', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] diff --git a/src/ralph/supports/migrations/0009_auto_20240506_1128.py b/src/ralph/supports/migrations/0009_auto_20240506_1128.py index 5638dab1a2..54015d6256 100644 --- a/src/ralph/supports/migrations/0009_auto_20240506_1128.py +++ b/src/ralph/supports/migrations/0009_auto_20240506_1128.py @@ -5,6 +5,8 @@ from django.db import migrations import django.db.models.manager +from ralph.assets.models.base import BaseObjectPolymorphicQuerySet + class Migration(migrations.Migration): @@ -16,7 +18,7 @@ class Migration(migrations.Migration): migrations.AlterModelManagers( name='support', managers=[ - ('polymorphic_objects', django.db.models.manager.Manager()), + ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), ], ), ] diff --git a/src/ralph/supports/migrations/0010_auto_20240506_1321.py b/src/ralph/supports/migrations/0010_auto_20240506_1321.py new file mode 100644 index 0000000000..334dcb9837 --- /dev/null +++ b/src/ralph/supports/migrations/0010_auto_20240506_1321.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.13 on 2024-05-06 13:21 +from __future__ import unicode_literals + +from django.db import migrations +import django.db.models.manager + + +class Migration(migrations.Migration): + + dependencies = [ + ('supports', '0009_auto_20240506_1128'), + ] + + operations = [ + migrations.AlterModelManagers( + name='support', + managers=[ + ('polymorphic_objects', django.db.models.manager.Manager()), + ], + ), + ] From 63f897b7b503e6fa0b8d09956b316f1b1b192e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 13:35:28 +0200 Subject: [PATCH 14/45] Fix data_importer tests --- src/ralph/data_importer/tests/test_fields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ralph/data_importer/tests/test_fields.py b/src/ralph/data_importer/tests/test_fields.py index 0074ab16d2..f5474d2818 100644 --- a/src/ralph/data_importer/tests/test_fields.py +++ b/src/ralph/data_importer/tests/test_fields.py @@ -134,7 +134,7 @@ def test_through_field_only_add(self): self.assertEqual(self.licence.base_objects.all().count(), 4) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -151,7 +151,7 @@ def test_through_field_only_remove(self): self.assertEqual(self.licence.base_objects.all().count(), 1) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) @@ -172,7 +172,7 @@ def test_through_field_add_and_remove(self): ) self.assertEqual(self.licence.base_objects.all().count(), 3) self.assertCountEqual( - self.licence.base_objects.values_list('pk', flat=True), ids + [bo.pk for bo in self.licence.base_objects.all()], ids ) # Make sure it doesn't touch other licences self.assertEqual(self.licence2.base_objects.all().count(), 2) From bb2c870a8909c764ea977e0b5c049e284f50e66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Mon, 6 May 2024 16:34:55 +0200 Subject: [PATCH 15/45] Clean up migrations --- .../migrations/0035_auto_20240506_1128.py | 24 ------------- ...506_1321.py => 0035_auto_20240506_1633.py} | 4 +-- .../migrations/0007_auto_20240506_1128.py | 36 ------------------- ...506_1321.py => 0007_auto_20240506_1633.py} | 4 +-- .../migrations/0007_auto_20240506_1128.py | 24 ------------- ...506_1321.py => 0007_auto_20240506_1633.py} | 4 +-- src/ralph/signals.py | 2 -- .../migrations/0009_auto_20240506_1128.py | 24 ------------- ...506_1321.py => 0009_auto_20240506_1633.py} | 4 +-- 9 files changed, 8 insertions(+), 118 deletions(-) delete mode 100644 src/ralph/assets/migrations/0035_auto_20240506_1128.py rename src/ralph/assets/migrations/{0036_auto_20240506_1321.py => 0035_auto_20240506_1633.py} (81%) delete mode 100644 src/ralph/deployment/migrations/0007_auto_20240506_1128.py rename src/ralph/deployment/migrations/{0008_auto_20240506_1321.py => 0007_auto_20240506_1633.py} (89%) delete mode 100644 src/ralph/licences/migrations/0007_auto_20240506_1128.py rename src/ralph/licences/migrations/{0008_auto_20240506_1321.py => 0007_auto_20240506_1633.py} (81%) delete mode 100644 src/ralph/supports/migrations/0009_auto_20240506_1128.py rename src/ralph/supports/migrations/{0010_auto_20240506_1321.py => 0009_auto_20240506_1633.py} (81%) diff --git a/src/ralph/assets/migrations/0035_auto_20240506_1128.py b/src/ralph/assets/migrations/0035_auto_20240506_1128.py deleted file mode 100644 index 3f252879a4..0000000000 --- a/src/ralph/assets/migrations/0035_auto_20240506_1128.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 11:28 -from __future__ import unicode_literals - -from django.db import migrations -import django.db.models.manager - -from ralph.assets.models.base import BaseObjectPolymorphicQuerySet - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0034_auto_20240304_1511'), - ] - - operations = [ - migrations.AlterModelManagers( - name='baseobject', - managers=[ - ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), - ], - ), - ] diff --git a/src/ralph/assets/migrations/0036_auto_20240506_1321.py b/src/ralph/assets/migrations/0035_auto_20240506_1633.py similarity index 81% rename from src/ralph/assets/migrations/0036_auto_20240506_1321.py rename to src/ralph/assets/migrations/0035_auto_20240506_1633.py index 6ecaccce69..fb3d93e631 100644 --- a/src/ralph/assets/migrations/0036_auto_20240506_1321.py +++ b/src/ralph/assets/migrations/0035_auto_20240506_1633.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 13:21 +# Generated by Django 1.9.13 on 2024-05-06 16:33 from __future__ import unicode_literals from django.db import migrations @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ - ('assets', '0035_auto_20240506_1128'), + ('assets', '0034_auto_20240304_1511'), ] operations = [ diff --git a/src/ralph/deployment/migrations/0007_auto_20240506_1128.py b/src/ralph/deployment/migrations/0007_auto_20240506_1128.py deleted file mode 100644 index 7b5fa219c1..0000000000 --- a/src/ralph/deployment/migrations/0007_auto_20240506_1128.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 11:28 -from __future__ import unicode_literals - -from django.db import migrations -import django.db.models.manager - -from ralph.lib.polymorphic.models import PolymorphicQuerySet - - -class Migration(migrations.Migration): - - dependencies = [ - ('deployment', '0006_auto_20211019_1456'), - ] - - operations = [ - migrations.AlterModelManagers( - name='prebootconfiguration', - managers=[ - ('polymorphic_objects', PolymorphicQuerySet.as_manager()), - ], - ), - migrations.AlterModelManagers( - name='prebootfile', - managers=[ - ('polymorphic_objects', PolymorphicQuerySet.as_manager()), - ], - ), - migrations.AlterModelManagers( - name='prebootitem', - managers=[ - ('polymorphic_objects', PolymorphicQuerySet.as_manager()), - ], - ), - ] diff --git a/src/ralph/deployment/migrations/0008_auto_20240506_1321.py b/src/ralph/deployment/migrations/0007_auto_20240506_1633.py similarity index 89% rename from src/ralph/deployment/migrations/0008_auto_20240506_1321.py rename to src/ralph/deployment/migrations/0007_auto_20240506_1633.py index e7187ea0b7..70a0dbeb64 100644 --- a/src/ralph/deployment/migrations/0008_auto_20240506_1321.py +++ b/src/ralph/deployment/migrations/0007_auto_20240506_1633.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 13:21 +# Generated by Django 1.9.13 on 2024-05-06 16:33 from __future__ import unicode_literals from django.db import migrations @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ - ('deployment', '0007_auto_20240506_1128'), + ('deployment', '0006_auto_20211019_1456'), ] operations = [ diff --git a/src/ralph/licences/migrations/0007_auto_20240506_1128.py b/src/ralph/licences/migrations/0007_auto_20240506_1128.py deleted file mode 100644 index a5fd4d835f..0000000000 --- a/src/ralph/licences/migrations/0007_auto_20240506_1128.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 11:28 -from __future__ import unicode_literals - -from django.db import migrations -import django.db.models.manager - -from ralph.assets.models.base import BaseObjectPolymorphicQuerySet - - -class Migration(migrations.Migration): - - dependencies = [ - ('licences', '0006_auto_20200909_1115'), - ] - - operations = [ - migrations.AlterModelManagers( - name='licence', - managers=[ - ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), - ], - ), - ] diff --git a/src/ralph/licences/migrations/0008_auto_20240506_1321.py b/src/ralph/licences/migrations/0007_auto_20240506_1633.py similarity index 81% rename from src/ralph/licences/migrations/0008_auto_20240506_1321.py rename to src/ralph/licences/migrations/0007_auto_20240506_1633.py index ce411d4063..ed4b7e13b8 100644 --- a/src/ralph/licences/migrations/0008_auto_20240506_1321.py +++ b/src/ralph/licences/migrations/0007_auto_20240506_1633.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 13:21 +# Generated by Django 1.9.13 on 2024-05-06 16:33 from __future__ import unicode_literals from django.db import migrations @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ - ('licences', '0007_auto_20240506_1128'), + ('licences', '0006_auto_20200909_1115'), ] operations = [ diff --git a/src/ralph/signals.py b/src/ralph/signals.py index 830d52d5cb..2ac27932c4 100644 --- a/src/ralph/signals.py +++ b/src/ralph/signals.py @@ -52,6 +52,4 @@ def wrapper(): func(instance) setattr(instance, called_already_attr, True) - # TODO(mkurek): replace connection by transaction after upgrading to - # Django 1.9 transaction.on_commit(wrapper) diff --git a/src/ralph/supports/migrations/0009_auto_20240506_1128.py b/src/ralph/supports/migrations/0009_auto_20240506_1128.py deleted file mode 100644 index 54015d6256..0000000000 --- a/src/ralph/supports/migrations/0009_auto_20240506_1128.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 11:28 -from __future__ import unicode_literals - -from django.db import migrations -import django.db.models.manager - -from ralph.assets.models.base import BaseObjectPolymorphicQuerySet - - -class Migration(migrations.Migration): - - dependencies = [ - ('supports', '0008_auto_20200909_1012'), - ] - - operations = [ - migrations.AlterModelManagers( - name='support', - managers=[ - ('polymorphic_objects', BaseObjectPolymorphicQuerySet.as_manager()), - ], - ), - ] diff --git a/src/ralph/supports/migrations/0010_auto_20240506_1321.py b/src/ralph/supports/migrations/0009_auto_20240506_1633.py similarity index 81% rename from src/ralph/supports/migrations/0010_auto_20240506_1321.py rename to src/ralph/supports/migrations/0009_auto_20240506_1633.py index 334dcb9837..853f53829b 100644 --- a/src/ralph/supports/migrations/0010_auto_20240506_1321.py +++ b/src/ralph/supports/migrations/0009_auto_20240506_1633.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9.13 on 2024-05-06 13:21 +# Generated by Django 1.9.13 on 2024-05-06 16:33 from __future__ import unicode_literals from django.db import migrations @@ -9,7 +9,7 @@ class Migration(migrations.Migration): dependencies = [ - ('supports', '0009_auto_20240506_1128'), + ('supports', '0008_auto_20200909_1012'), ] operations = [ From 5bd289e8d8c74852c15b4bd896680e3c9954d611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 7 May 2024 11:58:08 +0200 Subject: [PATCH 16/45] WIP - migrate from deprectated get_... --- src/ralph/accounts/models.py | 4 ++- src/ralph/admin/m2m.py | 4 +-- src/ralph/api/serializers.py | 2 +- src/ralph/assets/_migration_helpers.py | 36 ++++++++++++---------- src/ralph/data_center/tests/test_models.py | 5 +-- src/ralph/lib/permissions/admin.py | 2 +- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/ralph/accounts/models.py b/src/ralph/accounts/models.py index bfd3a8286d..1748378607 100644 --- a/src/ralph/accounts/models.py +++ b/src/ralph/accounts/models.py @@ -5,6 +5,7 @@ from django.conf import settings from django.contrib.auth.models import AbstractUser from django.db import models +from django.db.models import Field from django.db.models.signals import post_save from django.dispatch import receiver from django.utils.encoding import force_bytes @@ -168,7 +169,8 @@ def save(self, *args, **kwargs): for field in ('country',): val = getattr(self, field) if val is None: - val = self._meta.get_field_by_name(field)[0].default + field_: Field = self._meta.get_field(field) + val = field_.default setattr(self, field, val) return super().save(*args, **kwargs) diff --git a/src/ralph/admin/m2m.py b/src/ralph/admin/m2m.py index a1d6f5339d..a6137700eb 100644 --- a/src/ralph/admin/m2m.py +++ b/src/ralph/admin/m2m.py @@ -129,8 +129,8 @@ def get_m2m(parent_model, model): """ # need to check on both sides (m2m field will be defined only in one of the # models) - for rel in parent_model._meta.get_all_related_many_to_many_objects(): - if issubclass(rel.related_model, model): + for rel in parent_model._meta.get_fields(include_hidden=True): + if rel.many_to_many and rel.auto_created and issubclass(rel.related_model, model): return rel.field for rel in parent_model._meta.many_to_many: diff --git a/src/ralph/api/serializers.py b/src/ralph/api/serializers.py index 781a6fd775..7dbf1fa450 100644 --- a/src/ralph/api/serializers.py +++ b/src/ralph/api/serializers.py @@ -176,7 +176,7 @@ class NestedMeta: # exclude some fields from nested serializer for field in NESTED_SERIALIZER_FIELDS_BLACKLIST: try: - relation_info.related_model._meta.get_field_by_name(field) + relation_info.related_model._meta.get_field(field) except exceptions.FieldDoesNotExist: pass else: diff --git a/src/ralph/assets/_migration_helpers.py b/src/ralph/assets/_migration_helpers.py index 306a5d4bd1..9e458c629f 100644 --- a/src/ralph/assets/_migration_helpers.py +++ b/src/ralph/assets/_migration_helpers.py @@ -65,23 +65,25 @@ def baseobject_migration( obj.save() # foreign keys - for relation in Model._meta.get_all_related_objects(local_only=True): - related_model = relation.related_model - relation_field = relation.field.attname - logger.info('Processing relation {}<->{} using field {}'.format( - model_str, related_model, relation_field - )) - relation_mapping = defaultdict(list) - for related_object in related_model._default_manager.values_list( - 'pk', relation_field - ): - relation_mapping[related_object[1]].append(related_object[0]) - for old_id, new_id in id_mapping.items(): - related_model._default_manager.filter( - pk__in=relation_mapping.get(old_id, []) - ).update( - **{relation_field: new_id} - ) + # migrated from deprecated get_all_related_objects(local_only=True) + for relation in Model._meta.get_fields(include_parents=False): + if (relation.one_to_many or relation.one_to_one) and relation.auto_created and not relation.concrete: + related_model = relation.related_model + relation_field = relation.field.attname + logger.info('Processing relation {}<->{} using field {}'.format( + model_str, related_model, relation_field + )) + relation_mapping = defaultdict(list) + for related_object in related_model._default_manager.values_list( + 'pk', relation_field + ): + relation_mapping[related_object[1]].append(related_object[0]) + for old_id, new_id in id_mapping.items(): + related_model._default_manager.filter( + pk__in=relation_mapping.get(old_id, []) + ).update( + **{relation_field: new_id} + ) # ImportedObjects ImportedObjects = apps.get_model('data_importer', 'ImportedObjects') diff --git a/src/ralph/data_center/tests/test_models.py b/src/ralph/data_center/tests/test_models.py index ee53299a4f..cbdc93dbe6 100644 --- a/src/ralph/data_center/tests/test_models.py +++ b/src/ralph/data_center/tests/test_models.py @@ -2,6 +2,7 @@ from ddt import data, ddt, unpack from django.conf import settings from django.core.exceptions import ValidationError +from django.db.models import Field from ralph.accounts.tests.factories import RegionFactory from ralph.back_office.models import BackOfficeAsset, BackOfficeAssetStatus @@ -169,7 +170,7 @@ def test_convert_to_backoffice_asset_uses_default_from_settings(self): ('16',), ) def test_should_pass_when_slot_no_is_correct(self, slot_no): - slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0] + slot_no_field: Field = self.dc_asset._meta.get_field('slot_no') slot_no_field.clean(slot_no, self.dc_asset) @unpack @@ -188,7 +189,7 @@ def test_should_pass_when_slot_no_is_correct(self, slot_no): def test_should_raise_validation_error_when_slot_no_is_incorrect( self, slot_no ): - slot_no_field = self.dc_asset._meta.get_field_by_name('slot_no')[0] + slot_no_field: Field = self.dc_asset._meta.get_field('slot_no') with self.assertRaises(ValidationError): slot_no_field.clean(slot_no, self.dc_asset) diff --git a/src/ralph/lib/permissions/admin.py b/src/ralph/lib/permissions/admin.py index 38377fe1e5..ebbcfbde55 100644 --- a/src/ralph/lib/permissions/admin.py +++ b/src/ralph/lib/permissions/admin.py @@ -28,7 +28,7 @@ def _has_access_to_field(self, field_name, request): this field. """ try: - self.model._meta.get_field_by_name(field_name) + self.model._meta.get_field(field_name) except FieldDoesNotExist: perm_field = getattr( ( From 37ece5a5150d309c4c39182322a9ef1b0216363e Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 7 May 2024 15:52:08 +0200 Subject: [PATCH 17/45] cleanup --- src/ralph/lib/custom_fields/fields.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index ac34fb95bd..c61c48bd65 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -1,7 +1,9 @@ import operator from collections import defaultdict from functools import reduce +from typing import Any +from dataclasses import dataclass from django.contrib.contenttypes.fields import ( create_generic_related_manager, GenericRelation @@ -147,6 +149,12 @@ def values_list(self, *fields): ) +@dataclass +class RelModel: + model: Any # noqa + field: CustomFieldsWithInheritanceRelation # noqa + + class ReverseGenericRelatedObjectsWithInheritanceDescriptor: def __init__(self, field, for_concrete_model=True): """ @@ -164,11 +172,9 @@ def __get__(self, instance, instance_type=None): """ if instance is None: return self - rel_model = self.field.rel.to - rel_model.model = self.field.rel.to - rel_model.field = self.field + rel_model = RelModel(model=self.field.rel.to, field=self.field) # difference here comparing to Django! - superclass = rel_model.inherited_objects.__class__ + superclass = rel_model.model.inherited_objects.__class__ RelatedManager = create_generic_related_manager_with_inheritance( superclass, rel_model ) From 21c46573fe1d1f0e4ca2424dbcbb9f081eeb68ce Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 7 May 2024 15:58:09 +0200 Subject: [PATCH 18/45] cleanup --- src/ralph/lib/custom_fields/fields.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index c61c48bd65..fa59ffb672 100644 --- a/src/ralph/lib/custom_fields/fields.py +++ b/src/ralph/lib/custom_fields/fields.py @@ -3,7 +3,6 @@ from functools import reduce from typing import Any -from dataclasses import dataclass from django.contrib.contenttypes.fields import ( create_generic_related_manager, GenericRelation @@ -149,10 +148,10 @@ def values_list(self, *fields): ) -@dataclass class RelModel: - model: Any # noqa - field: CustomFieldsWithInheritanceRelation # noqa + def __init__(self, model: Any, field: CustomFieldsWithInheritanceRelation): + self.model = model + self.field = field class ReverseGenericRelatedObjectsWithInheritanceDescriptor: From e97463e8d381b2356bbe2b115aedfe10f393251b Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 7 May 2024 16:06:55 +0200 Subject: [PATCH 19/45] cleanup --- src/ralph/lib/polymorphic/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index ea7ef776fe..e6c35119b1 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -61,7 +61,7 @@ def iterator(self): # noqa result.append(( obj.content_type_id, obj.pk) ) - except: # noqa + except AttributeError as e: # noqa pass # store original order of items by PK From aff1f477745e0ebe2e6e337e67db748f3025b548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 8 May 2024 10:50:52 +0200 Subject: [PATCH 20/45] Bump dependencies --- requirements/base.txt | 13 ++++++------ .../migrations/0008_auto_20240507_1422.py | 21 +++++++++++++++++++ src/ralph/api/routers.py | 2 +- src/ralph/lib/permissions/api.py | 3 +-- src/ralph/settings/base.py | 4 +++- 5 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 src/ralph/accounts/migrations/0008_auto_20240507_1422.py diff --git a/requirements/base.txt b/requirements/base.txt index 2f76f21cb2..2a1592947d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,21 +1,21 @@ -r openstack.txt -r hermes.txt -Django==1.9.13 +Django==1.10.1 dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 -django-import-export==0.4.2 +django-import-export==0.6.0 django-money==0.15.1 py-moneyed==1.2 django-mptt==0.8.7 -django-reversion==1.10.0 +django-reversion==2.0 django-rq==2.0 django-sitetree==1.7.0 -django-taggit==0.18.1 -django-taggit-serializer==0.1.5 +django-taggit==0.22.2 +django-taggit-serializer==0.1.7 django-threadlocals==0.8 django-cryptography==0.3 -djangorestframework==3.2.2 +djangorestframework==3.4.0 djangorestframework_xml==1.2.0 drf-nested-routers==0.11.1 Markdown<3.0 # headerid extension removed in 3.0 - see #3313 for details @@ -36,4 +36,3 @@ Faker==0.9.0 openpyxl==2.4.0 typing==3.6.6 Pillow==6.2.2 - diff --git a/src/ralph/accounts/migrations/0008_auto_20240507_1422.py b/src/ralph/accounts/migrations/0008_auto_20240507_1422.py new file mode 100644 index 0000000000..634fb4f39b --- /dev/null +++ b/src/ralph/accounts/migrations/0008_auto_20240507_1422.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.1 on 2024-05-07 14:22 +from __future__ import unicode_literals + +import django.contrib.auth.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0007_auto_20240506_1128'), + ] + + operations = [ + migrations.AlterField( + model_name='ralphuser', + name='username', + field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username'), + ), + ] diff --git a/src/ralph/api/routers.py b/src/ralph/api/routers.py index d48df23c65..92a482533f 100644 --- a/src/ralph/api/routers.py +++ b/src/ralph/api/routers.py @@ -18,7 +18,7 @@ class RalphRouter(NestedCustomFieldsRouterMixin, routers.DefaultRouter): # skip .json style formatting suffixes in urls include_format_suffixes = False - def get_api_root_view(self): + def get_api_root_view(self, schema_urls=None): api_root_dict = {} list_name = self.routes[0].name for prefix, viewset, basename in self.registry: diff --git a/src/ralph/lib/permissions/api.py b/src/ralph/lib/permissions/api.py index 7fc5d83bb5..5aa40f14a7 100644 --- a/src/ralph/lib/permissions/api.py +++ b/src/ralph/lib/permissions/api.py @@ -5,7 +5,6 @@ from collections import OrderedDict from django.utils.translation import ugettext_lazy as _ -from rest_framework.compat import get_model_name from rest_framework.exceptions import ValidationError from rest_framework.fields import empty from rest_framework.filters import BaseFilterBackend @@ -190,7 +189,7 @@ def get_required_permissions(self, method, model_cls): """ kwargs = { 'app_label': model_cls._meta.app_label, - 'model_name': get_model_name(model_cls) + 'model_name': model_cls._meta.model_name } return [perm % kwargs for perm in self.perms_map[method]] diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index c22855e0bb..0b5270fcc2 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -9,7 +9,9 @@ from ralph.settings.hooks import HOOKS_CONFIGURATION # noqa: F401 -SILENCED_SYSTEM_CHECKS = ['models.E006'] # TODO fix +SILENCED_SYSTEM_CHECKS = [] +SILENCED_SYSTEM_CHECKS += ['models.E006',] # TODO fix +# SILENCED_SYSTEM_CHECKS += ['admin.E013',] # TODO fix def bool_from_env(var, default: bool=False) -> bool: From d17ae9fb2ea6f85fab8675555623e2c7e0f697d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 8 May 2024 12:03:58 +0200 Subject: [PATCH 21/45] Adjust import-export --- requirements/base.txt | 2 +- src/ralph/data_importer/tests/test_export.py | 4 ++-- src/ralph/data_importer/widgets.py | 24 ++++++++++---------- src/ralph/lib/permissions/models.py | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 2a1592947d..15a9c8ee04 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -4,7 +4,7 @@ Django==1.10.1 dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 -django-import-export==0.6.0 +django-import-export==1.0.0 django-money==0.15.1 py-moneyed==1.2 django-mptt==0.8.7 diff --git a/src/ralph/data_importer/tests/test_export.py b/src/ralph/data_importer/tests/test_export.py index e420f175ac..ff79f2c034 100644 --- a/src/ralph/data_importer/tests/test_export.py +++ b/src/ralph/data_importer/tests/test_export.py @@ -50,7 +50,7 @@ def _export(self, model, filters=None): file_format = RawFormat() queryset = admin_class.get_export_queryset(request) - export_data = admin_class.get_export_data(file_format, queryset) + export_data = admin_class.get_export_data(file_format, queryset, request=request) return export_data def _init(self, num=10): @@ -118,7 +118,7 @@ def test_data_center_asset_export(self): def test_data_center_asset_export_with_parent_queries_count(self): self._test_queries_count(func=lambda: self._export( DataCenterAsset - )) + ), max_queries=12) def test_data_center_asset_export_with_parent(self): self._init(10) diff --git a/src/ralph/data_importer/widgets.py b/src/ralph/data_importer/widgets.py index 9230c52110..ba943b27e3 100644 --- a/src/ralph/data_importer/widgets.py +++ b/src/ralph/data_importer/widgets.py @@ -56,7 +56,7 @@ def clean(self, value): ) return result - def render(self, value): + def render(self, value, obj=None): if value: return value.username return '' @@ -72,7 +72,7 @@ def clean(self, value): usernames = value.split(self.separator) return get_user_model().objects.filter(username__in=usernames) - def render(self, value): + def render(self, value, obj=None): return self.separator.join([obj.username for obj in value.all()]) @@ -101,7 +101,7 @@ def clean(self, value): pk__in=value.split(self.separator) ) - def render(self, value): + def render(self, value, obj=None): return self.separator.join( [str(getattr(obj, self.through_field).pk) for obj in value.all()] ) @@ -109,13 +109,13 @@ def render(self, value): class ExportForeignKeyStrWidget(widgets.Widget): - def render(self, value): + def render(self, value, obj=None): return str(value) class ExportManyToManyStrWidget(widgets.ManyToManyWidget): - def render(self, value): + def render(self, value, obj=None): return self.separator.join([str(obj) for obj in value.all()]) @@ -124,7 +124,7 @@ class ExportManyToManyStrTroughWidget(ManyToManyThroughWidget): Exporter-equivalent of `ManyToManyThroughWidget` - return str of whole object instead of pk. """ - def render(self, value): + def render(self, value, obj=None): return self.separator.join( [str(getattr(obj, self.through_field)) for obj in value.all()] ) @@ -232,7 +232,7 @@ def clean(self, value): value = None return value - def render(self, value): + def render(self, value, obj=None): if value is None: return "" return "{}|{}".format( @@ -259,7 +259,7 @@ def clean(self, value): value = None return value - def render(self, value): + def render(self, value, obj=None): if value is None: return "" return value.service.uid @@ -280,12 +280,12 @@ class IPManagementWidget(widgets.ManyToManyWidget): def clean(self, value): return value - def render(self, value): + def render(self, value, obj=None): return value or '' class BaseObjectServiceNamesM2MWidget(widgets.ManyToManyWidget): - def render(self, value): + def render(self, value, obj=None): return self.separator.join([ bo.service.name if bo.service else '-' for bo in value.all() @@ -293,10 +293,10 @@ def render(self, value): class PriceAmountWidget(widgets.Widget): - def render(self, value): + def render(self, value, obj=None): return '{0:.2f}'.format(value.amount) class PriceCurrencyWidget(widgets.Widget): - def render(self, value): + def render(self, value, obj=None): return str(value.currency) diff --git a/src/ralph/lib/permissions/models.py b/src/ralph/lib/permissions/models.py index bdcd2e0202..e06e63aaf5 100644 --- a/src/ralph/lib/permissions/models.py +++ b/src/ralph/lib/permissions/models.py @@ -339,7 +339,7 @@ def create_permissions( if perms: perms.update(content_type=ctype) ctypes.add(ctype) - for perm in _get_all_permissions(klass._meta, ctype): + for perm in _get_all_permissions(klass._meta): searched_perms.append((ctype, perm)) # Find all the Permissions that have a content_type for a model we're From 095c29ce34f11fa51808ec2d9b60e88d3cc0238c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 8 May 2024 12:09:45 +0200 Subject: [PATCH 22/45] Adjust django-money ver --- requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/base.txt b/requirements/base.txt index 15a9c8ee04..73a47b6e72 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -5,7 +5,7 @@ dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 django-import-export==1.0.0 -django-money==0.15.1 +django-money==0.12 py-moneyed==1.2 django-mptt==0.8.7 django-reversion==2.0 From da8060f583c555d3581b4e804b9a28c41a14b018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 8 May 2024 14:29:45 +0200 Subject: [PATCH 23/45] Fix render --- src/ralph/lib/mixins/forms.py | 3 ++- src/ralph/reports/resources.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ralph/lib/mixins/forms.py b/src/ralph/lib/mixins/forms.py index a5997b1be0..81cf49dc64 100644 --- a/src/ralph/lib/mixins/forms.py +++ b/src/ralph/lib/mixins/forms.py @@ -43,9 +43,10 @@ def _get_other_field(self, name, value): def render(self, name, value, attrs=None, choices=()): show_other = value and value.get('value') == OTHER choice_value = (value.get('value') if value else '') or '' + self.choices = choices return '
{}{}
'.format( self.css_class, - super().render(name, choice_value, attrs=attrs, choices=choices), + super().render(name, choice_value, attrs=attrs), self._get_other_field(name, value) if show_other else '' ) diff --git a/src/ralph/reports/resources.py b/src/ralph/reports/resources.py index 71dfc698e3..97167d9c8d 100644 --- a/src/ralph/reports/resources.py +++ b/src/ralph/reports/resources.py @@ -17,7 +17,7 @@ class ChoiceWidget(Widget): def __init__(self, choice: Type[Choices]) -> None: self.choice = choice - def render(self, value): + def render(self, value, obj=None): if value: return self.choice.from_id(value).name else: From 664222dbe4ec16e647af912c29c2c63c99970287 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Fri, 10 May 2024 13:28:58 +0200 Subject: [PATCH 24/45] Fix imports --- src/ralph/accounts/ldap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ralph/accounts/ldap.py b/src/ralph/accounts/ldap.py index 005e3fa222..79aeceaabc 100644 --- a/src/ralph/accounts/ldap.py +++ b/src/ralph/accounts/ldap.py @@ -3,7 +3,6 @@ from dj.choices import Country from django.conf import settings -from django.contrib.auth.models import Group from django.dispatch import receiver from django.utils.encoding import force_text from django_auth_ldap.backend import _LDAPUser, LDAPSettings, populate_user @@ -56,6 +55,7 @@ def mirror_groups(self): self._user.groups.values_list('name', flat=True).iterator() ) if target_group_names != current_group_names: + from django.contrib.auth.models import Group logger.info('Modifing user groups: current = {}, target = {}'.format( ', '.join(current_group_names), ', '.join(target_group_names) )) From 7f7723edae7a1da35f866834cdee6fcc04f5e659 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 13 May 2024 13:40:33 +0200 Subject: [PATCH 25/45] Fix ldap imports --- src/ralph/accounts/ldap.py | 89 +--------------------------- src/ralph/accounts/ldap_helpers.py | 93 ++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 88 deletions(-) create mode 100644 src/ralph/accounts/ldap_helpers.py diff --git a/src/ralph/accounts/ldap.py b/src/ralph/accounts/ldap.py index 79aeceaabc..d8cdabe5bd 100644 --- a/src/ralph/accounts/ldap.py +++ b/src/ralph/accounts/ldap.py @@ -3,12 +3,10 @@ from dj.choices import Country from django.conf import settings +from django.contrib.auth.models import Group from django.dispatch import receiver from django.utils.encoding import force_text from django_auth_ldap.backend import _LDAPUser, LDAPSettings, populate_user -from django_auth_ldap.config import ActiveDirectoryGroupType - -from ralph.accounts.management.commands.ldap_sync import get_nested_groups logger = logging.getLogger(__name__) @@ -55,7 +53,6 @@ def mirror_groups(self): self._user.groups.values_list('name', flat=True).iterator() ) if target_group_names != current_group_names: - from django.contrib.auth.models import Group logger.info('Modifing user groups: current = {}, target = {}'.format( ', '.join(current_group_names), ', '.join(target_group_names) )) @@ -102,87 +99,3 @@ def manager_country_attribute_populate( user.country = Country.id_from_name(country.lower()) except ValueError: user.country = None - - -class MappedGroupOfNamesType(ActiveDirectoryGroupType): - """Provide group mappings described in project settings.""" - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._ldap_groups = None - - @property - def ldap_groups(self): - """ - Composition of flat LDAP groups (taken from `AUTH_LDAP_GROUP_MAPPING`) - and nested groups (taken from `AUTH_LDAP_NESTED_GROUPS`). - - Returns: dict with both flat and nested LDAP groups. - """ - if not self._ldap_groups: - logger.debug('Evaluating LDAP groupd from settings') - self._ldap_flat_groups = getattr( - settings, 'AUTH_LDAP_GROUP_MAPPING', {} - ) - self._ldap_nested_groups = getattr( - settings, 'AUTH_LDAP_NESTED_GROUPS', {} - ) - self._ldap_groups = self._ldap_flat_groups.copy() - self._ldap_groups.update(self._ldap_nested_groups) - return self._ldap_groups - - def _get_group(self, group_dn, ldap_user, group_search): - base_dn = group_search.base_dn - group_search.base_dn = force_text(group_dn) - group = group_search.execute(ldap_user.connection)[0] - group_search.base_dn = base_dn - return group - - def user_groups(self, ldap_user, group_search): - """Get groups which user belongs to.""" - group_map = [] - - def handle_groups(groups_dns): - """ - Compare user groups with groups accepted by Ralph - (`self.ldap_groups`) and for each in common get LDAP group - - Args: - groups_dns: set of user groups DNs - """ - for group_dn in groups_dns & set(self.ldap_groups.keys()): - group = self._get_group(group_dn, ldap_user, group_search) - group_map.append(group) - - username = ldap_user.attrs[settings.AUTH_LDAP_USER_USERNAME_ATTR][0] - - # handle flat groups first (to which user belongs directly) - try: - flat_groups_dns = set(map(force_text, ldap_user.attrs['memberOf'])) - except KeyError: - flat_groups_dns = set() - logger.info('Flat groups DNs for {}: {}'.format( - username, flat_groups_dns - )) - handle_groups(flat_groups_dns) - - # handle nested groups - nested_groups_dns = get_nested_groups()[1].get(username, set()) - logger.info('Nested groups DNs for {}: {}'.format( - username, nested_groups_dns - )) - handle_groups(nested_groups_dns) - return group_map - - def group_name_from_info(self, group_info): - """Map ldap group names into ralph names if mapping defined.""" - if self.ldap_groups: - for dn in group_info[1]['distinguishedname']: - mapped = self.ldap_groups.get(dn) - if mapped: - return mapped - # return original name if mapping not defined - else: - return super( - MappedGroupOfNamesType, - self - ).group_name_from_info(group_info) diff --git a/src/ralph/accounts/ldap_helpers.py b/src/ralph/accounts/ldap_helpers.py new file mode 100644 index 0000000000..2f7488ca9d --- /dev/null +++ b/src/ralph/accounts/ldap_helpers.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +import logging + +from django.conf import settings +from django.utils.encoding import force_text +from django_auth_ldap.config import ActiveDirectoryGroupType + + +logger = logging.getLogger(__name__) + + +class MappedGroupOfNamesType(ActiveDirectoryGroupType): + """Provide group mappings described in project settings.""" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._ldap_groups = None + + @property + def ldap_groups(self): + """ + Composition of flat LDAP groups (taken from `AUTH_LDAP_GROUP_MAPPING`) + and nested groups (taken from `AUTH_LDAP_NESTED_GROUPS`). + + Returns: dict with both flat and nested LDAP groups. + """ + if not self._ldap_groups: + logger.debug('Evaluating LDAP groupd from settings') + self._ldap_flat_groups = getattr( + settings, 'AUTH_LDAP_GROUP_MAPPING', {} + ) + self._ldap_nested_groups = getattr( + settings, 'AUTH_LDAP_NESTED_GROUPS', {} + ) + self._ldap_groups = self._ldap_flat_groups.copy() + self._ldap_groups.update(self._ldap_nested_groups) + return self._ldap_groups + + def _get_group(self, group_dn, ldap_user, group_search): + base_dn = group_search.base_dn + group_search.base_dn = force_text(group_dn) + group = group_search.execute(ldap_user.connection)[0] + group_search.base_dn = base_dn + return group + + def user_groups(self, ldap_user, group_search): + """Get groups which user belongs to.""" + group_map = [] + + def handle_groups(groups_dns): + """ + Compare user groups with groups accepted by Ralph + (`self.ldap_groups`) and for each in common get LDAP group + + Args: + groups_dns: set of user groups DNs + """ + for group_dn in groups_dns & set(self.ldap_groups.keys()): + group = self._get_group(group_dn, ldap_user, group_search) + group_map.append(group) + + username = ldap_user.attrs[settings.AUTH_LDAP_USER_USERNAME_ATTR][0] + + # handle flat groups first (to which user belongs directly) + try: + flat_groups_dns = set(map(force_text, ldap_user.attrs['memberOf'])) + except KeyError: + flat_groups_dns = set() + logger.info('Flat groups DNs for {}: {}'.format( + username, flat_groups_dns + )) + handle_groups(flat_groups_dns) + from ralph.accounts.management.commands.ldap_sync import get_nested_groups # noqa + # handle nested groups + nested_groups_dns = get_nested_groups()[1].get(username, set()) + logger.info('Nested groups DNs for {}: {}'.format( + username, nested_groups_dns + )) + handle_groups(nested_groups_dns) + return group_map + + def group_name_from_info(self, group_info): + """Map ldap group names into ralph names if mapping defined.""" + if self.ldap_groups: + for dn in group_info[1]['distinguishedname']: + mapped = self.ldap_groups.get(dn) + if mapped: + return mapped + # return original name if mapping not defined + else: + return super( + MappedGroupOfNamesType, + self + ).group_name_from_info(group_info) From 5809f3d546042fe1d0079d9f05693578a405bbb4 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 13 May 2024 17:07:53 +0200 Subject: [PATCH 26/45] Fix reversion import and bump Django --- requirements/base.txt | 2 +- src/ralph/admin/m2m.py | 2 +- src/ralph/api/tests/test_serializers.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 73a47b6e72..029eb67c84 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,6 +1,6 @@ -r openstack.txt -r hermes.txt -Django==1.10.1 +Django==1.10.8 dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 diff --git a/src/ralph/admin/m2m.py b/src/ralph/admin/m2m.py index a6137700eb..6389cb1fd5 100644 --- a/src/ralph/admin/m2m.py +++ b/src/ralph/admin/m2m.py @@ -146,7 +146,7 @@ def get_foreign_key_for_m2m(parent_model, m2m): parent_model: Django model for which admin inline is created m2m: ManyToManyField relation instance """ - for field in m2m.related.through._meta.fields: + for field in m2m.remote_field.through._meta.fields: if ( isinstance(field, ForeignKey) and issubclass(parent_model, field.rel.to) diff --git a/src/ralph/api/tests/test_serializers.py b/src/ralph/api/tests/test_serializers.py index 5cb6cc9c9c..2fc847af58 100644 --- a/src/ralph/api/tests/test_serializers.py +++ b/src/ralph/api/tests/test_serializers.py @@ -4,7 +4,7 @@ from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse from rest_framework.test import APIClient, APIRequestFactory -from reversion import revisions as reversion +from reversion.models import Version from ralph.accounts.tests.factories import RegionFactory from ralph.api.relations import RalphHyperlinkedRelatedField, RalphRelatedField @@ -99,7 +99,7 @@ def test_reversion_history_save(self): '/test-ralph-api/foos/', data={'bar': 'bar_name'} ) foo = Foo.objects.get(pk=response.data['id']) - history = reversion.get_for_object(foo) + history = Version.objects.get_for_object(foo) self.assertEqual(len(history), 1) self.assertIn('bar_name', history[0].serialized_data) @@ -108,7 +108,7 @@ def test_reversion_history_save(self): data={'bar': 'new_bar'} ) foo = Foo.objects.get(pk=response.data['id']) - history = reversion.get_for_object(foo) + history = Version.objects.get_for_object(foo) self.assertEqual(len(history), 2) self.assertIn('new_bar', history[0].serialized_data) @@ -124,7 +124,7 @@ def test_reversion_history_for_intermediary_model(self): base_object_licence = BaseObjectLicence.objects.get( pk=response.data['id'] ) - history = reversion.get_for_object(base_object_licence) + history = Version.objects.get_for_object(base_object_licence) self.assertEqual(len(history), 1) self.assertIn( '"licence": {}'.format(licence.id), history[0].serialized_data From 7e80230ae5ec82462ccf0fa77d9969ed0b7eb29e Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 14 May 2024 11:57:50 +0200 Subject: [PATCH 27/45] fix PermissionsForObjectMixin --- src/ralph/lib/permissions/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ralph/lib/permissions/models.py b/src/ralph/lib/permissions/models.py index e06e63aaf5..e2f05769bd 100644 --- a/src/ralph/lib/permissions/models.py +++ b/src/ralph/lib/permissions/models.py @@ -272,7 +272,7 @@ def has_permission_to_object(self, user): user_perms = self._permissions.has_access(user) if not user_perms: return True - return self._default_manager.filter( + return self.__class__.objects.filter( user_perms, pk=self.pk ).exists() From 529ccd5c6b2803e567936a8159c5c3c229c385f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 14 May 2024 13:06:49 +0200 Subject: [PATCH 28/45] Fix 500 when sorting ContentType --- src/ralph/admin/views/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ralph/admin/views/main.py b/src/ralph/admin/views/main.py index 0705295470..8d45df957e 100644 --- a/src/ralph/admin/views/main.py +++ b/src/ralph/admin/views/main.py @@ -35,7 +35,7 @@ def get_ordering_from_related_model_admin(self, prefix, field_name): return fields try: model_admin = admin_site._registry[field.field.rel.to] - except AttributeError: + except (AttributeError, KeyError): pass else: if all([model_admin, model_admin.ordering]): From 5351b00b7b6c3af11cb0de1313699114037f9691 Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Tue, 14 May 2024 13:32:00 +0200 Subject: [PATCH 29/45] Fix icon-unknown --- src/ralph/admin/templates/admin/edit_inline/tabular.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ralph/admin/templates/admin/edit_inline/tabular.html b/src/ralph/admin/templates/admin/edit_inline/tabular.html index c9ce5461ee..6a281ef532 100644 --- a/src/ralph/admin/templates/admin/edit_inline/tabular.html +++ b/src/ralph/admin/templates/admin/edit_inline/tabular.html @@ -17,7 +17,7 @@

{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}

{% if not field.widget.is_hidden %} {{ field.label|capfirst }} {% if field.help_text %} -  ({{ field.help_text|striptags }}) +  ({{ field.help_text|striptags }}) {% endif %} {% endif %} From 8a917a7599e2f9991017cfa37acce78f1493b731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 14 May 2024 14:11:39 +0200 Subject: [PATCH 30/45] Fix invalid literal for int() with base 10: 'PL' --- src/ralph/accounts/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ralph/accounts/models.py b/src/ralph/accounts/models.py index bfd3a8286d..b93a09e0b8 100644 --- a/src/ralph/accounts/models.py +++ b/src/ralph/accounts/models.py @@ -167,6 +167,8 @@ def save(self, *args, **kwargs): # set default values if None provided for field in ('country',): val = getattr(self, field) + if isinstance(val, str): + val = Country.from_name(val.lower()).id if val is None: val = self._meta.get_field_by_name(field)[0].default setattr(self, field, val) From 812d66693d4ba26a550564aaa43124b21fdd4658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 14 May 2024 14:45:26 +0200 Subject: [PATCH 31/45] Fix set country --- src/ralph/accounts/models.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ralph/accounts/models.py b/src/ralph/accounts/models.py index b93a09e0b8..8924e5f60c 100644 --- a/src/ralph/accounts/models.py +++ b/src/ralph/accounts/models.py @@ -164,14 +164,10 @@ def has_any_perms(self, perms, obj=None): return any([self.has_perm(p, obj=obj) for p in perms]) def save(self, *args, **kwargs): - # set default values if None provided - for field in ('country',): - val = getattr(self, field) - if isinstance(val, str): - val = Country.from_name(val.lower()).id - if val is None: - val = self._meta.get_field_by_name(field)[0].default - setattr(self, field, val) + if isinstance(self.country, str): + self.country = Country.from_name(self.country.lower()).id + elif self.country is None: + self.country = Country.pl.id return super().save(*args, **kwargs) @property From 1eb6ee9efd30d52e54e36848440c7220c1a41edc Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 14 May 2024 16:42:30 +0200 Subject: [PATCH 32/45] fix flake, fix ImportForeignKeyMixin --- requirements/base.txt | 2 +- src/ralph/admin/m2m.py | 3 ++- src/ralph/assets/_migration_helpers.py | 3 ++- src/ralph/data_importer/mixins.py | 2 +- src/ralph/lib/transitions/tests/test_actions.py | 2 +- src/ralph/networks/tests/test_api.py | 2 +- src/ralph/settings/base.py | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 029eb67c84..636c08b6a4 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -4,7 +4,7 @@ Django==1.10.8 dj.choices==0.11.0 django-extensions==1.7.5 django-filter==0.13.0 -django-import-export==1.0.0 +django-import-export==1.2.0 django-money==0.12 py-moneyed==1.2 django-mptt==0.8.7 diff --git a/src/ralph/admin/m2m.py b/src/ralph/admin/m2m.py index 6389cb1fd5..c47615ab15 100644 --- a/src/ralph/admin/m2m.py +++ b/src/ralph/admin/m2m.py @@ -130,7 +130,8 @@ def get_m2m(parent_model, model): # need to check on both sides (m2m field will be defined only in one of the # models) for rel in parent_model._meta.get_fields(include_hidden=True): - if rel.many_to_many and rel.auto_created and issubclass(rel.related_model, model): + if rel.many_to_many and rel.auto_created and \ + issubclass(rel.related_model, model): return rel.field for rel in parent_model._meta.many_to_many: diff --git a/src/ralph/assets/_migration_helpers.py b/src/ralph/assets/_migration_helpers.py index 9e458c629f..100279448b 100644 --- a/src/ralph/assets/_migration_helpers.py +++ b/src/ralph/assets/_migration_helpers.py @@ -67,7 +67,8 @@ def baseobject_migration( # foreign keys # migrated from deprecated get_all_related_objects(local_only=True) for relation in Model._meta.get_fields(include_parents=False): - if (relation.one_to_many or relation.one_to_one) and relation.auto_created and not relation.concrete: + if (relation.one_to_many or relation.one_to_one) and \ + relation.auto_created and not relation.concrete: related_model = relation.related_model relation_field = relation.field.attname logger.info('Processing relation {}<->{} using field {}'.format( diff --git a/src/ralph/data_importer/mixins.py b/src/ralph/data_importer/mixins.py index 44cf42dea4..2966c2f691 100644 --- a/src/ralph/data_importer/mixins.py +++ b/src/ralph/data_importer/mixins.py @@ -89,7 +89,7 @@ def get_or_init_instance(self, instance_loader, row): instance_loader, row ) - def after_save_instance(self, instance, dry_run): + def after_save_instance(self, instance, dry_run, *args, **kwargs): if not dry_run and self.old_object_pk: content_type = ContentType.objects.get_for_model(self._meta.model) ImportedObjects.objects.update_or_create( diff --git a/src/ralph/lib/transitions/tests/test_actions.py b/src/ralph/lib/transitions/tests/test_actions.py index d1c20f672f..9bf31b3ef4 100644 --- a/src/ralph/lib/transitions/tests/test_actions.py +++ b/src/ralph/lib/transitions/tests/test_actions.py @@ -126,7 +126,7 @@ def test_sync_api_validation_error(self): self.assertEqual(response.status_code, 400) self.assertEqual( response.data['user'], - ['This field is required.'] + ['This field may not be blank.'] ) def test_sync_gui(self): diff --git a/src/ralph/networks/tests/test_api.py b/src/ralph/networks/tests/test_api.py index fac610f8df..5b8fbb6196 100644 --- a/src/ralph/networks/tests/test_api.py +++ b/src/ralph/networks/tests/test_api.py @@ -96,7 +96,7 @@ def test_change_ip_address_already_occupied_should_not_pass(self): url = reverse('ipaddress-detail', args=(self.ip1.id,)) response = self.client.patch(url, format='json', data=data) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) - self.assertIn('This field must be unique.', response.data['address']) + self.assertIn('IPAddress with this IP address already exists.', response.data['address']) def test_change_ip_address_with_dhcp_exposition_should_not_pass(self): data = {'address': '127.0.0.3'} diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 0b5270fcc2..2233f1009c 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -10,7 +10,7 @@ from ralph.settings.hooks import HOOKS_CONFIGURATION # noqa: F401 SILENCED_SYSTEM_CHECKS = [] -SILENCED_SYSTEM_CHECKS += ['models.E006',] # TODO fix +SILENCED_SYSTEM_CHECKS += ['models.E006', ] # TODO fix # SILENCED_SYSTEM_CHECKS += ['admin.E013',] # TODO fix From 9f410fdd66e6f04b9f340fa2d0d6da92b130ec1f Mon Sep 17 00:00:00 2001 From: awieckowski Date: Tue, 14 May 2024 17:25:12 +0200 Subject: [PATCH 33/45] fix data importer widgets --- src/ralph/data_importer/widgets.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ralph/data_importer/widgets.py b/src/ralph/data_importer/widgets.py index ba943b27e3..92d3934b45 100644 --- a/src/ralph/data_importer/widgets.py +++ b/src/ralph/data_importer/widgets.py @@ -44,7 +44,7 @@ class UserWidget(widgets.ForeignKeyWidget): """Widget for Ralph User Foreign Key field.""" - def clean(self, value): + def clean(self, value, *args, **kwargs): result = None if value: result, created = get_user_model().objects.get_or_create( @@ -66,7 +66,7 @@ class UserManyToManyWidget(widgets.ManyToManyWidget): """Widget for many Ralph Users Foreign Key field.""" - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return get_user_model().objects.none() usernames = value.split(self.separator) @@ -94,7 +94,7 @@ def __init__(self, through_field, related_model, *args, **kwargs): self.related_model = related_model super().__init__(*args, **kwargs) - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return self.related_model.objects.none() return self.related_model.objects.filter( @@ -134,7 +134,7 @@ class BaseObjectManyToManyWidget(widgets.ManyToManyWidget): """Widget for BO/DC base objects.""" - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return self.model.objects.none() ids = value.split(self.separator) @@ -167,7 +167,7 @@ class BaseObjectWidget(widgets.ForeignKeyWidget): """Widget for BO/DC base objects.""" - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return None result = None @@ -193,7 +193,7 @@ class ImportedForeignKeyWidget(widgets.ForeignKeyWidget): """Widget for ForeignKey fields for which can not define unique.""" - def clean(self, value): + def clean(self, value, *args, **kwargs): if settings.MAP_IMPORTED_ID_TO_NEW_ID: if value: content_type, imported_obj = get_imported_obj( @@ -205,7 +205,7 @@ def clean(self, value): class NullStringWidget(widgets.CharWidget): - def clean(self, value): + def clean(self, value, *args, **kwargs): return super().clean(value) or None @@ -216,7 +216,7 @@ class AssetServiceEnvWidget(widgets.ForeignKeyWidget): CSV field format Service.name|Environment.name """ - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return None try: @@ -243,7 +243,7 @@ def render(self, value, obj=None): class AssetServiceUidWidget(widgets.ForeignKeyWidget): - def clean(self, value): + def clean(self, value, *args, **kwargs): if not value: return None try: @@ -277,7 +277,7 @@ class IPManagementWidget(widgets.ManyToManyWidget): ip. This because management ip is seperate model which can't be created wihtout DataCenterAsset (and DataCenterAsset is the result of importing). """ - def clean(self, value): + def clean(self, value, *args, **kwargs): return value def render(self, value, obj=None): From daa8310cc9b4be8ad328d12136acfc15a8c72160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 15 May 2024 13:54:53 +0200 Subject: [PATCH 34/45] Fix django-import-export compatibility --- src/ralph/data_importer/mixins.py | 2 +- src/ralph/settings/base.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ralph/data_importer/mixins.py b/src/ralph/data_importer/mixins.py index 2966c2f691..befa8e5ee1 100644 --- a/src/ralph/data_importer/mixins.py +++ b/src/ralph/data_importer/mixins.py @@ -89,7 +89,7 @@ def get_or_init_instance(self, instance_loader, row): instance_loader, row ) - def after_save_instance(self, instance, dry_run, *args, **kwargs): + def after_save_instance(self, instance, using_transactions: bool, dry_run: bool, *args, **kwargs): if not dry_run and self.old_object_pk: content_type = ContentType.objects.get_for_model(self._meta.model) ImportedObjects.objects.update_or_create( diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 2233f1009c..2042a44e0e 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -11,7 +11,6 @@ SILENCED_SYSTEM_CHECKS = [] SILENCED_SYSTEM_CHECKS += ['models.E006', ] # TODO fix -# SILENCED_SYSTEM_CHECKS += ['admin.E013',] # TODO fix def bool_from_env(var, default: bool=False) -> bool: From 3965ff03e6c261754b0211f5f1000581c4c78cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 15 May 2024 14:08:50 +0200 Subject: [PATCH 35/45] Build for any push --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 05794c40a5..d42383c1b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,7 +5,6 @@ name: CI # push or pull request events but only for the ng branch on: push: - branches: [ ng ] pull_request: branches: [ ng ] From 79eea7920b3af60c416b05fb795595f43632b83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 15 May 2024 14:28:41 +0200 Subject: [PATCH 36/45] Fix non-relational field in select_related --- src/ralph/virtual/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index b4a6f18b8d..7831367604 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -478,7 +478,8 @@ class CloudProjectAdmin(CustomFieldValueAdminMixin, RalphAdmin): fields = ['name', 'project_id', 'cloudprovider', 'service_env', 'tags', 'remarks', 'instances_count'] list_display = ['name', 'service_env', 'instances_count'] - list_select_related = ['cloudprovider__name', 'service_env__environment', + list_select_related = ['cloudprovider', + 'service_env__environment', 'service_env__service'] list_filter = ['service_env', 'cloudprovider', TagsListFilter] readonly_fields = ['name', 'project_id', 'cloudprovider', 'created', From 1112b755a8e317d44b068308a80b53ded8efc2b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Thu, 16 May 2024 11:55:54 +0200 Subject: [PATCH 37/45] Fix bad manager by making them even worse --- src/ralph/data_importer/fields.py | 4 ++-- src/ralph/data_importer/mixins.py | 10 ++++++++++ src/ralph/lib/mixins/models.py | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/ralph/data_importer/fields.py b/src/ralph/data_importer/fields.py index 138c95cb7b..9e010aa3f4 100644 --- a/src/ralph/data_importer/fields.py +++ b/src/ralph/data_importer/fields.py @@ -44,7 +44,7 @@ def __init__( self.through_to_field_name = through_to_field_name super().__init__(attribute, column_name, widget, readonly) - def save(self, obj, data): + def save(self, obj, data, is_m2m=False): if not self.readonly: value = data.get(self.column_name) current = set(self.widget.clean(value)) @@ -89,7 +89,7 @@ def save(self, obj, data): class PriceField(fields.Field): - def save(self, obj, data): + def save(self, obj, data, is_m2m=False): price = Money( data['price'], data.get('price_currency', DEFAULT_CURRENCY_CODE) diff --git a/src/ralph/data_importer/mixins.py b/src/ralph/data_importer/mixins.py index befa8e5ee1..62c6ffea08 100644 --- a/src/ralph/data_importer/mixins.py +++ b/src/ralph/data_importer/mixins.py @@ -97,3 +97,13 @@ def after_save_instance(self, instance, using_transactions: bool, dry_run: bool, old_object_pk=self.old_object_pk, defaults={'object_pk': instance.pk} ) + + def import_field(self, field, obj, data, is_m2m=False): + """ + Calls :meth:`import_export.fields.Field.save` if ``Field.attribute`` + and ``Field.column_name`` are found in ``data``. + """ + if field.column_name == 'management_ip': + field.save(obj, data, is_m2m=False) + elif field.attribute and field.column_name in data: + field.save(obj, data, is_m2m) diff --git a/src/ralph/lib/mixins/models.py b/src/ralph/lib/mixins/models.py index 333e7acfdb..75b85bd27c 100644 --- a/src/ralph/lib/mixins/models.py +++ b/src/ralph/lib/mixins/models.py @@ -4,7 +4,7 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from djmoney.models.fields import MoneyField -from taggit.managers import TaggableManager as TaggableManagerOriginal +from taggit.managers import TaggableManager as TaggableManagerOriginal, _TaggableManager from ralph.lib.mixins.fields import TaggitTagField from ralph.settings import DEFAULT_CURRENCY_CODE @@ -79,10 +79,22 @@ def get_absolute_url(self): ) +class ManagerOfManager(_TaggableManager): + def set(self, *tags, **kwargs): + def _flatten(nested_list): + for item in nested_list: + if isinstance(item, (list, models.QuerySet)): + yield from _flatten(item) + else: + yield item + flattened_tags = list(_flatten(tags)) + super().set(*flattened_tags, **kwargs) + + class TaggableManager(TaggableManagerOriginal): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + super().__init__(manager=ManagerOfManager, *args, **kwargs) self.manager.name = 'tags' def value_from_object(self, instance): From d5d2ea0e1847c2f5bc71b57707f31892ee96fb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Thu, 16 May 2024 12:26:39 +0200 Subject: [PATCH 38/45] Adjust num queries --- src/ralph/data_center/tests/test_view.py | 4 ++-- src/ralph/data_importer/tests/test_fields.py | 8 ++++---- src/ralph/lib/mixins/models.py | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ralph/data_center/tests/test_view.py b/src/ralph/data_center/tests/test_view.py index d4df78e0f2..0e320a997d 100644 --- a/src/ralph/data_center/tests/test_view.py +++ b/src/ralph/data_center/tests/test_view.py @@ -39,7 +39,7 @@ class DataCenterAssetViewTest(ClientMixin, TestCase): def test_changelist_view(self): self.login_as_user() DataCenterAssetFullFactory.create_batch(10) - with self.assertNumQueries(20): + with self.assertNumQueries(21): self.client.get( reverse('admin:data_center_datacenterasset_changelist'), ) @@ -54,7 +54,7 @@ def test_changelist_view(self): VirtualServerFullFactory.create_batch(5) CloudHostFullFactory.create_batch(4) ClusterFactory.create_batch(4) - with self.assertNumQueries(21): + with self.assertNumQueries(22): result = self.client.get( reverse('admin:data_center_dchost_changelist'), ) diff --git a/src/ralph/data_importer/tests/test_fields.py b/src/ralph/data_importer/tests/test_fields.py index f5474d2818..938d2268ae 100644 --- a/src/ralph/data_importer/tests/test_fields.py +++ b/src/ralph/data_importer/tests/test_fields.py @@ -69,7 +69,7 @@ def test_users_through_field(self): self.assertEqual(self.licence2.users.all().count(), 3) # Add and remove - with self.assertNumQueries(4): + with self.assertNumQueries(5): field.save( self.licence, {'users': ','.join([i.username for i in self.users])} @@ -88,7 +88,7 @@ def test_users_through_field(self): self.assertEqual(self.licence.users.all().count(), 5) # Remove - with self.assertNumQueries(3): + with self.assertNumQueries(4): field.save( self.licence, {'users': ','.join([i.username for i in users[:4]])} @@ -143,7 +143,7 @@ def test_through_field_only_remove(self): field = self._get_base_objects_through_field() self.assertEqual(self.licence.base_objects.all().count(), 2) ids = [self.back_office_assets[0].pk] - with self.assertNumQueries(3): + with self.assertNumQueries(4): field.save( self.licence, {'base_objects': ','.join(map(str, ids))} @@ -165,7 +165,7 @@ def test_through_field_add_and_remove(self): self.back_office_assets[3].pk, ] - with self.assertNumQueries(4): + with self.assertNumQueries(5): field.save( self.licence, {'base_objects': ','.join(map(str, ids))} diff --git a/src/ralph/lib/mixins/models.py b/src/ralph/lib/mixins/models.py index 75b85bd27c..8253e503db 100644 --- a/src/ralph/lib/mixins/models.py +++ b/src/ralph/lib/mixins/models.py @@ -4,7 +4,8 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from djmoney.models.fields import MoneyField -from taggit.managers import TaggableManager as TaggableManagerOriginal, _TaggableManager +from taggit.managers import TaggableManager as TaggableManagerOriginal +from taggit.managers import _TaggableManager # noqa from ralph.lib.mixins.fields import TaggitTagField from ralph.settings import DEFAULT_CURRENCY_CODE From 7a11b0eeca24d06c4887363ae98bd20cd5eef9a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Thu, 16 May 2024 12:35:41 +0200 Subject: [PATCH 39/45] Fix line length --- src/ralph/data_importer/mixins.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ralph/data_importer/mixins.py b/src/ralph/data_importer/mixins.py index 62c6ffea08..cd0ea70755 100644 --- a/src/ralph/data_importer/mixins.py +++ b/src/ralph/data_importer/mixins.py @@ -89,7 +89,14 @@ def get_or_init_instance(self, instance_loader, row): instance_loader, row ) - def after_save_instance(self, instance, using_transactions: bool, dry_run: bool, *args, **kwargs): + def after_save_instance( + self, + instance, + using_transactions: bool, + dry_run: bool, + *args, + **kwargs + ): if not dry_run and self.old_object_pk: content_type = ContentType.objects.get_for_model(self._meta.model) ImportedObjects.objects.update_or_create( From 9ad95409af29796de813471e884631f84debe33b Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Fri, 17 May 2024 13:46:05 +0200 Subject: [PATCH 40/45] Fix popup_response --- src/ralph/admin/static/auto-complete-helpers.js | 4 ---- src/ralph/admin/static/js/popup_response.js | 17 +++++++++++++++++ .../admin/templates/admin/popup_response.html | 17 ++++++----------- 3 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 src/ralph/admin/static/js/popup_response.js diff --git a/src/ralph/admin/static/auto-complete-helpers.js b/src/ralph/admin/static/auto-complete-helpers.js index d68c91a96d..3ea5f5add5 100644 --- a/src/ralph/admin/static/auto-complete-helpers.js +++ b/src/ralph/admin/static/auto-complete-helpers.js @@ -24,10 +24,6 @@ function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) { } function dismissAddRelatedObjectPopup(win, newId, newRepr) { - // newId and newRepr are expected to have previously been escaped by - // django.utils.html.escape. - newId = html_unescape(newId); - newRepr = html_unescape(newRepr); var name = windowname_to_id(win.name); var elem = document.getElementById(name); var o; diff --git a/src/ralph/admin/static/js/popup_response.js b/src/ralph/admin/static/js/popup_response.js new file mode 100644 index 0000000000..7d9e5a6546 --- /dev/null +++ b/src/ralph/admin/static/js/popup_response.js @@ -0,0 +1,17 @@ +/*global opener */ +(function() { + 'use strict'; + var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse); + switch(initData.action) { + case 'change': + opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value); + opener.updateAfterClose(window.name, initData.new_value); + break; + case 'delete': + opener.dismissDeleteRelatedObjectPopup(window, initData.value); + break; + default: + opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj); + break; + } +})(); diff --git a/src/ralph/admin/templates/admin/popup_response.html b/src/ralph/admin/templates/admin/popup_response.html index c7530f42a6..5be376aeb5 100644 --- a/src/ralph/admin/templates/admin/popup_response.html +++ b/src/ralph/admin/templates/admin/popup_response.html @@ -1,16 +1,11 @@ - +{% load i18n static %} - + {% trans 'Popup closing...' %} - From c4dff784f0cd0057e3e51d363413f7e94dd60bad Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 3 Jun 2024 12:54:34 +0200 Subject: [PATCH 41/45] Fix network terminators --- src/ralph/networks/admin.py | 6 ++++++ src/ralph/networks/fields.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ralph/networks/admin.py b/src/ralph/networks/admin.py index 5768860210..8eba137044 100644 --- a/src/ralph/networks/admin.py +++ b/src/ralph/networks/admin.py @@ -155,6 +155,12 @@ class NetworkAdmin(RalphMPTTAdmin): }) ) + def save_model(self, request, obj, form, change): + super(NetworkAdmin, self).save_model(request, obj, form, change) + terminator = form.cleaned_data['terminators'] + if terminator: + obj.terminators.set(terminator, clear=True) + def get_changelist(self, request, **kwargs): return NetworkRalphChangeList diff --git a/src/ralph/networks/fields.py b/src/ralph/networks/fields.py index 8ba7288760..2b7e084e68 100644 --- a/src/ralph/networks/fields.py +++ b/src/ralph/networks/fields.py @@ -15,7 +15,7 @@ def network_validator(value): raise ValidationError(exc.message) -class IPNetwork(Field): +class IPNetwork(CharField): """Field for network with CIDR notation.""" def __init__(self, *args, **kwargs): From d5e5cbeae12ff4a5874f77d89b96d7ca7dc27a1c Mon Sep 17 00:00:00 2001 From: Olga Matyla Date: Mon, 3 Jun 2024 14:39:20 +0200 Subject: [PATCH 42/45] Fix IPNetwork to_python --- src/ralph/networks/fields.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/ralph/networks/fields.py b/src/ralph/networks/fields.py index 2b7e084e68..94227fac20 100644 --- a/src/ralph/networks/fields.py +++ b/src/ralph/networks/fields.py @@ -1,7 +1,7 @@ import ipaddress from django.core.exceptions import ValidationError -from django.db.models.fields import CharField, Field +from django.db.models.fields import CharField MAX_NETWORK_ADDRESS_LENGTH = 44 @@ -28,20 +28,6 @@ def db_type(self, connection): max_length=MAX_NETWORK_ADDRESS_LENGTH ).db_type(connection) - def to_python(self, value): - if isinstance(value, ipaddress.IPv4Network): - return value - if value is None: - return value - try: - return ipaddress.ip_network(value) - except ValueError as exc: - raise ValidationError( - str(exc), - code='invalid', - params={'value': value}, - ) - def from_db_value(self, value, expression, connection, context): if value is None: return value From 3978c1326eecf1b624ba55716ee1f99361d43aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 2 Jul 2024 14:02:13 +0200 Subject: [PATCH 43/45] Add test for dhcp config format Remove middleware --- src/ralph/dhcp/tests/test_views.py | 23 +++++++++++ src/ralph/lib/error_handling/__init__.py | 0 src/ralph/lib/error_handling/exceptions.py | 5 --- src/ralph/lib/error_handling/middleware.py | 46 ---------------------- 4 files changed, 23 insertions(+), 51 deletions(-) delete mode 100644 src/ralph/lib/error_handling/__init__.py delete mode 100644 src/ralph/lib/error_handling/exceptions.py delete mode 100644 src/ralph/lib/error_handling/middleware.py diff --git a/src/ralph/dhcp/tests/test_views.py b/src/ralph/dhcp/tests/test_views.py index a8b329b4a7..cd1f2b3c41 100644 --- a/src/ralph/dhcp/tests/test_views.py +++ b/src/ralph/dhcp/tests/test_views.py @@ -1,3 +1,5 @@ +import re + from ddt import data, ddt, unpack from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse @@ -61,6 +63,27 @@ class DHCPEntriesViewTest(TestCase): def setUp(self): self.view = DHCPEntriesView() + def test_dhcp_entries_are_returned_in_correct_format(self): + get_user_model().objects.create_superuser( + 'test', 'test@test.test', 'test' + ) + self.client.login(username='test', password='test') + network = NetworkFactory(address='192.168.1.0/24') + IPAddressFactory(address='192.168.1.2', dhcp_expose=True) + url = '{}?env={}'.format( + reverse('dhcp_config_entries'), network.network_environment + ) + response = self.client.get(url) + lines = response.content.decode().strip().split('\n') + self.assertTrue(lines[0].startswith('# DHCP config generated by Ralph last modified at')) + self.assertTrue( + re.match( + r'^host\s\S+\s\{fixed-address\s192\.168\.1\.2;\shardware\sethernet\s\S*?;\s}$', + lines[2] + ) + ) + self.assertEqual(len(lines), 4) + def test_get_last_modified_should_return_ip_modified(self): network = NetworkFactory(address='192.168.1.0/24') ip = IPAddressFactory(address='192.168.1.2') diff --git a/src/ralph/lib/error_handling/__init__.py b/src/ralph/lib/error_handling/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/ralph/lib/error_handling/exceptions.py b/src/ralph/lib/error_handling/exceptions.py deleted file mode 100644 index 4543b346c9..0000000000 --- a/src/ralph/lib/error_handling/exceptions.py +++ /dev/null @@ -1,5 +0,0 @@ -class WrappedOperationalError(RuntimeError): - def __init__(self, query, model, error_str): - self.query = query - self.model = model - self.original_error_str = error_str diff --git a/src/ralph/lib/error_handling/middleware.py b/src/ralph/lib/error_handling/middleware.py deleted file mode 100644 index d36e51895d..0000000000 --- a/src/ralph/lib/error_handling/middleware.py +++ /dev/null @@ -1,46 +0,0 @@ -import logging -import traceback - -from django.conf import settings -from django.db import OperationalError - -from ralph.lib.error_handling.exceptions import WrappedOperationalError - - -logger = logging.getLogger(__name__) - - -class OperationalErrorHandlerMiddleware: - def process_exception(self, request, exception): - if exception: - request_id = request.META.get('HTTP_X_REQUEST_ID', '-') - if isinstance(exception, OperationalError): - logger.error("OperationalError occured. URI: %s, " - "user: %s, exception: %s, " - "django running since: %s, " - "request id: %s", - request.build_absolute_uri(), request.user, - exception, settings.START_TIMESTAMP, - request_id, - exc_info=True, stack_info=True, - extra={'request_id': request_id} - ) - raise exception - elif isinstance(exception, WrappedOperationalError): - inner_exc = exception.__context__ - logger.error("WrappedOperationalError occured. URI: %s, " - "user: %s, SQL query: %s, " - "model object: %s, original_error: %s, " - "inner exception traceback: %s, " - "django running since: %s, " - "request id: %s", - request.build_absolute_uri(), request.user, - str(exception.query), exception.model.__dict__, - exception.original_error_str, - traceback.format_tb(inner_exc.__traceback__), - settings.START_TIMESTAMP, request_id, - exc_info=True, stack_info=True, - extra={'request_id': request_id} - ) - raise inner_exc - return None From d00a1a68a5355d04f8b85d442cc0dcd77e51a649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Tue, 2 Jul 2024 14:12:27 +0200 Subject: [PATCH 44/45] remove removed middleware imports --- src/ralph/lib/polymorphic/models.py | 2 -- src/ralph/settings/base.py | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index e6c35119b1..e91ddc9b27 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -18,8 +18,6 @@ from django.contrib.contenttypes.models import ContentType from django.db import models, OperationalError -from ralph.lib.error_handling.exceptions import WrappedOperationalError - class PolymorphicQuerySet(models.QuerySet): def __init__(self, *args, **kwargs): diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 2042a44e0e..3a6f445b6f 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -122,7 +122,6 @@ def get_sentinels(sentinels_string): 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'threadlocals.middleware.ThreadLocalMiddleware', - 'ralph.lib.error_handling.middleware.OperationalErrorHandlerMiddleware', 'ralph.lib.metrics.middlewares.RequestMetricsMiddleware' ) @@ -275,11 +274,6 @@ def get_sentinels(sentinels_string): 'level': os.environ.get('LOGGING_RALPH_LEVEL', 'WARNING'), 'propagate': True, }, - 'ralph.lib.error_handling.middleware': { - 'handlers': ['file'], - 'level': os.environ.get('LOGGING_RALPH_LEVEL', 'WARNING'), - 'propagate': False, - }, 'rq.worker': { 'level': os.environ.get('LOGGING_RQ_LEVEL', 'WARNING'), 'handlers': ['file'], From 160156cb3d66cef7dbdbfcd73f5f24005f8b206c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulc?= Date: Wed, 3 Jul 2024 11:32:33 +0200 Subject: [PATCH 45/45] Remove WrappedOperationalError occurrence --- src/ralph/lib/polymorphic/models.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index e91ddc9b27..640c052de1 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -16,7 +16,7 @@ from itertools import groupby from django.contrib.contenttypes.models import ContentType -from django.db import models, OperationalError +from django.db import models class PolymorphicQuerySet(models.QuerySet): @@ -118,15 +118,8 @@ def iterator(self): # noqa *self._polymorphic_filter_args, **self._polymorphic_filter_kwargs ) - try: - for obj in model_query: - result_mapping[obj.pk].append(obj) - # NOTE(pszulc): We try to catch OperationalError that randomly - # occurs (1052, "Column 'created' in field list is ambiguous") - except OperationalError as e: - raise WrappedOperationalError( - query=model_query.query, model=self, error_str=str(e)) \ - from e + for obj in model_query: + result_mapping[obj.pk].append(obj) # yield objects in original order for pk in pks_order: # yield all objects with particular PK