From 203ee5c7c99f72bf6ac78f708d15e3423e86a550 Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Mon, 30 May 2022 12:30:01 +0200 Subject: [PATCH 1/5] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000000..c7d9fe3212 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,72 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ ng ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ ng ] + schedule: + - cron: '39 7 * * 4' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript', 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 From 073b70c16e7b8a2b85f8d68e6fc9ce3a66582faf Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Mon, 30 May 2022 12:27:47 +0200 Subject: [PATCH 2/5] started work on port to django3.2 --- README.md | 2 + requirements/base.txt | 72 +++++++++---------- src/ralph/accounts/admin.py | 2 +- src/ralph/accounts/helpers.py | 2 +- .../accounts/management/commands/ldap_sync.py | 2 +- src/ralph/accounts/models.py | 6 +- src/ralph/accounts/tests/tests.py | 2 +- src/ralph/accounts/urls.py | 10 +-- src/ralph/accounts/views.py | 2 +- src/ralph/admin/__init__.py | 10 --- src/ralph/admin/apps.py | 2 +- src/ralph/admin/autocomplete.py | 4 +- src/ralph/admin/filters.py | 4 +- src/ralph/admin/helpers.py | 2 +- src/ralph/admin/mixins.py | 4 +- src/ralph/admin/sites.py | 4 +- .../admin/templatetags/dashboard_tags.py | 5 +- src/ralph/admin/tests/test_m2m.py | 2 +- src/ralph/admin/tests/tests_autocomplete.py | 2 +- src/ralph/admin/tests/tests_functional.py | 2 +- src/ralph/admin/tests/tests_multiadd.py | 2 +- src/ralph/admin/tests/tests_views.py | 2 +- src/ralph/admin/views/multiadd.py | 2 +- src/ralph/admin/widgets.py | 8 +-- src/ralph/api/routers.py | 2 +- src/ralph/api/tests/test_rendering.py | 2 +- src/ralph/api/tests/test_routers.py | 2 +- src/ralph/api/tests/test_serializers.py | 2 +- src/ralph/assets/models/assets.py | 2 +- src/ralph/assets/models/base.py | 4 +- src/ralph/assets/tests/test_api.py | 2 +- src/ralph/assets/tests/test_subscribers.py | 2 +- src/ralph/attachments/helpers.py | 2 +- src/ralph/attachments/models.py | 10 +-- src/ralph/back_office/admin.py | 4 +- src/ralph/back_office/tests/test_api.py | 2 +- src/ralph/back_office/tests/test_models.py | 2 +- src/ralph/configuration_management/models.py | 2 +- .../tests/test_api.py | 2 +- src/ralph/configuration_management/views.py | 2 +- src/ralph/dashboards/admin.py | 2 +- src/ralph/dashboards/renderers.py | 2 +- src/ralph/dashboards/tests/test_api.py | 2 +- src/ralph/data_center/admin.py | 2 +- src/ralph/data_center/models/physical.py | 2 +- src/ralph/data_center/tests/test_api.py | 2 +- src/ralph/data_center/tests/test_forms.py | 2 +- src/ralph/data_center/tests/test_view.py | 2 +- src/ralph/data_importer/fields.py | 4 +- src/ralph/data_importer/models.py | 4 +- src/ralph/data_importer/tests/test_export.py | 2 +- .../dc_view/serializers/models_serializer.py | 2 +- .../deployment/tests/test_transitions.py | 2 +- src/ralph/deployment/utils.py | 2 +- src/ralph/dhcp/tests/test_views.py | 2 +- src/ralph/domains/models/domains.py | 2 +- src/ralph/lib/api/utils.py | 2 +- src/ralph/lib/custom_fields/models.py | 12 ++-- src/ralph/lib/custom_fields/tests/models.py | 2 +- .../lib/custom_fields/tests/test_admin.py | 2 +- src/ralph/lib/custom_fields/tests/test_api.py | 2 +- .../tests/test_custom_fields_api.py | 2 +- src/ralph/lib/hooks/main.py | 6 +- src/ralph/lib/mixins/fields.py | 9 ++- src/ralph/lib/mixins/models.py | 6 +- src/ralph/lib/permissions/__init__.py | 6 -- src/ralph/lib/permissions/api.py | 2 +- src/ralph/lib/permissions/apps.py | 5 +- src/ralph/lib/permissions/tests/test_api.py | 2 +- .../permissions/tests/test_permission_view.py | 2 +- src/ralph/lib/serializers/__init__.py | 4 +- src/ralph/lib/table/__init__.py | 2 - src/ralph/lib/table/table.py | 2 +- src/ralph/lib/template/loaders.py | 2 +- src/ralph/lib/transitions/admin.py | 6 +- src/ralph/lib/transitions/api/views.py | 2 +- src/ralph/lib/transitions/checks.py | 2 +- src/ralph/lib/transitions/models.py | 12 ++-- .../lib/transitions/tests/test_actions.py | 2 +- src/ralph/lib/transitions/tests/test_admin.py | 2 +- src/ralph/lib/transitions/views.py | 6 +- src/ralph/licences/models.py | 2 +- src/ralph/licences/tests/test_api.py | 2 +- src/ralph/licences/tests/test_functional.py | 2 +- src/ralph/licences/tests/tests_models.py | 2 +- src/ralph/networks/admin.py | 2 +- src/ralph/networks/tests/test_api.py | 2 +- src/ralph/operations/tests/test_admin.py | 2 +- src/ralph/operations/tests/test_api.py | 2 +- src/ralph/reports/tests/test_reports.py | 2 +- src/ralph/reports/views.py | 2 +- src/ralph/security/models.py | 2 +- src/ralph/security/tests/test_api.py | 2 +- src/ralph/security/views.py | 5 +- src/ralph/settings/__init__.py | 1 - src/ralph/settings/base.py | 8 +-- src/ralph/settings/local.template | 4 +- src/ralph/settings/test.py | 5 +- src/ralph/sim_cards/tests/test_admin.py | 2 +- src/ralph/ssl_certificates/tests/api.py | 2 +- src/ralph/supports/admin.py | 2 +- src/ralph/supports/tests/test_api.py | 2 +- src/ralph/supports/tests/test_autocomplete.py | 2 +- src/ralph/tests/mixins.py | 2 +- src/ralph/virtual/admin.py | 2 +- src/ralph/virtual/tests/test_api.py | 2 +- src/ralph/virtual/tests/test_cloudsync.py | 2 +- 107 files changed, 192 insertions(+), 210 deletions(-) diff --git a/README.md b/README.md index 0b30a105a0..c57f6870ad 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Ralph +This is a next gen fork of Ralph, +keeping in line with current django LTS (3.2) and recent python (3.10) Ralph is full-featured Asset Management, DCIM and CMDB system for data centers and back offices. Features: diff --git a/requirements/base.txt b/requirements/base.txt index a1a56cad95..aa6aefdb43 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,40 +1,38 @@ --r openstack.txt -r hermes.txt -Django==1.8.19 -dj.choices==0.11.0 -django-extensions==1.7.5 -django-filter==0.13.0 -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-rq==2.0 -django-sitetree==1.7.0 -django-taggit==0.17.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 -drf-nested-routers==0.11.1 +Django>=3.2.0 +dj.choices>=0.11.0 +django-extensions>=1.7.5 +django-filter>=0.13.0 +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-rq>=2.0 +django-sitetree>=1.7.0 +django-taggit>=0.17.1 +django-taggit-serializer>=0.1.5 +django-threadlocals>=0.8 +django-cryptography>=0.3 +djangorestframework>=3.2.2 +djangorestframework_xml>=1.2.0 +drf-nested-routers>=0.11.1 Markdown<3.0 # headerid extension removed in 3.0 - see #3313 for details -mysqlclient==1.3.13 -netaddr==0.7.18 -python-dateutil==2.4.2 -pytz==2015.4 -redis==3.2.1 -requests==2.20.0 -requests-oauthlib==1.3.0 -rq==1.0 +#mysqlclient>=1.3.13 # only required if using mysql, can also work with postgres or other db servers +netaddr>=0.7.18 +python-dateutil>=2.4.2 +pytz>=2015.4 +redis>=3.2.1 +requests>=2.20.0 +requests-oauthlib>=1.3.0 +rq>=1.0 six>=1.9.0 -sqlparse==0.2.3 -Unidecode==0.04.18 -tablib==0.11.5 -factory-boy==2.11.1 -Faker==0.9.0 -openpyxl==2.4.0 -typing==3.6.6 -Pillow==6.2.2 - +sqlparse>=0.2.3 +Unidecode>=0.04.18 +tablib>=0.11.5 +factory-boy>=2.11.1 +Faker>=0.9.0 +openpyxl>=2.4.0 +typing>=3.6.6 +Pillow>=6.2.2 +statsd diff --git a/src/ralph/accounts/admin.py b/src/ralph/accounts/admin.py index 00982c8875..1c68bcf469 100644 --- a/src/ralph/accounts/admin.py +++ b/src/ralph/accounts/admin.py @@ -7,7 +7,7 @@ from django.contrib.auth.admin import GroupAdmin, UserAdmin from django.contrib.auth.models import Group from django.core.exceptions import PermissionDenied -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Q from django.forms.models import model_to_dict from django.utils.functional import cached_property diff --git a/src/ralph/accounts/helpers.py b/src/ralph/accounts/helpers.py index e15ac32a14..c38cf7da12 100644 --- a/src/ralph/accounts/helpers.py +++ b/src/ralph/accounts/helpers.py @@ -2,7 +2,7 @@ from urllib.parse import urlencode from django.conf import settings -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.access_cards.models import AccessCard from ralph.admin.sites import ralph_site diff --git a/src/ralph/accounts/management/commands/ldap_sync.py b/src/ralph/accounts/management/commands/ldap_sync.py index 05e58af204..43729b2abe 100644 --- a/src/ralph/accounts/management/commands/ldap_sync.py +++ b/src/ralph/accounts/management/commands/ldap_sync.py @@ -3,12 +3,12 @@ import sys import textwrap from collections import defaultdict +from functools import lru_cache from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import Group from django.core.management.base import BaseCommand -from django.utils.lru_cache import lru_cache from ldap.controls import SimplePagedResultsControl from ralph.helpers import cache diff --git a/src/ralph/accounts/models.py b/src/ralph/accounts/models.py index 4aca57acc1..b958498397 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 @@ -50,7 +50,7 @@ def object_has_region(user): class Regionalizable(PermissionsForObjectMixin): - region = models.ForeignKey(Region, blank=False, null=False) + region = models.ForeignKey(Region, blank=False, null=False, on_delete=models.CASCADE) class Meta: abstract = True @@ -121,7 +121,7 @@ class RalphUser( blank=True, ) regions = models.ManyToManyField(Region, related_name='users', blank=True) - team = models.ForeignKey(Team, null=True, blank=True) + team = models.ForeignKey(Team, null=True, blank=True, on_delete=models.CASCADE) autocomplete_tooltip_fields = [ 'employee_id', diff --git a/src/ralph/accounts/tests/tests.py b/src/ralph/accounts/tests/tests.py index 363cbc7071..10c24440b3 100644 --- a/src/ralph/accounts/tests/tests.py +++ b/src/ralph/accounts/tests/tests.py @@ -5,7 +5,7 @@ from django.conf import settings from django.contrib.auth.hashers import check_password from django.contrib.auth.models import Permission -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from rest_framework import status diff --git a/src/ralph/accounts/urls.py b/src/ralph/accounts/urls.py index 8e48361157..6ffd40ee9b 100644 --- a/src/ralph/accounts/urls.py +++ b/src/ralph/accounts/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import url +from django.urls import re_path from django.contrib.auth.decorators import login_required from ralph.accounts.views import ( @@ -9,23 +9,23 @@ ) urlpatterns = [ - url( + re_path( r'^user_profile/?$', login_required(UserProfileView.as_view()), name='user_profile' ), - url( + re_path( r'^my_equipment/?$', login_required(CurrentUserInfoView.as_view()), name='current_user_info' ), - url( + re_path( r'^my_equipment/inventory_tag/' r'(?P[0-9]+)/(?Pyes|no)/$', login_required(InventoryTagConfirmationView.as_view()), name='inventory_tag_confirmation' ), - url( + re_path( r'^my_equipment/inventory_tag/$', login_required(InventoryTagView.as_view()), name='inventory_tag' diff --git a/src/ralph/accounts/views.py b/src/ralph/accounts/views.py index 0fe7599659..546ac57f19 100644 --- a/src/ralph/accounts/views.py +++ b/src/ralph/accounts/views.py @@ -4,7 +4,7 @@ import reversion from django.conf import settings from django.contrib import messages -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponseForbidden, HttpResponseRedirect from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/admin/__init__.py b/src/ralph/admin/__init__.py index a584458339..2949aa58e0 100644 --- a/src/ralph/admin/__init__.py +++ b/src/ralph/admin/__init__.py @@ -1,13 +1,3 @@ -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__ = [ diff --git a/src/ralph/admin/apps.py b/src/ralph/admin/apps.py index ff3cf25b7b..3da05dffa6 100644 --- a/src/ralph/admin/apps.py +++ b/src/ralph/admin/apps.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from ralph.admin.filters import register_custom_filters from ralph.apps import RalphAppConfig @@ -9,5 +8,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..869e0c0858 100644 --- a/src/ralph/admin/autocomplete.py +++ b/src/ralph/admin/autocomplete.py @@ -7,7 +7,7 @@ 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.apps import apps 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/filters.py b/src/ralph/admin/filters.py index 7e644b76b9..3a3dac1906 100644 --- a/src/ralph/admin/filters.py +++ b/src/ralph/admin/filters.py @@ -10,7 +10,7 @@ from django.contrib.admin.filters import FieldListFilter from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.utils import get_model_from_relation -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.db.models import Q from django.forms.utils import flatatt @@ -20,7 +20,6 @@ from django.utils.translation import ugettext_lazy as _ from mptt.fields import TreeForeignKey from mptt.settings import DEFAULT_LEVEL_INDICATOR -from taggit.managers import TaggableManager from ralph.admin.autocomplete import AUTOCOMPLETE_EMPTY_VALUE, get_results from ralph.admin.helpers import get_field_by_relation_path @@ -642,6 +641,7 @@ def register_custom_filters(): This function is called in AppConfig.ready() (ralph.admin.apps). """ + from taggit.managers import TaggableManager field_filter_mapper = [ (lambda f: bool(f.choices), ChoicesListFilter), (lambda f: isinstance(f, ( diff --git a/src/ralph/admin/helpers.py b/src/ralph/admin/helpers.py index 016e841b5c..fae338607c 100644 --- a/src/ralph/admin/helpers.py +++ b/src/ralph/admin/helpers.py @@ -3,7 +3,7 @@ from django.contrib.admin.utils import get_fields_from_path from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models.constants import LOOKUP_SEP from django.db.models.expressions import Func diff --git a/src/ralph/admin/mixins.py b/src/ralph/admin/mixins.py index de146bf8cc..e76c7bf968 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -7,16 +7,16 @@ from django import forms from django.conf import settings from django.contrib import admin, messages -from django.contrib.admin.templatetags.admin_static import static from django.contrib.admin.views.main import ORDER_VAR from django.contrib.auth import get_permission_codename from django.contrib.contenttypes.admin import GenericTabularInline from django.core import checks from django.core.exceptions import FieldDoesNotExist -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ +from django.templatetags.static import static from django.views.generic import TemplateView from import_export.admin import ImportExportModelAdmin from import_export.widgets import ForeignKeyWidget diff --git a/src/ralph/admin/sites.py b/src/ralph/admin/sites.py index 950edfdf20..3b5897ef02 100644 --- a/src/ralph/admin/sites.py +++ b/src/ralph/admin/sites.py @@ -2,7 +2,7 @@ from collections import defaultdict from django.conf import settings -from django.conf.urls import url +from django.conf.urls import re_path from django.contrib.admin.sites import AdminSite @@ -35,7 +35,7 @@ def get_urls(self, *args, **kwargs): ) for model, model_admin in self._registry.items(): for view in self._get_views(model_admin): - urlpatterns.insert(0, url( + urlpatterns.insert(0, re_path( view.get_url_pattern(model), view.as_view(), { diff --git a/src/ralph/admin/templatetags/dashboard_tags.py b/src/ralph/admin/templatetags/dashboard_tags.py index b5a8d5fbe2..a91247bdb6 100644 --- a/src/ralph/admin/templatetags/dashboard_tags.py +++ b/src/ralph/admin/templatetags/dashboard_tags.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -from collections import Counter, Iterable +from collections.abc import Counter, Iterable from itertools import cycle from django.apps import apps from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Count, Prefetch, Q, Sum from django.template import Library from django.utils.text import slugify @@ -243,7 +243,6 @@ def my_services(user): @register.inclusion_tag('admin/templatetags/objects_summary.html') def get_objects_summary(service_env, content_type_id, objects): - from django.core.urlresolvers import reverse content_type = ContentType.objects.get_for_id(content_type_id) opts = content_type.model_class()._meta url = reverse( diff --git a/src/ralph/admin/tests/test_m2m.py b/src/ralph/admin/tests/test_m2m.py index 45de0a4598..0b44f01ada 100644 --- a/src/ralph/admin/tests/test_m2m.py +++ b/src/ralph/admin/tests/test_m2m.py @@ -2,7 +2,7 @@ from datetime import date from decimal import Decimal -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import RequestFactory, TestCase from djmoney.money import Money from moneyed import PLN diff --git a/src/ralph/admin/tests/tests_autocomplete.py b/src/ralph/admin/tests/tests_autocomplete.py index b112bf4b38..c5755a31cc 100644 --- a/src/ralph/admin/tests/tests_autocomplete.py +++ b/src/ralph/admin/tests/tests_autocomplete.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import urllib -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from ralph.accounts.models import RalphUser, Region diff --git a/src/ralph/admin/tests/tests_functional.py b/src/ralph/admin/tests/tests_functional.py index 8dcd18e7ed..5e68ac0c9e 100644 --- a/src/ralph/admin/tests/tests_functional.py +++ b/src/ralph/admin/tests/tests_functional.py @@ -2,7 +2,7 @@ from ddt import data, ddt, unpack from django.contrib.admin.options import IS_POPUP_VAR from django.contrib.admin.views.main import SEARCH_VAR -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import RequestFactory, TestCase from django.views.generic import View diff --git a/src/ralph/admin/tests/tests_multiadd.py b/src/ralph/admin/tests/tests_multiadd.py index 2874b555dc..cd012d8656 100644 --- a/src/ralph/admin/tests/tests_multiadd.py +++ b/src/ralph/admin/tests/tests_multiadd.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.test.utils import override_settings diff --git a/src/ralph/admin/tests/tests_views.py b/src/ralph/admin/tests/tests_views.py index 643ad6d559..85895837ba 100644 --- a/src/ralph/admin/tests/tests_views.py +++ b/src/ralph/admin/tests/tests_views.py @@ -4,7 +4,7 @@ from ddt import data, ddt, unpack from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import connections from django.test import RequestFactory, TestCase from django.test.utils import CaptureQueriesContext diff --git a/src/ralph/admin/views/multiadd.py b/src/ralph/admin/views/multiadd.py index e55c8b7eda..798dc6fb80 100644 --- a/src/ralph/admin/views/multiadd.py +++ b/src/ralph/admin/views/multiadd.py @@ -2,7 +2,7 @@ from django import forms from django.conf.urls import url from django.contrib import messages -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import IntegrityError, models, transaction from django.forms import ValidationError from django.http import HttpResponseForbidden, HttpResponseRedirect diff --git a/src/ralph/admin/widgets.py b/src/ralph/admin/widgets.py index ceb554c1b9..b79c46e173 100644 --- a/src/ralph/admin/widgets.py +++ b/src/ralph/admin/widgets.py @@ -8,15 +8,15 @@ from urllib import parse from django import forms -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.urls import reverse +from django.apps import apps from django.forms.utils import flatatt from django.template import loader from django.template.context import RenderContext from django.template.defaultfilters import slugify, title +from django.templatetags.static import static from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ @@ -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/api/routers.py b/src/ralph/api/routers.py index d48df23c65..b6ff8dc45f 100644 --- a/src/ralph/api/routers.py +++ b/src/ralph/api/routers.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from collections import OrderedDict -from django.core.urlresolvers import NoReverseMatch +from django.urls import NoReverseMatch from rest_framework import routers from rest_framework.response import Response from rest_framework.reverse import reverse diff --git a/src/ralph/api/tests/test_rendering.py b/src/ralph/api/tests/test_rendering.py index 25c9811b9f..c0d4551002 100644 --- a/src/ralph/api/tests/test_rendering.py +++ b/src/ralph/api/tests/test_rendering.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from rest_framework.test import APIClient, APITestCase diff --git a/src/ralph/api/tests/test_routers.py b/src/ralph/api/tests/test_routers.py index da006554b7..8cb5b759e6 100644 --- a/src/ralph/api/tests/test_routers.py +++ b/src/ralph/api/tests/test_routers.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase diff --git a/src/ralph/api/tests/test_serializers.py b/src/ralph/api/tests/test_serializers.py index e1fe028588..d96c0cd537 100644 --- a/src/ralph/api/tests/test_serializers.py +++ b/src/ralph/api/tests/test_serializers.py @@ -3,7 +3,7 @@ import reversion from dj.choices import Choices from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework.test import APIClient, APIRequestFactory from ralph.accounts.tests.factories import RegionFactory diff --git a/src/ralph/assets/models/assets.py b/src/ralph/assets/models/assets.py index efe4c0cba6..7a3adf6874 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..5a6fe90caf 100644 --- a/src/ralph/assets/models/base.py +++ b/src/ralph/assets/models/base.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -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/tests/test_api.py b/src/ralph/assets/tests/test_api.py index cf3e5dfba2..dc298e5787 100644 --- a/src/ralph/assets/tests/test_api.py +++ b/src/ralph/assets/tests/test_api.py @@ -2,7 +2,7 @@ from urllib.parse import urlencode from ddt import data, ddt, unpack -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.accounts.tests.factories import TeamFactory diff --git a/src/ralph/assets/tests/test_subscribers.py b/src/ralph/assets/tests/test_subscribers.py index 750df35eca..7f23c6d367 100644 --- a/src/ralph/assets/tests/test_subscribers.py +++ b/src/ralph/assets/tests/test_subscribers.py @@ -3,7 +3,7 @@ from unittest.mock import patch from django.conf import settings -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from ralph.accounts.tests.factories import UserFactory diff --git a/src/ralph/attachments/helpers.py b/src/ralph/attachments/helpers.py index 8cc745ace8..08a66e7463 100644 --- a/src/ralph/attachments/helpers.py +++ b/src/ralph/attachments/helpers.py @@ -1,6 +1,6 @@ import mimetypes import os -from collections import Iterable +from collections.abc import Iterable from uuid import uuid4 diff --git a/src/ralph/attachments/models.py b/src/ralph/attachments/models.py index b5223f8a8c..f7af17fda8 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 @@ -115,7 +115,7 @@ class Attachment(TimeStampMixin, models.Model): default='application/octet-stream', ) description = models.TextField(blank=True) - uploaded_by = models.ForeignKey(settings.AUTH_USER_MODEL) + uploaded_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) objects = AttachmentManager() @@ -166,10 +166,10 @@ class AttachmentItem(models.Model): This model is bridge between attachment and content type - with this model we can add one attachment and link with many content types. """ - attachment = models.ForeignKey(Attachment, related_name='items') - content_type = models.ForeignKey(ContentType) + attachment = models.ForeignKey(Attachment, related_name='items', on_delete=models.CASCADE) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 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 560063d09e..6cfdb86026 100644 --- a/src/ralph/back_office/admin.py +++ b/src/ralph/back_office/admin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django import forms from django.conf import settings -from django.db.models.loading import get_model +from django.apps import apps from django.utils.translation import ugettext_lazy as _ from ralph.admin import RalphAdmin, RalphTabularInline, register @@ -210,7 +210,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/back_office/tests/test_api.py b/src/ralph/back_office/tests/test_api.py index 3a2870cda6..0e9f09a68d 100644 --- a/src/ralph/back_office/tests/test_api.py +++ b/src/ralph/back_office/tests/test_api.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.accounts.models import Region diff --git a/src/ralph/back_office/tests/test_models.py b/src/ralph/back_office/tests/test_models.py index fefab6dd15..30093c4208 100644 --- a/src/ralph/back_office/tests/test_models.py +++ b/src/ralph/back_office/tests/test_models.py @@ -9,7 +9,7 @@ from django.contrib.messages.storage.fallback import FallbackStorage from django.core import mail from django.core.files.uploadedfile import SimpleUploadedFile -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import override_settings, RequestFactory, SimpleTestCase from django.utils import timezone 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/configuration_management/tests/test_api.py b/src/ralph/configuration_management/tests/test_api.py index 35419caead..e3316738b1 100644 --- a/src/ralph/configuration_management/tests/test_api.py +++ b/src/ralph/configuration_management/tests/test_api.py @@ -1,7 +1,7 @@ from datetime import datetime from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.api.tests._base import RalphAPITestCase from ralph.configuration_management.models import SCMCheckResult, SCMStatusCheck diff --git a/src/ralph/configuration_management/views.py b/src/ralph/configuration_management/views.py index 449f75a771..44bbd9ba2c 100644 --- a/src/ralph/configuration_management/views.py +++ b/src/ralph/configuration_management/views.py @@ -2,7 +2,7 @@ from django.conf import settings from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import NoReverseMatch +from django.urls import NoReverseMatch from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/dashboards/admin.py b/src/ralph/dashboards/admin.py index e4e93d17ae..3ee56367a7 100644 --- a/src/ralph/dashboards/admin.py +++ b/src/ralph/dashboards/admin.py @@ -4,7 +4,7 @@ from django import forms from django.conf import settings from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.utils.translation import ugettext as _ from ralph.admin import RalphAdmin, register diff --git a/src/ralph/dashboards/renderers.py b/src/ralph/dashboards/renderers.py index 0df5af911e..94ddb7a4d9 100644 --- a/src/ralph/dashboards/renderers.py +++ b/src/ralph/dashboards/renderers.py @@ -3,7 +3,7 @@ import logging from urllib.parse import urlencode -from django.core.urlresolvers import NoReverseMatch, reverse +from django.urls import NoReverseMatch, reverse from django.template.loader import render_to_string from django.utils.safestring import mark_safe diff --git a/src/ralph/dashboards/tests/test_api.py b/src/ralph/dashboards/tests/test_api.py index 6ce1792344..6ff05ef3eb 100644 --- a/src/ralph/dashboards/tests/test_api.py +++ b/src/ralph/dashboards/tests/test_api.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.api.tests._base import RalphAPITestCase from ralph.dashboards.models import AggregateType diff --git a/src/ralph/data_center/admin.py b/src/ralph/data_center/admin.py index 604bf8da9b..9e135107e5 100644 --- a/src/ralph/data_center/admin.py +++ b/src/ralph/data_center/admin.py @@ -6,7 +6,7 @@ from django.contrib.admin import SimpleListFilter from django.contrib.admin.views.main import ChangeList, ORDER_VAR from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Prefetch, Q from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/data_center/models/physical.py b/src/ralph/data_center/models/physical.py index 283ab3cee8..09477ecde2 100644 --- a/src/ralph/data_center/models/physical.py +++ b/src/ralph/data_center/models/physical.py @@ -7,7 +7,7 @@ from django import forms from django.conf import settings from django.core.exceptions import ValidationError -from django.core.urlresolvers import reverse +from django.urls import reverse from django.core.validators import ( MaxValueValidator, MinValueValidator, diff --git a/src/ralph/data_center/tests/test_api.py b/src/ralph/data_center/tests/test_api.py index a566d51c52..11500116b8 100644 --- a/src/ralph/data_center/tests/test_api.py +++ b/src/ralph/data_center/tests/test_api.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/data_center/tests/test_forms.py b/src/ralph/data_center/tests/test_forms.py index 3f710b6388..09fdbf0931 100755 --- a/src/ralph/data_center/tests/test_forms.py +++ b/src/ralph/data_center/tests/test_forms.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse +from django.urls import reverse from django.forms import ValidationError from django.test import RequestFactory diff --git a/src/ralph/data_center/tests/test_view.py b/src/ralph/data_center/tests/test_view.py index 620824f490..4d027a02c6 100644 --- a/src/ralph/data_center/tests/test_view.py +++ b/src/ralph/data_center/tests/test_view.py @@ -2,7 +2,7 @@ from urllib.parse import urlencode from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from ralph.data_center.models import BaseObjectCluster, Cluster, DataCenterAsset diff --git a/src/ralph/data_importer/fields.py b/src/ralph/data_importer/fields.py index 138c95cb7b..5e44eab887 100644 --- a/src/ralph/data_importer/fields.py +++ b/src/ralph/data_importer/fields.py @@ -3,7 +3,7 @@ from djmoney.money import Money from import_export import fields -from ralph.settings import DEFAULT_CURRENCY_CODE +from django.conf import settings logger = logging.getLogger(__name__) @@ -92,6 +92,6 @@ class PriceField(fields.Field): def save(self, obj, data): price = Money( data['price'], - data.get('price_currency', DEFAULT_CURRENCY_CODE) + data.get('price_currency', settings.DEFAULT_CURRENCY_CODE) ) setattr(obj, 'price', price) diff --git a/src/ralph/data_importer/models.py b/src/ralph/data_importer/models.py index e4c01317d2..3d76b5be90 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 = fiels.GenericForeignKey('content_type', 'object_pk') def __str__(self): return "{} - {}".format( diff --git a/src/ralph/data_importer/tests/test_export.py b/src/ralph/data_importer/tests/test_export.py index 6eec5bef33..3868ecdcfc 100644 --- a/src/ralph/data_importer/tests/test_export.py +++ b/src/ralph/data_importer/tests/test_export.py @@ -1,7 +1,7 @@ from decimal import Decimal from ddt import data, ddt, unpack -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import connections from django.test import RequestFactory, TestCase from django.test.utils import CaptureQueriesContext diff --git a/src/ralph/dc_view/serializers/models_serializer.py b/src/ralph/dc_view/serializers/models_serializer.py index 11dde11fff..b41f4548d8 100644 --- a/src/ralph/dc_view/serializers/models_serializer.py +++ b/src/ralph/dc_view/serializers/models_serializer.py @@ -1,6 +1,6 @@ from collections import OrderedDict -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import serializers from ralph.data_center.models.choices import RackOrientation diff --git a/src/ralph/deployment/tests/test_transitions.py b/src/ralph/deployment/tests/test_transitions.py index b691abdb41..23fe5d5598 100644 --- a/src/ralph/deployment/tests/test_transitions.py +++ b/src/ralph/deployment/tests/test_transitions.py @@ -1,7 +1,7 @@ from ddt import data, ddt, unpack from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import Client from rest_framework.test import APIClient from ralph.assets.models import AssetLastHostname diff --git a/src/ralph/deployment/utils.py b/src/ralph/deployment/utils.py index dd39586dc5..df3236395d 100644 --- a/src/ralph/deployment/utils.py +++ b/src/ralph/deployment/utils.py @@ -1,7 +1,7 @@ from urllib.parse import urljoin from django.conf import settings -from django.core.urlresolvers import reverse +from django.urls import reverse from django.template import Context, Template diff --git a/src/ralph/dhcp/tests/test_views.py b/src/ralph/dhcp/tests/test_views.py index a8b329b4a7..d62e4fe4c5 100644 --- a/src/ralph/dhcp/tests/test_views.py +++ b/src/ralph/dhcp/tests/test_views.py @@ -1,6 +1,6 @@ from ddt import data, ddt, unpack from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from django.utils.http import http_date 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/api/utils.py b/src/ralph/lib/api/utils.py index 05b46a1d7b..44ca068c2d 100644 --- a/src/ralph/lib/api/utils.py +++ b/src/ralph/lib/api/utils.py @@ -1,7 +1,7 @@ import logging from collections import OrderedDict -from django.core.urlresolvers import NoReverseMatch +from django.urls import NoReverseMatch from django.utils.encoding import force_text from rest_framework.metadata import SimpleMetadata from rest_framework.relations import ManyRelatedField, RelatedField diff --git a/src/ralph/lib/custom_fields/models.py b/src/ralph/lib/custom_fields/models.py index cd5970531d..71b4233910 100644 --- a/src/ralph/lib/custom_fields/models.py +++ b/src/ralph/lib/custom_fields/models.py @@ -4,12 +4,12 @@ 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 from django.db import models -from django.db.models.fields.related import add_lazy_relation +from django.db.models.fields.related import lazy_related_operation from django.utils.text import capfirst, slugify from django.utils.translation import ugettext_lazy as _ @@ -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) @@ -196,9 +196,9 @@ def __new__(cls, name, bases, attrs): # `add_custom_field_inheritance` - it will be called lazy, only when # model will be loaded for field_path, model in new_cls.custom_fields_inheritance.items(): - add_lazy_relation( - new_cls, field_path, model, add_custom_field_inheritance - ) + def lazyfn(local, related, field): + return add_custom_field_inheritance(field_path, model, local) + lazy_related_operation(lazyfn, new_cls, model, field_path) return new_cls diff --git a/src/ralph/lib/custom_fields/tests/models.py b/src/ralph/lib/custom_fields/tests/models.py index 08c4c49424..eeed3f33f6 100644 --- a/src/ralph/lib/custom_fields/tests/models.py +++ b/src/ralph/lib/custom_fields/tests/models.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from collections import OrderedDict -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from ..models import WithCustomFieldsMixin diff --git a/src/ralph/lib/custom_fields/tests/test_admin.py b/src/ralph/lib/custom_fields/tests/test_admin.py index d93b0647a4..c3e63699e0 100644 --- a/src/ralph/lib/custom_fields/tests/test_admin.py +++ b/src/ralph/lib/custom_fields/tests/test_admin.py @@ -1,6 +1,6 @@ from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import RequestFactory, TestCase from rest_framework.status import HTTP_200_OK diff --git a/src/ralph/lib/custom_fields/tests/test_api.py b/src/ralph/lib/custom_fields/tests/test_api.py index f69385c094..f0dfd56838 100644 --- a/src/ralph/lib/custom_fields/tests/test_api.py +++ b/src/ralph/lib/custom_fields/tests/test_api.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.contrib.auth import get_user_model from django.contrib.auth.models import Group -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase diff --git a/src/ralph/lib/custom_fields/tests/test_custom_fields_api.py b/src/ralph/lib/custom_fields/tests/test_custom_fields_api.py index 9fed171781..6d4d31804f 100644 --- a/src/ralph/lib/custom_fields/tests/test_custom_fields_api.py +++ b/src/ralph/lib/custom_fields/tests/test_custom_fields_api.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/lib/hooks/main.py b/src/ralph/lib/hooks/main.py index 03cac9a87d..e76898d4e4 100644 --- a/src/ralph/lib/hooks/main.py +++ b/src/ralph/lib/hooks/main.py @@ -1,8 +1,7 @@ from typing import Any, Callable, Optional import pkg_resources -from django.conf import settings -from django.utils import lru_cache +from functools import lru_cache def hook_name_to_env_name(name, prefix='HOOKS'): @@ -15,9 +14,10 @@ def hook_name_to_env_name(name, prefix='HOOKS'): return '_'.join([prefix, name.upper().replace('.', '_')]) -@lru_cache.lru_cache(maxsize=None) +@lru_cache(maxsize=None) def get_hook(name: str, variant: Optional[str]=None) -> Callable[..., Any]: """Returns function based on configuration and entry_points.""" + from django.conf import settings loaded_func = None if variant is None: diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index 995cb30513..ad3f3e9298 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -7,9 +7,8 @@ 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.apps import apps from django.forms.utils import flatatt -from django.utils import six from django.utils.html import format_html, smart_urlquote from django.utils.translation import ugettext_lazy as _ from taggit.forms import TagField @@ -227,7 +226,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,12 +236,12 @@ 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): def render(self, name, value, attrs=None): - if value is not None and not isinstance(value, six.string_types): + if value is not None and not isinstance(value, basestring): value = ', '.join(sorted([ (t if ',' not in t else '"%s"' % t) for t in value ])) diff --git a/src/ralph/lib/mixins/models.py b/src/ralph/lib/mixins/models.py index 333e7acfdb..a17b0f2e06 100644 --- a/src/ralph/lib/mixins/models.py +++ b/src/ralph/lib/mixins/models.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from django.utils import timezone from django.utils.translation import ugettext_lazy as _ @@ -7,7 +7,7 @@ from taggit.managers import TaggableManager as TaggableManagerOriginal from ralph.lib.mixins.fields import TaggitTagField -from ralph.settings import DEFAULT_CURRENCY_CODE +from django.conf import settings class NamedMixin(models.Model): @@ -124,7 +124,7 @@ class Meta: class PriceMixin(models.Model): price = MoneyField( max_digits=15, decimal_places=2, null=True, default=0, - default_currency=DEFAULT_CURRENCY_CODE + default_currency=settings.DEFAULT_CURRENCY_CODE ) class Meta: diff --git a/src/ralph/lib/permissions/__init__.py b/src/ralph/lib/permissions/__init__.py index 501f22b4b9..137512e8e7 100644 --- a/src/ralph/lib/permissions/__init__.py +++ b/src/ralph/lib/permissions/__init__.py @@ -1,9 +1,3 @@ -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..33184d5536 100644 --- a/src/ralph/lib/permissions/apps.py +++ b/src/ralph/lib/permissions/apps.py @@ -2,8 +2,6 @@ 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): @@ -11,6 +9,9 @@ class PermissionAppConfig(AppConfig): verbose_name = 'Permissions' def ready(self): + + 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/tests/test_api.py b/src/ralph/lib/permissions/tests/test_api.py index 72d1c2d3cc..276bb9a912 100644 --- a/src/ralph/lib/permissions/tests/test_api.py +++ b/src/ralph/lib/permissions/tests/test_api.py @@ -3,7 +3,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase diff --git a/src/ralph/lib/permissions/tests/test_permission_view.py b/src/ralph/lib/permissions/tests/test_permission_view.py index 750cafc756..bcf6904d0d 100644 --- a/src/ralph/lib/permissions/tests/test_permission_view.py +++ b/src/ralph/lib/permissions/tests/test_permission_view.py @@ -1,7 +1,7 @@ from django.conf.urls import include, url from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponse from django.test import TestCase from django.views.generic import View diff --git a/src/ralph/lib/serializers/__init__.py b/src/ralph/lib/serializers/__init__.py index e6cb11b579..132dc9f50c 100644 --- a/src/ralph/lib/serializers/__init__.py +++ b/src/ralph/lib/serializers/__init__.py @@ -10,7 +10,6 @@ from djmoney.money import Money from djmoney.utils import get_currency_field_name -from ralph.settings import DEFAULT_CURRENCY_CODE Serializer = JSONSerializer @@ -31,6 +30,7 @@ def Deserializer(stream_or_string, **options): # noqa from django.core.serializers.python import \ Deserializer as PythonDeserializer, _get_model + from django.conf import settings ignore = options.pop("ignorenonexistent", False) @@ -60,7 +60,7 @@ def Deserializer(stream_or_string, **options): # noqa currency = \ obj["fields"][get_currency_field_name(field_name)] except KeyError: - currency = DEFAULT_CURRENCY_CODE + currency = settings.DEFAULT_CURRENCY_CODE money_fields[field_name] = Money(field_value, currency) else: fields[field_name] = field_value diff --git a/src/ralph/lib/table/__init__.py b/src/ralph/lib/table/__init__.py index 64ccbba1a4..77cc3ec33f 100644 --- a/src/ralph/lib/table/__init__.py +++ b/src/ralph/lib/table/__init__.py @@ -1,3 +1 @@ -from ralph.lib.table.table import Table, TableWithUrl - __all__ = ['Table', 'TableWithUrl'] diff --git a/src/ralph/lib/table/table.py b/src/ralph/lib/table/table.py index b5d74f7299..29420c7320 100644 --- a/src/ralph/lib/table/table.py +++ b/src/ralph/lib/table/table.py @@ -7,7 +7,7 @@ from django.contrib.contenttypes.models import ContentType from django.core.exceptions import FieldDoesNotExist -from django.core.urlresolvers import reverse +from django.urls import reverse from django.forms.utils import flatatt from django.template.loader import render_to_string from django.utils.html import escape diff --git a/src/ralph/lib/template/loaders.py b/src/ralph/lib/template/loaders.py index 6d0c71a502..ea9d2680cc 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.exceptions import TemplateDoesNotExist from django.template.loaders.base import Loader as BaseLoader diff --git a/src/ralph/lib/transitions/admin.py b/src/ralph/lib/transitions/admin.py index 2230cf6897..b66985d5a3 100644 --- a/src/ralph/lib/transitions/admin.py +++ b/src/ralph/lib/transitions/admin.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- from itertools import repeat +from functools import partial from django.conf.urls import url from django.contrib.admin import TabularInline from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponseRedirect -from django.utils.functional import curry from django.utils.http import urlencode from ralph.admin import RalphAdmin, register @@ -145,7 +145,7 @@ def transition_action_redirect(cls, request, queryset, transition): ) return ( - curry(transition_action_redirect, transition=transition), + partial(transition_action_redirect, transition=transition), name, '{} transition'.format(name.capitalize()), ) diff --git a/src/ralph/lib/transitions/api/views.py b/src/ralph/lib/transitions/api/views.py index c9eefb9650..1d03755c56 100644 --- a/src/ralph/lib/transitions/api/views.py +++ b/src/ralph/lib/transitions/api/views.py @@ -3,7 +3,7 @@ from django import forms from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import serializers, status from rest_framework.exceptions import ValidationError as DRFValidationError from rest_framework.exceptions import NotFound diff --git a/src/ralph/lib/transitions/checks.py b/src/ralph/lib/transitions/checks.py index e0ed14e64d..9ef68a70fb 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.exceptions import TemplateDoesNotExist from django.template.loader import get_template diff --git a/src/ralph/lib/transitions/models.py b/src/ralph/lib/transitions/models.py index 6d3874b20a..3fcf308a15 100644 --- a/src/ralph/lib/transitions/models.py +++ b/src/ralph/lib/transitions/models.py @@ -3,6 +3,7 @@ import inspect import logging from collections import defaultdict +from functools import partial import reversion from dj.choices import Choices @@ -21,7 +22,6 @@ pre_save ) from django.dispatch import receiver -from django.utils.functional import curry from django.utils.text import slugify from django.utils.translation import ugettext_lazy as _ from django_extensions.db.fields.json import JSONField @@ -485,7 +485,7 @@ def __new__(cls, name, bases, attrs): for field in fields: new_class.add_to_class( 'get_available_transitions_for_{}'.format(field), - curry(get_available_transitions_for_field, field=field) + partial(get_available_transitions_for_field, field=field) ) return new_class @@ -498,7 +498,7 @@ class TransitionWorkflowBaseWithPermissions( class TransitionModel(AdminAbsoluteUrlMixin, models.Model): - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) field_name = models.CharField(max_length=50) class Meta: @@ -518,7 +518,7 @@ def get_for_field(cls, model, field_name): class Transition(models.Model): name = models.CharField(max_length=50) - model = models.ForeignKey(TransitionModel) + model = models.ForeignKey(TransitionModel, on_delete=models.CASCADE) run_asynchronously = models.BooleanField( default=False, help_text=_( @@ -616,12 +616,12 @@ def actions_for_model(cls, model): class TransitionsHistory(TimeStampMixin): - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) transition_name = models.CharField(max_length=255) source = models.CharField(max_length=50, blank=True, null=True) target = models.CharField(max_length=50, blank=True, null=True) object_id = models.IntegerField(db_index=True) - logged_user = models.ForeignKey(settings.AUTH_USER_MODEL) + logged_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) attachments = models.ManyToManyField(Attachment) kwargs = JSONField() actions = JSONField() diff --git a/src/ralph/lib/transitions/tests/test_actions.py b/src/ralph/lib/transitions/tests/test_actions.py index d1c20f672f..56ce3faefc 100644 --- a/src/ralph/lib/transitions/tests/test_actions.py +++ b/src/ralph/lib/transitions/tests/test_actions.py @@ -2,7 +2,7 @@ from dj.choices import Country from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import Client, TransactionTestCase from rest_framework.test import APIClient diff --git a/src/ralph/lib/transitions/tests/test_admin.py b/src/ralph/lib/transitions/tests/test_admin.py index 9e2ac09b02..66c4e6e1a6 100644 --- a/src/ralph/lib/transitions/tests/test_admin.py +++ b/src/ralph/lib/transitions/tests/test_admin.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.lib.transitions.tests import TransitionTestCase from ralph.tests.mixins import ClientMixin, ReloadUrlsMixin diff --git a/src/ralph/lib/transitions/views.py b/src/ralph/lib/transitions/views.py index 84ebf3c4b9..34e2268f2e 100644 --- a/src/ralph/lib/transitions/views.py +++ b/src/ralph/lib/transitions/views.py @@ -3,8 +3,8 @@ from django import forms from django.contrib import messages -from django.core.urlresolvers import reverse -from django.db.models.loading import get_model +from django.urls import reverse +from django.apps import apps 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/models.py b/src/ralph/licences/models.py index 92f5a9ca32..fb5ef9adfc 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 diff --git a/src/ralph/licences/tests/test_api.py b/src/ralph/licences/tests/test_api.py index f69c3d9cbf..2185e7eea5 100644 --- a/src/ralph/licences/tests/test_api.py +++ b/src/ralph/licences/tests/test_api.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.accounts.tests.factories import RegionFactory diff --git a/src/ralph/licences/tests/test_functional.py b/src/ralph/licences/tests/test_functional.py index 41d1ba88c7..4c1f2d53d6 100644 --- a/src/ralph/licences/tests/test_functional.py +++ b/src/ralph/licences/tests/test_functional.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from moneyed import PLN diff --git a/src/ralph/licences/tests/tests_models.py b/src/ralph/licences/tests/tests_models.py index 27d8e93360..a5ad0306ff 100644 --- a/src/ralph/licences/tests/tests_models.py +++ b/src/ralph/licences/tests/tests_models.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.core.exceptions import ValidationError -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.accounts.tests.factories import RegionFactory, UserFactory from ralph.back_office.tests.factories import BackOfficeAssetFactory diff --git a/src/ralph/networks/admin.py b/src/ralph/networks/admin.py index 8427cb318d..1cef304477 100644 --- a/src/ralph/networks/admin.py +++ b/src/ralph/networks/admin.py @@ -1,5 +1,5 @@ from django.contrib.admin.views.main import ORDER_VAR, SEARCH_VAR -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Count, F, Prefetch from django.utils.html import escape from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/networks/tests/test_api.py b/src/ralph/networks/tests/test_api.py index fac610f8df..f9798d49f1 100644 --- a/src/ralph/networks/tests/test_api.py +++ b/src/ralph/networks/tests/test_api.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/operations/tests/test_admin.py b/src/ralph/operations/tests/test_admin.py index f260943a65..aa32676d62 100644 --- a/src/ralph/operations/tests/test_admin.py +++ b/src/ralph/operations/tests/test_admin.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from ralph.operations.models import OperationType diff --git a/src/ralph/operations/tests/test_api.py b/src/ralph/operations/tests/test_api.py index 5ecf903b8f..ca69725b29 100644 --- a/src/ralph/operations/tests/test_api.py +++ b/src/ralph/operations/tests/test_api.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.accounts.tests.factories import UserFactory diff --git a/src/ralph/reports/tests/test_reports.py b/src/ralph/reports/tests/test_reports.py index 6e0a78a58a..53f251b5fe 100644 --- a/src/ralph/reports/tests/test_reports.py +++ b/src/ralph/reports/tests/test_reports.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import factory from django.core.exceptions import ValidationError -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.admin.helpers import get_content_type_for_model from ralph.assets.models.choices import ObjectModelType diff --git a/src/ralph/reports/views.py b/src/ralph/reports/views.py index d43e88a414..37c0e2c188 100644 --- a/src/ralph/reports/views.py +++ b/src/ralph/reports/views.py @@ -4,7 +4,7 @@ import tablib from django.conf import settings from django.contrib.contenttypes.models import ContentType -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Count, Prefetch from django.http import HttpResponse from django.utils.encoding import smart_str 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/tests/test_api.py b/src/ralph/security/tests/test_api.py index 4a56f8ede8..e7fd489b8b 100644 --- a/src/ralph/security/tests/test_api.py +++ b/src/ralph/security/tests/test_api.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from datetime import datetime, timedelta -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/security/views.py b/src/ralph/security/views.py index 03d7123445..ee87d6fb98 100644 --- a/src/ralph/security/views.py +++ b/src/ralph/security/views.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- import logging +from functools import lru_cache + from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import NoReverseMatch -from django.utils.lru_cache import lru_cache +from django.urls import NoReverseMatch from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/settings/__init__.py b/src/ralph/settings/__init__.py index 4df1bf82bf..e69de29bb2 100644 --- a/src/ralph/settings/__init__.py +++ b/src/ralph/settings/__init__.py @@ -1 +0,0 @@ -from ralph.settings.base import * # noqa diff --git a/src/ralph/settings/base.py b/src/ralph/settings/base.py index 098a836e7d..c7c2555ef5 100644 --- a/src/ralph/settings/base.py +++ b/src/ralph/settings/base.py @@ -56,8 +56,10 @@ def get_sentinels(sentinels_string): # Application definition INSTALLED_APPS = ( - 'ralph.admin', + 'taggit', + 'taggit_serializer', 'django.contrib.admin', + 'ralph.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.humanize', @@ -103,8 +105,6 @@ def get_sentinels(sentinels_string): 'ralph.ssl_certificates', 'rest_framework', 'rest_framework.authtoken', - 'taggit', - 'taggit_serializer', 'djmoney', ) @@ -168,7 +168,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.sqlite3'), # 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..07581627f4 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', '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..527878d950 100644 --- a/src/ralph/settings/test.py +++ b/src/ralph/settings/test.py @@ -1,6 +1,7 @@ import sys +import os -from ralph.settings import * # noqa +from ralph.settings.base import * # for dhcp agent test sys.path.append(os.path.join(BASE_DIR, '..', '..', 'contrib', 'dhcp_agent')) @@ -10,7 +11,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', 'PORT': os.environ.get('DATABASE_PORT', 5432), 'OPTIONS': {}, }) diff --git a/src/ralph/sim_cards/tests/test_admin.py b/src/ralph/sim_cards/tests/test_admin.py index dde9ec8180..7a00b57635 100644 --- a/src/ralph/sim_cards/tests/test_admin.py +++ b/src/ralph/sim_cards/tests/test_admin.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.back_office.models import BackOfficeAssetStatus from ralph.back_office.tests.factories import WarehouseFactory diff --git a/src/ralph/ssl_certificates/tests/api.py b/src/ralph/ssl_certificates/tests/api.py index f1e960c3ae..c15cd7a72e 100644 --- a/src/ralph/ssl_certificates/tests/api.py +++ b/src/ralph/ssl_certificates/tests/api.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/supports/admin.py b/src/ralph/supports/admin.py index 9b334433fe..add94458ab 100644 --- a/src/ralph/supports/admin.py +++ b/src/ralph/supports/admin.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Count from django.http import HttpResponseRedirect from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/supports/tests/test_api.py b/src/ralph/supports/tests/test_api.py index bb6f7d1896..1fcab9c0b3 100644 --- a/src/ralph/supports/tests/test_api.py +++ b/src/ralph/supports/tests/test_api.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from datetime import date -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.accounts.models import Region diff --git a/src/ralph/supports/tests/test_autocomplete.py b/src/ralph/supports/tests/test_autocomplete.py index 34c1cd2965..ce24e4f350 100644 --- a/src/ralph/supports/tests/test_autocomplete.py +++ b/src/ralph/supports/tests/test_autocomplete.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import json -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from ralph.admin.autocomplete import QUERY_PARAM diff --git a/src/ralph/tests/mixins.py b/src/ralph/tests/mixins.py index 2b69e81ad9..b07a776127 100644 --- a/src/ralph/tests/mixins.py +++ b/src/ralph/tests/mixins.py @@ -3,7 +3,7 @@ from imp import reload from django.conf import settings -from django.core.urlresolvers import clear_url_caches +from django.urls import clear_url_caches from django.utils.importlib import import_module from ralph.tests.factories import UserFactory diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index 811d94394f..dd2f7b3888 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -2,7 +2,7 @@ from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models import Count, Prefetch from django.utils.translation import ugettext_lazy as _ diff --git a/src/ralph/virtual/tests/test_api.py b/src/ralph/virtual/tests/test_api.py index 62bf300fbe..444e44e847 100644 --- a/src/ralph/virtual/tests/test_api.py +++ b/src/ralph/virtual/tests/test_api.py @@ -1,5 +1,5 @@ from ddt import data, ddt, unpack -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from ralph.api.tests._base import RalphAPITestCase diff --git a/src/ralph/virtual/tests/test_cloudsync.py b/src/ralph/virtual/tests/test_cloudsync.py index 4bf4fd5fc8..f2058ae7ef 100644 --- a/src/ralph/virtual/tests/test_cloudsync.py +++ b/src/ralph/virtual/tests/test_cloudsync.py @@ -1,6 +1,6 @@ from unittest.mock import Mock -from django.core.urlresolvers import reverse +from django.urls import reverse from ralph.api.tests._base import RalphAPITestCase from ralph.virtual import cloudsync From bcc5b88a9fd89de96fad3c2a76b4bd07b0e254f9 Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Mon, 30 May 2022 12:38:15 +0200 Subject: [PATCH 3/5] bump dependencies with known security issues (thx to dependabot) --- requirements/dev.txt | 2 +- requirements/docs.txt | 2 +- requirements/openstack.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 5147026f8b..8415106166 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,5 +1,5 @@ -r test.txt -django-debug-toolbar==1.8 +django-debug-toolbar>=1.11.1 werkzeug==0.16.1 pudb ipython diff --git a/requirements/docs.txt b/requirements/docs.txt index 8aab9d4283..68d04dfbb7 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,4 +1,4 @@ -mkdocs==1.1 +mkdocs>=1.2.3 mkdocs-material==5.1.1 mkdocs-bootswatch==1.1 mkdocs_bootstrap==1.1 diff --git a/requirements/openstack.txt b/requirements/openstack.txt index f602f241d3..e7b377a2fb 100644 --- a/requirements/openstack.txt +++ b/requirements/openstack.txt @@ -4,7 +4,7 @@ python-keystoneclient==2.3.0 python-novaclient==3.2.0 python-ironicclient==1.7.1 -Babel==2.2.0 +Babel>=2.9.1 debtcollector==1.3.0 funcsigs==0.4 iso8601==0.1.11 From 3391f999ec6770ea311b80c061fcad7b8ecb225f Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Mon, 30 May 2022 12:49:09 +0200 Subject: [PATCH 4/5] implement missing code from ReverseGenericRelatedObjectsDescriptor --- src/ralph/lib/custom_fields/fields.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ralph/lib/custom_fields/fields.py b/src/ralph/lib/custom_fields/fields.py index 926e8b6f11..e96b6c6da8 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): + """ + ported from ReverseGenericRelatedObjectsDescriptor + """ + self.field = field + self.for_concrete_model = for_concrete_model + def __get__(self, instance, instance_type=None): """ Overwrite of ReverseGenericRelatedObjectsDescriptor's __get__ From bafaaf43b053086d0667da3e211418c0f24099f8 Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Mon, 30 May 2022 14:40:10 +0200 Subject: [PATCH 5/5] more porting to python 3.10 and django 3.2 --- src/ralph/access_cards/admin.py | 3 +- src/ralph/access_cards/models.py | 3 +- src/ralph/accessories/admin.py | 3 +- src/ralph/accessories/models.py | 8 +++-- src/ralph/accounts/admin.py | 5 +-- src/ralph/admin/mixins.py | 2 +- src/ralph/admin/tests/tests_functional.py | 2 +- src/ralph/admin/widgets.py | 4 +-- src/ralph/assets/admin.py | 5 +-- src/ralph/assets/models/assets.py | 14 ++++---- src/ralph/assets/models/components.py | 2 +- src/ralph/assets/models/configuration.py | 4 ++- src/ralph/back_office/admin.py | 2 +- src/ralph/back_office/models.py | 5 ++- src/ralph/dashboards/admin.py | 2 +- src/ralph/dashboards/models.py | 2 +- src/ralph/data_center/admin.py | 2 +- src/ralph/data_center/models/components.py | 5 +-- src/ralph/data_center/models/physical.py | 7 ++-- src/ralph/data_center/models/virtual.py | 6 ++-- src/ralph/data_importer/mixins.py | 25 ++++++++++++--- src/ralph/data_importer/models.py | 4 +-- src/ralph/deployment/admin.py | 2 +- src/ralph/dhcp/admin.py | 4 +-- src/ralph/dhcp/models.py | 9 ++++-- src/ralph/domains/admin.py | 2 +- src/ralph/domains/models/domains.py | 10 ++++-- src/ralph/lib/custom_fields/admin.py | 2 +- src/ralph/lib/custom_fields/models.py | 5 +-- src/ralph/lib/mixins/fields.py | 3 ++ src/ralph/lib/polymorphic/models.py | 2 +- src/ralph/lib/table/tests.py | 2 +- src/ralph/lib/transitions/admin.py | 3 +- src/ralph/lib/transitions/forms.py | 2 +- src/ralph/licences/admin.py | 2 +- src/ralph/licences/models.py | 10 +++--- src/ralph/networks/admin.py | 4 +-- src/ralph/networks/models/networks.py | 5 ++- src/ralph/networks/views.py | 2 +- src/ralph/operations/admin.py | 2 +- src/ralph/operations/models.py | 5 +-- src/ralph/reports/admin.py | 2 +- src/ralph/reports/models.py | 3 +- src/ralph/security/views.py | 2 +- src/ralph/sim_cards/admin.py | 2 +- src/ralph/ssl_certificates/admin.py | 2 +- src/ralph/supports/admin.py | 2 +- src/ralph/supports/models.py | 4 +-- src/ralph/tests/admin.py | 2 +- src/ralph/trade_marks/admin.py | 2 +- src/ralph/trade_marks/models.py | 37 +++++++++++++--------- src/ralph/virtual/admin.py | 2 +- src/ralph/virtual/models.py | 14 ++++---- 53 files changed, 161 insertions(+), 104 deletions(-) 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/access_cards/models.py b/src/ralph/access_cards/models.py index 7311b7bb2a..a6d1b459d6 100644 --- a/src/ralph/access_cards/models.py +++ b/src/ralph/access_cards/models.py @@ -55,7 +55,8 @@ def __str__(self): null=True, blank=True, related_name='children', - db_index=True + db_index=True, + on_delete=models.CASCADE, ) 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..6806d051b4 100644 --- a/src/ralph/accessories/models.py +++ b/src/ralph/accessories/models.py @@ -77,7 +77,8 @@ class Accessory( Manufacturer, on_delete=models.PROTECT, blank=True, null=True ) category = TreeForeignKey( - Category, null=True, related_name='+' + Category, null=True, related_name='+', + on_delete=models.CASCADE, ) accessory_name = models.CharField( max_length=255, @@ -215,10 +216,11 @@ def free(self): @reversion.register() class AccessoryUser(models.Model): - accessory = models.ForeignKey(Accessory) + accessory = models.ForeignKey(Accessory, on_delete=models.CASCADE) user = models.ForeignKey( settings.AUTH_USER_MODEL, - related_name='user' + related_name='user', + on_delete=models.CASCADE, ) quantity = models.PositiveIntegerField(default=1) diff --git a/src/ralph/accounts/admin.py b/src/ralph/accounts/admin.py index 1c68bcf469..2651fad215 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 -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/admin/mixins.py b/src/ralph/admin/mixins.py index e76c7bf968..41f7dc3684 100644 --- a/src/ralph/admin/mixins.py +++ b/src/ralph/admin/mixins.py @@ -21,7 +21,7 @@ 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 diff --git a/src/ralph/admin/tests/tests_functional.py b/src/ralph/admin/tests/tests_functional.py index 5e68ac0c9e..7d600ac0bf 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/admin/widgets.py b/src/ralph/admin/widgets.py index b79c46e173..d1cbdd58c9 100644 --- a/src/ralph/admin/widgets.py +++ b/src/ralph/admin/widgets.py @@ -146,10 +146,10 @@ class AutocompleteWidget(forms.TextInput): def __init__(self, field, admin_site, attrs=None, using=None, **kwargs): self.field = field - self.rel = self.field.rel + self.rel = field.remote_field self.multi = kwargs.get('multi', False) self.request = kwargs.get('request', None) - self.rel_to = kwargs.get('rel_to') or field.rel.to + self.rel_to = kwargs.get('rel_to') or field.remote_field.model self.admin_site = admin_site self.db = using super().__init__(attrs) 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 7a3adf6874..cb2b9de9d8 100644 --- a/src/ralph/assets/models/assets.py +++ b/src/ralph/assets/models/assets.py @@ -72,8 +72,8 @@ class Service( active = models.BooleanField(default=True) uid = NullableCharField(max_length=40, unique=True, blank=True, null=True) - profit_center = models.ForeignKey(ProfitCenter, null=True, blank=True) - business_segment = models.ForeignKey(BusinessSegment, null=True, blank=True) + profit_center = models.ForeignKey(ProfitCenter, null=True, blank=True, on_delete=models.CASCADE) + business_segment = models.ForeignKey(BusinessSegment, null=True, blank=True, on_delete=models.CASCADE) cost_center = models.CharField(max_length=100, blank=True) environments = models.ManyToManyField( 'Environment', through='ServiceEnvironment' @@ -90,6 +90,7 @@ class Service( ) support_team = models.ForeignKey( Team, null=True, blank=True, related_name='services', + on_delete=models.CASCADE, ) def __str__(self): @@ -106,8 +107,8 @@ class ServiceEnvironment( BaseObject ): _allow_in_dashboard = True - service = models.ForeignKey(Service) - environment = models.ForeignKey(Environment) + service = models.ForeignKey(Service, on_delete=models.CASCADE) + environment = models.ForeignKey(Environment, on_delete=models.CASCADE) autocomplete_tooltip_fields = [ 'service__business_owners', @@ -180,7 +181,7 @@ class AssetModel( Manufacturer, on_delete=models.PROTECT, blank=True, null=True ) category = TreeForeignKey( - 'Category', null=True, related_name='models' + 'Category', null=True, related_name='models', on_delete=models.CASCADE, ) power_consumption = models.PositiveIntegerField( verbose_name=_("Power consumption"), @@ -250,7 +251,8 @@ class Category( null=True, blank=True, related_name='children', - db_index=True + db_index=True, + on_delete=models.CASCADE, ) imei_required = models.BooleanField(default=False) allow_deployment = models.BooleanField(default=False) diff --git a/src/ralph/assets/models/components.py b/src/ralph/assets/models/components.py index 69aa597d33..eea742797b 100644 --- a/src/ralph/assets/models/components.py +++ b/src/ralph/assets/models/components.py @@ -75,7 +75,7 @@ def __str__(self): class Component(AdminAbsoluteUrlMixin, TimeStampMixin, models.Model): - base_object = models.ForeignKey(BaseObject, related_name='%(class)s_set') + base_object = models.ForeignKey(BaseObject, related_name='%(class)s_set', on_delete=models.CASCADE) # TODO(xor-xor): This field should be removed along with ComponentModel # class. model = models.ForeignKey( diff --git a/src/ralph/assets/models/configuration.py b/src/ralph/assets/models/configuration.py index 85b44ec263..cbe2f64a48 100644 --- a/src/ralph/assets/models/configuration.py +++ b/src/ralph/assets/models/configuration.py @@ -40,6 +40,7 @@ class ConfigurationModule( blank=True, default=None, related_name='children_modules', + on_delete=models.CASCADE, ) # TODO: is this necessary? support_team = models.ForeignKey( @@ -86,7 +87,8 @@ class ConfigurationClass(AdminAbsoluteUrlMixin, BaseObject): ) module = models.ForeignKey( ConfigurationModule, - related_name='configuration_classes' + related_name='configuration_classes', + on_delete=models.CASCADE, ) autocomplete_words_split = True diff --git a/src/ralph/back_office/admin.py b/src/ralph/back_office/admin.py index 6cfdb86026..5c09a0f5ca 100644 --- a/src/ralph/back_office/admin.py +++ b/src/ralph/back_office/admin.py @@ -4,7 +4,7 @@ from django.apps import apps from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline, register from ralph.admin.filters import LiquidatedStatusFilter, TagsListFilter from ralph.admin.mixins import BulkEditChangeListMixin from ralph.admin.sites import ralph_site diff --git a/src/ralph/back_office/models.py b/src/ralph/back_office/models.py index 30fbfe33e6..7bcc78be81 100644 --- a/src/ralph/back_office/models.py +++ b/src/ralph/back_office/models.py @@ -174,10 +174,12 @@ class BackOfficeAsset(Regionalizable, Asset): owner = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, related_name='assets_as_owner', + on_delete=models.CASCADE, ) user = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, related_name='assets_as_user', + on_delete=models.CASCADE, ) location = models.CharField(max_length=128, null=True, blank=True) purchase_order = models.CharField(max_length=50, null=True, blank=True) @@ -197,7 +199,8 @@ class BackOfficeAsset(Regionalizable, Asset): verbose_name=_('IMEI 2') ) office_infrastructure = models.ForeignKey( - OfficeInfrastructure, null=True, blank=True + OfficeInfrastructure, null=True, blank=True, + on_delete=models.CASCADE, ) class Meta: diff --git a/src/ralph/dashboards/admin.py b/src/ralph/dashboards/admin.py index 3ee56367a7..0cb2f61a01 100644 --- a/src/ralph/dashboards/admin.py +++ b/src/ralph/dashboards/admin.py @@ -7,7 +7,7 @@ from django.urls import reverse from django.utils.translation import ugettext as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, register from ralph.admin.mixins import RalphAdminForm from ralph.dashboards.models import Dashboard, Graph diff --git a/src/ralph/dashboards/models.py b/src/ralph/dashboards/models.py index 8be067c4cf..07f664d7c0 100644 --- a/src/ralph/dashboards/models.py +++ b/src/ralph/dashboards/models.py @@ -186,7 +186,7 @@ def format_label(self, value): class Graph(AdminAbsoluteUrlMixin, NamedMixin, TimeStampMixin, models.Model): description = models.CharField('description', max_length=250, blank=True) - model = models.ForeignKey(ContentType) + model = models.ForeignKey(ContentType, on_delete=models.CASCADE) aggregate_type = models.PositiveIntegerField(choices=AggregateType()) chart_type = models.PositiveIntegerField(choices=ChartType()) params = JSONField(blank=True) diff --git a/src/ralph/data_center/admin.py b/src/ralph/data_center/admin.py index 9e135107e5..4cf810a561 100644 --- a/src/ralph/data_center/admin.py +++ b/src/ralph/data_center/admin.py @@ -60,7 +60,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/models/components.py b/src/ralph/data_center/models/components.py index fecc686451..5180881207 100644 --- a/src/ralph/data_center/models/components.py +++ b/src/ralph/data_center/models/components.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- from django.db import models -from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from ralph.assets.models.assets import Asset @@ -9,7 +8,6 @@ from ralph.lib.mixins.models import AdminAbsoluteUrlMixin -@python_2_unicode_compatible class DiskShare(Component): share_id = models.PositiveIntegerField( verbose_name=_('share identifier'), null=True, blank=True, @@ -40,9 +38,8 @@ def __str__(self): return '%s (%s)' % (self.label, self.wwn) -@python_2_unicode_compatible class DiskShareMount(AdminAbsoluteUrlMixin, models.Model): - share = models.ForeignKey(DiskShare, verbose_name=_("share")) + share = models.ForeignKey(DiskShare, verbose_name=_("share"), on_delete=models.CASCADE) asset = models.ForeignKey( Asset, verbose_name=_('asset'), null=True, blank=True, default=None, on_delete=models.SET_NULL diff --git a/src/ralph/data_center/models/physical.py b/src/ralph/data_center/models/physical.py index 09477ecde2..c6f78bf679 100644 --- a/src/ralph/data_center/models/physical.py +++ b/src/ralph/data_center/models/physical.py @@ -152,7 +152,7 @@ def get_queryset(self): class ServerRoom(AdminAbsoluteUrlMixin, NamedMixin.NonUnique, models.Model): _allow_in_dashboard = True - data_center = models.ForeignKey(DataCenter, verbose_name=_("data center")) + data_center = models.ForeignKey(DataCenter, verbose_name=_("data center"), on_delete=models.CASCADE) data_center._autocomplete = False data_center._filter_title = _('data center') visualization_cols_num = models.PositiveIntegerField( @@ -185,8 +185,8 @@ class Meta: class RackAccessory(AdminAbsoluteUrlMixin, models.Model): - accessory = models.ForeignKey(Accessory) - rack = models.ForeignKey('Rack') + accessory = models.ForeignKey(Accessory, on_delete=models.CASCADE) + rack = models.ForeignKey('Rack', on_delete=models.CASCADE) orientation = models.PositiveIntegerField( choices=Orientation(), default=Orientation.front.id, @@ -219,6 +219,7 @@ class Rack(AdminAbsoluteUrlMixin, NamedMixin.NonUnique, models.Model): ServerRoom, verbose_name=_('server room'), null=True, blank=False, + on_delete=models.CASCADE, ) server_room._autocomplete = False server_room._filter_title = _('server room') diff --git a/src/ralph/data_center/models/virtual.py b/src/ralph/data_center/models/virtual.py index bed3b509a7..5e9d436424 100644 --- a/src/ralph/data_center/models/virtual.py +++ b/src/ralph/data_center/models/virtual.py @@ -40,7 +40,7 @@ class VIPProtocol(Choices): class VIP(AdminAbsoluteUrlMixin, BaseObject): name = models.CharField(_('name'), max_length=255) - ip = models.ForeignKey(IPAddress) + ip = models.ForeignKey(IPAddress, on_delete=models.CASCADE) port = models.PositiveIntegerField(verbose_name=_('port'), default=0) protocol = models.PositiveIntegerField( verbose_name=_('protocol'), @@ -95,7 +95,7 @@ class Cluster( max_length=255, verbose_name=_('hostname') ) - type = models.ForeignKey(ClusterType) + type = models.ForeignKey(ClusterType, on_delete=models.CASCADE) base_objects = models.ManyToManyField( BaseObject, verbose_name=_('Assigned base objects'), @@ -173,7 +173,7 @@ def clean(self): class BaseObjectCluster(models.Model): - cluster = models.ForeignKey(Cluster) + cluster = models.ForeignKey(Cluster, on_delete=models.CASCADE) base_object = BaseObjectForeignKey( BaseObject, related_name='clusters', diff --git a/src/ralph/data_importer/mixins.py b/src/ralph/data_importer/mixins.py index 44cf42dea4..ff6414c4a6 100644 --- a/src/ralph/data_importer/mixins.py +++ b/src/ralph/data_importer/mixins.py @@ -21,12 +21,24 @@ def __new__(cls, name, bases, attrs): for display ForeignKey fields. """ # https://bugs.python.org/issue29270 - attrs.pop('__classcell__', None) - new_class = super().__new__(cls, name, bases, attrs) + # https://bugs.python.org/issue41629 + # https://stackoverflow.com/questions/41343263/provide-classcell-example-for-python-3-6-metaclass + # https://github.com/django/django/pull/7653/files + #attrs.pop('__classcell__', None) + super_new = super(ImportForeignKeyMeta, cls).__new__ + classcell = attrs.pop('__classcell__', None) + module = attrs.pop('__module__') + new_attrs = {'__module__': module} + + if classcell is not None: + new_attrs['__classcell__'] = classcell + + print('cls, name, bases, attrs', cls, name, bases, new_attrs) + new_class = super_new(cls, name, bases, new_attrs) # Generate second class only for export which has added # additional *_str fields - export_class = super().__new__( - cls, '{}Exporter'.format(name), bases, attrs + export_class = super_new( + cls, '{}Exporter'.format(name), bases, new_attrs ) update_fields = [] for name, field in new_class.fields.items(): @@ -75,6 +87,11 @@ def __new__(cls, name, bases, attrs): return new_class + #def __repr__(self): + # return str(self.__class__) + + + class ImportForeignKeyMixin(object): """ImportForeignKeyMixin class for django import-export resources.""" diff --git a/src/ralph/data_importer/models.py b/src/ralph/data_importer/models.py index 3d76b5be90..da41dd37b0 100644 --- a/src/ralph/data_importer/models.py +++ b/src/ralph/data_importer/models.py @@ -14,13 +14,13 @@ class ImportedObjects(TimeStampMixin, models.Model): """Django models for imported objects.""" - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_pk = models.IntegerField(db_index=True) old_object_pk = models.CharField(max_length=255, db_index=True) old_ci_uid = models.CharField( max_length=255, db_index=True, null=True, blank=True ) - object = fiels.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..5813f3d10f 100644 --- a/src/ralph/deployment/admin.py +++ b/src/ralph/deployment/admin.py @@ -1,6 +1,6 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, 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..447ca3e6ef 100644 --- a/src/ralph/dhcp/admin.py +++ b/src/ralph/dhcp/admin.py @@ -2,14 +2,14 @@ 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, 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/dhcp/models.py b/src/ralph/dhcp/models.py index 1bb3e5da4c..9d2a88ddd4 100644 --- a/src/ralph/dhcp/models.py +++ b/src/ralph/dhcp/models.py @@ -35,7 +35,8 @@ class DHCPServer(AdminAbsoluteUrlMixin, models.Model): verbose_name=_('IP address'), unique=True ) network_environment = models.ForeignKey( - NetworkEnvironment, null=True, blank=True + NetworkEnvironment, null=True, blank=True, + on_delete=models.CASCADE, ) last_synchronized = models.DateTimeField(null=True, blank=True) @@ -73,10 +74,12 @@ def __str__(self): class DNSServerGroupOrder(models.Model): dns_server_group = models.ForeignKey( - 'DNSServerGroup', related_name='server_group_order' + 'DNSServerGroup', related_name='server_group_order', + on_delete=models.CASCADE, ) dns_server = models.ForeignKey( - 'DNSServer', related_name='server_group_order' + 'DNSServer', related_name='server_group_order', + on_delete=models.CASCADE, ) order = models.PositiveIntegerField(editable=True, db_index=True) diff --git a/src/ralph/domains/admin.py b/src/ralph/domains/admin.py index 7b41d73a8a..0496f6d289 100644 --- a/src/ralph/domains/admin.py +++ b/src/ralph/domains/admin.py @@ -2,7 +2,7 @@ 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, 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 5e490a936d..5438ef22db 100644 --- a/src/ralph/domains/models/domains.py +++ b/src/ralph/domains/models/domains.py @@ -95,6 +95,7 @@ class Domain(AdminAbsoluteUrlMixin, BaseObject, models.Model): ) business_segment = models.ForeignKey( BusinessSegment, blank=True, null=True, + on_delete=models.CASCADE, help_text=_("Business segment for a domain") ) business_owner = models.ForeignKey( @@ -102,6 +103,7 @@ class Domain(AdminAbsoluteUrlMixin, BaseObject, models.Model): related_name='domaincontract_business_owner', blank=True, null=True, + on_delete=models.CASCADE, help_text=_("Business contact person for a domain") ) technical_owner = models.ForeignKey( @@ -109,12 +111,14 @@ class Domain(AdminAbsoluteUrlMixin, BaseObject, models.Model): related_name='domaincontract_technical_owner', blank=True, null=True, + on_delete=models.CASCADE, help_text=_("Technical contact person for a domain") ) domain_holder = models.ForeignKey( AssetHolder, blank=True, null=True, + on_delete=models.CASCADE, help_text=_("Company which receives invoice for the domain") ) domain_type = models.PositiveIntegerField( @@ -132,9 +136,11 @@ class Domain(AdminAbsoluteUrlMixin, BaseObject, models.Model): ) domain_category = models.ForeignKey( DomainCategory, blank=True, null=True, + on_delete=models.CASCADE, ) dns_provider = models.ForeignKey( DNSProvider, blank=True, null=True, + on_delete=models.CASCADE, help_text=_("Provider which keeps domain's DNS") ) additional_services = models.ManyToManyField( @@ -174,9 +180,9 @@ class DomainContract( PriceMixin, models.Model, ): - domain = models.ForeignKey(Domain) + domain = models.ForeignKey(Domain, on_delete=models.CASCADE) expiration_date = models.DateField(null=True, blank=True) - registrant = models.ForeignKey('DomainRegistrant', null=True, blank=True) + registrant = models.ForeignKey('DomainRegistrant', null=True, blank=True, on_delete=models.CASCADE ) def __str__(self): return "{domain_name} - {expiration_date}".format( diff --git a/src/ralph/lib/custom_fields/admin.py b/src/ralph/lib/custom_fields/admin.py index 1320b75aec..60e372f039 100644 --- a/src/ralph/lib/custom_fields/admin.py +++ b/src/ralph/lib/custom_fields/admin.py @@ -3,7 +3,7 @@ from django.contrib.admin.utils import unquote from django.contrib.contenttypes.models import ContentType -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, register from ralph.admin.mixins import RalphGenericTabularInline from ralph.lib.custom_fields.forms import ( CustomFieldValueForm, diff --git a/src/ralph/lib/custom_fields/models.py b/src/ralph/lib/custom_fields/models.py index 71b4233910..5cb38ba856 100644 --- a/src/ralph/lib/custom_fields/models.py +++ b/src/ralph/lib/custom_fields/models.py @@ -79,7 +79,8 @@ class CustomField(AdminAbsoluteUrlMixin, TimeStampMixin, models.Model): "When set, only members of the specified group will be " "allowed to set, change or unset values of this custom field " "for objects." - ) + ), + on_delete=models.CASCADE, ) use_as_configuration_variable = models.BooleanField( default=False, @@ -130,7 +131,7 @@ class CustomFieldValue(TimeStampMixin, models.Model): # is by-design simple, so it, for example, doesn't allow to filter by range # of integers or other Django filters like gte, lte. value = models.CharField(max_length=CUSTOM_FIELD_VALUE_MAX_LENGTH) - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField(db_index=True) object = fields.GenericForeignKey('content_type', 'object_id') diff --git a/src/ralph/lib/mixins/fields.py b/src/ralph/lib/mixins/fields.py index ad3f3e9298..3a0a473df8 100644 --- a/src/ralph/lib/mixins/fields.py +++ b/src/ralph/lib/mixins/fields.py @@ -217,6 +217,9 @@ class BaseObjectLicence(models.Model): def __init__(self, *args, **kwargs): kwargs['limit_choices_to'] = self.limit_choices self.limit_models = kwargs.pop('limit_models', []) + if 'on_delete' not in kwargs: + # default for on_delete in older django + kwargs['on_delete'] = models.CASCADE super().__init__(*args, **kwargs) def limit_choices(self): diff --git a/src/ralph/lib/polymorphic/models.py b/src/ralph/lib/polymorphic/models.py index 5a6aca2f2e..95c75ae455 100644 --- a/src/ralph/lib/polymorphic/models.py +++ b/src/ralph/lib/polymorphic/models.py @@ -253,7 +253,7 @@ class Polymorphic(models.Model): pass """ - content_type = models.ForeignKey(ContentType, blank=True, null=True) + content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.CASCADE) polymorphic_objects = PolymorphicQuerySet.as_manager() objects = models.Manager() 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/admin.py b/src/ralph/lib/transitions/admin.py index b66985d5a3..a9af7f3017 100644 --- a/src/ralph/lib/transitions/admin.py +++ b/src/ralph/lib/transitions/admin.py @@ -9,7 +9,8 @@ from django.http import HttpResponseRedirect 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/forms.py b/src/ralph/lib/transitions/forms.py index 3ec911b05a..403badbd14 100644 --- a/src/ralph/lib/transitions/forms.py +++ b/src/ralph/lib/transitions/forms.py @@ -2,7 +2,7 @@ from django import forms from django.conf import settings from django.utils.html import strip_tags -from django.utils.text import mark_safe +from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ from ralph.lib.transitions.models import ( diff --git a/src/ralph/licences/admin.py b/src/ralph/licences/admin.py index 70013ae94d..e7f67a68fa 100644 --- a/src/ralph/licences/admin.py +++ b/src/ralph/licences/admin.py @@ -1,7 +1,7 @@ # -*- 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, 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 fb5ef9adfc..555ca6157e 100644 --- a/src/ralph/licences/models.py +++ b/src/ralph/licences/models.py @@ -239,7 +239,8 @@ class Licence(Regionalizable, AdminAbsoluteUrlMixin, PriceMixin, BaseObject): default='', ) office_infrastructure = models.ForeignKey( - 'back_office.OfficeInfrastructure', null=True, blank=True + 'back_office.OfficeInfrastructure', null=True, blank=True, + on_delete=models.CASCADE, ) budget_info = models.ForeignKey( BudgetInfo, @@ -315,7 +316,7 @@ def get_autocomplete_queryset(cls): @reversion.register() class BaseObjectLicence(models.Model): - licence = models.ForeignKey(Licence) + licence = models.ForeignKey(Licence, on_delete=models.CASCADE) base_object = BaseObjectForeignKey( BaseObject, related_name='licences', @@ -351,10 +352,11 @@ def clean(self): class LicenceUser(models.Model): - licence = models.ForeignKey(Licence) + licence = models.ForeignKey(Licence, on_delete=models.CASCADE) user = models.ForeignKey( settings.AUTH_USER_MODEL, - related_name='licences' + related_name='licences', + on_delete=models.CASCADE, ) quantity = models.PositiveIntegerField(default=1) diff --git a/src/ralph/networks/admin.py b/src/ralph/networks/admin.py index 1cef304477..8775bac8e9 100644 --- a/src/ralph/networks/admin.py +++ b/src/ralph/networks/admin.py @@ -4,7 +4,7 @@ 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, register from ralph.admin.filters import RelatedAutocompleteFieldListFilter from ralph.admin.helpers import CastToInteger from ralph.admin.mixins import RalphMPTTAdmin @@ -12,7 +12,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/models/networks.py b/src/ralph/networks/models/networks.py index b02ff60476..029aac5f21 100644 --- a/src/ralph/networks/models/networks.py +++ b/src/ralph/networks/models/networks.py @@ -58,7 +58,8 @@ class NetworkEnvironment( ): data_center = models.ForeignKey( 'data_center.DataCenter', - verbose_name=_('data center') + verbose_name=_('data center'), + on_delete=models.CASCADE, ) queue = models.ForeignKey( 'DiscoveryQueue', @@ -250,6 +251,7 @@ class Network( related_name='children', db_index=True, editable=False, + on_delete=models.CASCADE, ) address = IPNetwork( verbose_name=_('network address'), @@ -319,6 +321,7 @@ class Network( service_env = models.ForeignKey( 'assets.ServiceEnvironment', related_name='networks', null=True, default=None, blank=True, + on_delete=models.CASCADE, ) dns_servers_group = models.ForeignKey( 'dhcp.DNSServerGroup', diff --git a/src/ralph/networks/views.py b/src/ralph/networks/views.py index a1ad126206..147af8f5c5 100644 --- a/src/ralph/networks/views.py +++ b/src/ralph/networks/views.py @@ -4,7 +4,7 @@ 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..6b2e9888ac 100644 --- a/src/ralph/operations/admin.py +++ b/src/ralph/operations/admin.py @@ -5,7 +5,7 @@ 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, 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/operations/models.py b/src/ralph/operations/models.py index 78302ae53a..3d2e8f57c2 100644 --- a/src/ralph/operations/models.py +++ b/src/ralph/operations/models.py @@ -34,7 +34,8 @@ class OperationType( null=True, blank=True, related_name='children', - db_index=True + db_index=True, + on_delete=models.CASCADE, ) class choices(Choices): @@ -55,7 +56,7 @@ class choices(Choices): class Operation(AdminAbsoluteUrlMixin, TaggableMixin, models.Model): - type = TreeForeignKey(OperationType, verbose_name=_('type')) + type = TreeForeignKey(OperationType, verbose_name=_('type'), on_delete=models.CASCADE) _allow_in_dashboard = True title = models.CharField( max_length=350, null=False, blank=False, verbose_name=_('title'), diff --git a/src/ralph/reports/admin.py b/src/ralph/reports/admin.py index c63af43a9d..712b03acd8 100644 --- a/src/ralph/reports/admin.py +++ b/src/ralph/reports/admin.py @@ -1,4 +1,4 @@ -from ralph.admin import RalphAdmin, RalphTabularInline, register +from ralph.admin.mixins import RalphAdmin, RalphTabularInline, register from ralph.reports.forms import ReportTemplateFormset from ralph.reports.models import Report, ReportLanguage, ReportTemplate diff --git a/src/ralph/reports/models.py b/src/ralph/reports/models.py index 192599d03a..26bc13faec 100644 --- a/src/ralph/reports/models.py +++ b/src/ralph/reports/models.py @@ -41,11 +41,12 @@ class ReportTemplate(TimeStampMixin, models.Model): upload_to=get_report_file_path, blank=False, ) - language = models.ForeignKey(ReportLanguage) + language = models.ForeignKey(ReportLanguage, on_delete=models.CASCADE) default = models.BooleanField() report = models.ForeignKey( Report, related_name='templates', + on_delete=models.CASCADE, ) class Meta: diff --git a/src/ralph/security/views.py b/src/ralph/security/views.py index ee87d6fb98..e55ef0cd72 100644 --- a/src/ralph/security/views.py +++ b/src/ralph/security/views.py @@ -8,7 +8,7 @@ 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, 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/sim_cards/admin.py b/src/ralph/sim_cards/admin.py index 075811e05b..752aa58ad3 100644 --- a/src/ralph/sim_cards/admin.py +++ b/src/ralph/sim_cards/admin.py @@ -1,6 +1,6 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, register 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 50bc814ae9..b56c26e217 100644 --- a/src/ralph/ssl_certificates/admin.py +++ b/src/ralph/ssl_certificates/admin.py @@ -1,6 +1,6 @@ from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, 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 add94458ab..111d074d1d 100644 --- a/src/ralph/supports/admin.py +++ b/src/ralph/supports/admin.py @@ -4,7 +4,7 @@ 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, 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/supports/models.py b/src/ralph/supports/models.py index 6298df9a5d..7a5009bd49 100644 --- a/src/ralph/supports/models.py +++ b/src/ralph/supports/models.py @@ -172,7 +172,7 @@ class BaseObjectsSupport( AdminAbsoluteUrlMixin, models.Model ): - support = models.ForeignKey(Support) + support = models.ForeignKey(Support, on_delete=models.CASCADE) baseobject = BaseObjectForeignKey( BaseObject, verbose_name=_('Asset'), @@ -180,7 +180,7 @@ class BaseObjectsSupport( limit_models=[ 'back_office.BackOfficeAsset', 'data_center.DataCenterAsset' - ] + ], ) class Meta: diff --git a/src/ralph/tests/admin.py b/src/ralph/tests/admin.py index bcb229fc10..4218003c78 100644 --- a/src/ralph/tests/admin.py +++ b/src/ralph/tests/admin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ -from ralph.admin import RalphAdmin, register +from ralph.admin.mixins import RalphAdmin, 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/trade_marks/admin.py b/src/ralph/trade_marks/admin.py index 8d16ec120a..21f86c3475 100644 --- a/src/ralph/trade_marks/admin.py +++ b/src/ralph/trade_marks/admin.py @@ -3,7 +3,7 @@ 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, register from ralph.admin.filters import ( ChoicesListFilter, custom_title_filter, diff --git a/src/ralph/trade_marks/models.py b/src/ralph/trade_marks/models.py index 20cb043422..d8c8ccfa0d 100644 --- a/src/ralph/trade_marks/models.py +++ b/src/ralph/trade_marks/models.py @@ -108,13 +108,15 @@ class IntellectualPropertyBase(models.Model): settings.AUTH_USER_MODEL, related_name='%(class)s_business_owner', blank=False, - null=False + null=False, + on_delete=models.CASCADE, ) technical_owner = models.ForeignKey( settings.AUTH_USER_MODEL, related_name='%(class)s_technical_owner', blank=False, - null=False + null=False, + on_delete=models.CASCADE, ) order_number_url = models.URLField( max_length=255, blank=True, null=True, @@ -126,7 +128,8 @@ class IntellectualPropertyBase(models.Model): holder = models.ForeignKey( AssetHolder, blank=True, - null=True + null=True, + on_delete=models.CASCADE, ) status = models.PositiveIntegerField( choices=TradeMarkStatus(), @@ -135,6 +138,7 @@ class IntellectualPropertyBase(models.Model): registrar_institution = models.ForeignKey( TradeMarkRegistrarInstitution, null=True, + on_delete=models.CASCADE, ) database_link = models.URLField( max_length=255, blank=True, null=True, @@ -179,10 +183,11 @@ class TradeMark(IntellectualPropertyBase, AdminAbsoluteUrlMixin, BaseObject): class TradeMarksLinkedDomains(models.Model): - trade_mark = models.ForeignKey(TradeMark) + trade_mark = models.ForeignKey(TradeMark, on_delete=models.CASCADE) domain = models.ForeignKey( Domain, - related_name='trade_mark' + related_name='trade_mark', + on_delete=models.CASCADE, ) class Meta: @@ -197,8 +202,8 @@ def __str__(self): class TradeMarkAdditionalCountry(models.Model): - trade_mark = models.ForeignKey(TradeMark) - country = models.ForeignKey(TradeMarkCountry) + trade_mark = models.ForeignKey(TradeMark, on_delete=models.CASCADE) + country = models.ForeignKey(TradeMarkCountry, on_delete=models.CASCADE) class Meta: verbose_name = _('Trade Mark Additional Country') @@ -219,10 +224,11 @@ class Patent(IntellectualPropertyBase, AdminAbsoluteUrlMixin, BaseObject): class PatentsLinkedDomains(models.Model): - patent = models.ForeignKey(Patent) + patent = models.ForeignKey(Patent, on_delete=models.CASCADE) domain = models.ForeignKey( Domain, - related_name='patent' + related_name='patent', + on_delete=models.CASCADE, ) class Meta: @@ -237,8 +243,8 @@ def __str__(self): class PatentAdditionalCountry(models.Model): - patent = models.ForeignKey(Patent) - country = models.ForeignKey(TradeMarkCountry) + patent = models.ForeignKey(Patent, on_delete=models.CASCADE) + country = models.ForeignKey(TradeMarkCountry, on_delete=models.CASCADE) class Meta: verbose_name = _('Patent Additional Country') @@ -259,10 +265,11 @@ class Design(IntellectualPropertyBase, AdminAbsoluteUrlMixin, BaseObject): class DesignsLinkedDomains(models.Model): - design = models.ForeignKey(Design) + design = models.ForeignKey(Design, on_delete=models.CASCADE) domain = models.ForeignKey( Domain, - related_name='design' + related_name='design', + on_delete=models.CASCADE, ) class Meta: @@ -277,8 +284,8 @@ def __str__(self): class DesignAdditionalCountry(models.Model): - design = models.ForeignKey(Design) - country = models.ForeignKey(TradeMarkCountry) + design = models.ForeignKey(Design, on_delete=models.CASCADE) + country = models.ForeignKey(TradeMarkCountry, on_delete=models.CASCADE) class Meta: verbose_name = _('Design Additional Country') diff --git a/src/ralph/virtual/admin.py b/src/ralph/virtual/admin.py index dd2f7b3888..34e8824c36 100644 --- a/src/ralph/virtual/admin.py +++ b/src/ralph/virtual/admin.py @@ -6,7 +6,7 @@ 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, register from ralph.admin.filters import BaseObjectHostnameFilter, TagsListFilter from ralph.assets.models import BaseObject from ralph.assets.models.components import Ethernet diff --git a/src/ralph/virtual/models.py b/src/ralph/virtual/models.py index bde08a2e70..54e8e4361d 100644 --- a/src/ralph/virtual/models.py +++ b/src/ralph/virtual/models.py @@ -57,7 +57,7 @@ class Meta: class CloudFlavor(AdminAbsoluteUrlMixin, BaseObject): name = models.CharField(_('name'), max_length=255) - cloudprovider = models.ForeignKey(CloudProvider) + cloudprovider = models.ForeignKey(CloudProvider, on_delete=models.CASCADE) cloudprovider._autocomplete = False flavor_id = models.CharField(unique=True, max_length=100) @@ -147,7 +147,7 @@ def disk(self, new_disk): class CloudProject(PreviousStateMixin, AdminAbsoluteUrlMixin, BaseObject): - cloudprovider = models.ForeignKey(CloudProvider) + cloudprovider = models.ForeignKey(CloudProvider, on_delete=models.CASCADE) cloudprovider._autocomplete = False custom_fields_inheritance = OrderedDict([ ('service_env', 'assets.ServiceEnvironment'), @@ -203,8 +203,8 @@ def save(self, *args, **kwargs): pass super(CloudHost, self).save(*args, **kwargs) - cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type') - cloudprovider = models.ForeignKey(CloudProvider) + cloudflavor = models.ForeignKey(CloudFlavor, verbose_name='Instance Type', on_delete=models.CASCADE) + cloudprovider = models.ForeignKey(CloudProvider, on_delete=models.CASCADE) cloudprovider._autocomplete = False host_id = models.CharField( @@ -216,7 +216,7 @@ def save(self, *args, **kwargs): verbose_name=_('hostname'), max_length=255 ) - hypervisor = models.ForeignKey(DataCenterAsset, blank=True, null=True) + hypervisor = models.ForeignKey(DataCenterAsset, blank=True, null=True, on_delete=models.CASCADE) image_name = models.CharField(max_length=255, null=True, blank=True) class Meta: @@ -346,7 +346,7 @@ class VirtualServer( default=VirtualServerStatus.new.id, choices=VirtualServerStatus(), ) - type = models.ForeignKey(VirtualServerType, related_name='virtual_servers') + type = models.ForeignKey(VirtualServerType, related_name='virtual_servers', on_delete=models.CASCADE) hostname = NullableCharField( blank=True, default=None, @@ -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, on_delete=models.CASCADE) previous_dc_host_update_fields = ['hostname'] _allow_in_dashboard = True