Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion component_catalog/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2184,7 +2184,7 @@ def test_subcomponent_admin_changelist_available_actions(self):
url = reverse("admin:component_catalog_subcomponent_changelist")
response = self.client.get(url)
expected = [
("", "---------"),
("", "- Select an option -"),
("set_policy", "Set usage policy from components"),
("mass_update", "Mass update"),
]
Expand Down
2 changes: 1 addition & 1 deletion dje/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def history_view(self, request, object_id, extra_context=None):
object_id=unquote(object_id),
content_type=ContentType.objects.get_for_model(self.model),
)
.select_related()
.select_related("user")
.order_by("-action_time")
)

Expand Down
4 changes: 0 additions & 4 deletions dje/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ def ready(self):

action_end.connect(successful_mass_update)

from rest_framework.renderers import DocumentationRenderer

DocumentationRenderer.languages = []

# Ensure that mappings are always dumped in the items order when using `yaml.safe_dump`.
def ordered_dumper(dumper, data):
return dumper.represent_mapping("tag:yaml.org,2002:map", data.items())
Expand Down
17 changes: 9 additions & 8 deletions dje/management/commands/dumpdataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.core.serializers.json import Serializer
from django.db.models import FETCH_PEERS

from component_catalog.models import AcceptableLinkage
from component_catalog.models import Component
Expand Down Expand Up @@ -216,32 +217,32 @@ def handle(self, *args, **options):
# The handle_assigned_licenses() method is not called so we need to dump
# ComponentAssignedLicense and SubcomponentAssignedLicense models data
data += list(
ComponentAssignedLicense.objects.filter(
component__id__in=component_ids
).select_related()
ComponentAssignedLicense.objects.filter(component__id__in=component_ids).fetch_mode(
FETCH_PEERS
)
)
data += list(
SubcomponentAssignedLicense.objects.filter(
subcomponent__in=subcomponents
).select_related()
).fetch_mode(FETCH_PEERS)
)

data += list(ComponentKeyword.objects.scope(dataspace))

packages = (
Package.objects.filter(componentassignedpackage__component__id__in=component_ids)
.select_related()
.fetch_mode(FETCH_PEERS)
.distinct()
)
data += list(packages)
data += list(
ComponentAssignedPackage.objects.filter(component__id__in=component_ids)
.select_related()
.fetch_mode(FETCH_PEERS)
.distinct()
)
data += list(
PackageAssignedLicense.objects.filter(package__in=packages)
.select_related()
.fetch_mode(FETCH_PEERS)
.distinct()
)

Expand All @@ -252,7 +253,7 @@ def handle(self, *args, **options):
models = REPORTING_MODELS[:]

for model_class in models:
qs = get_unsecured_manager(model_class).scope(dataspace).select_related()
qs = get_unsecured_manager(model_class).scope(dataspace).fetch_mode(FETCH_PEERS)
data += list(qs)

return ExcludeFieldsSerializer().serialize(
Expand Down
3 changes: 2 additions & 1 deletion dje/management/commands/dumpinitdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.contrib.auth.models import Group
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.db.models import FETCH_PEERS

from component_catalog.models import ComponentKeyword
from component_catalog.models import ComponentStatus
Expand Down Expand Up @@ -61,7 +62,7 @@ def handle(self, *args, **options):
models.extend(POLICY_MODELS)

for model_class in models:
qs = model_class.objects.scope(dataspace).select_related()
qs = model_class.objects.scope(dataspace).fetch_mode(FETCH_PEERS)
data += list(qs)

return ExcludeFieldsSerializer().serialize(
Expand Down
4 changes: 2 additions & 2 deletions dje/tests/test_two_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ def test_two_factor_authentication_disable_2fa(self):
response = self.client.post(self.tfa_disable_url, data=data)
self.assertContains(response, "Please enter your OTP token.")

data = {"otp_token": "123456"}
device_form_value = OTPTokenForm.device_choices(self.user)[0][0]
data = {"otp_token": "123456", "otp_device": device_form_value}
response = self.client.post(self.tfa_disable_url, data=data)
form_error = "Invalid token. Please make sure you have entered it correctly."
self.assertContains(response, form_error)
Expand All @@ -146,7 +147,6 @@ def test_two_factor_authentication_disable_2fa(self):
device.save()

valid_token = self._get_valid_token(device.bin_key)
device_form_value = OTPTokenForm.device_choices(self.user)[0][0]
data = {
"otp_token": valid_token,
"otp_device": device_form_value,
Expand Down
4 changes: 2 additions & 2 deletions dje/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
#

from django.contrib.admin.widgets import AdminTextInputWidget
from django.db.models.fields import BLANK_CHOICE_DASH
from django.forms import widgets
from django.forms.utils import flatatt
from django.utils.html import format_html
from django.utils.html import mark_safe
from django.utils.http import urlencode
from django.utils.translation import gettext as _

from django_filters.conf import settings as django_filters_settings
from django_filters.widgets import LinkWidget


Expand Down Expand Up @@ -67,7 +67,7 @@ def render(self, name, value, attrs=None, renderer=None, choices=()):

def render_option(self, name, selected_choices, option_value, option_label):
option_value = str(option_value)
if option_label == BLANK_CHOICE_DASH[0][1]:
if option_label == django_filters_settings.EMPTY_CHOICE_LABEL:
option_label = _("All")

data = self.data.copy()
Expand Down
12 changes: 11 additions & 1 deletion license_library/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,17 @@ def get_spdx_link(self, obj):
"get_dataspace",
)
list_display_links = ("key",)
list_select_related = True
# Explicit fields since `AsLink("owner")` and `get_dataspace` are not
# plain field names Django can auto-detect from `list_display`.
list_select_related = (
"owner",
"category",
"license_style",
"license_profile",
"license_status",
"usage_policy",
"dataspace",
)
search_fields = ("key", "name", "short_name", "keywords", "owner__name")
ordering = ("-last_modified_date",)
# Custom list as we don't want to inherit HistoryCreatedActionTimeListFilter
Expand Down
2 changes: 1 addition & 1 deletion license_library/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ def test_api_license_endpoint_assigned_tags(self):
self.license_list_url, data=json.dumps(data), content_type="application/json"
)
self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
expected = {"tags": [{"label": ["Object with label=Non existing does not exist."]}]}
expected = {"tags": {0: {"label": ["Object with label=Non existing does not exist."]}}}
self.assertEqual(expected, response.data)

data["tags"][0]["label"] = self.license_tag1.label
Expand Down
2 changes: 1 addition & 1 deletion product_portfolio/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ def helper(self):
def save(self, product):
from product_portfolio.importers import ImportFromScan

sid = transaction.savepoint()
sid = transaction.savepoint_create()
importer = ImportFromScan(
product,
self.user,
Expand Down
4 changes: 2 additions & 2 deletions product_portfolio/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ class FieldChangesMixin:
"""

@classmethod
def from_db(cls, db, field_names, values):
def from_db(cls, db, field_names, values, *, fetch_mode=None):
"""Store the original field values as loaded from the db on the instance."""
new = super().from_db(db, field_names, values)
new = super().from_db(db, field_names, values, fetch_mode=fetch_mode)
new._loaded_values = dict(zip(field_names, values))
return new

Expand Down
2 changes: 1 addition & 1 deletion product_portfolio/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_product_security_admin_changelist_available_actions(self):
self.client.login(username=self.user.username, password="secret")
response = self.client.get(self.product_changelist_url)
expected = [
("", "---------"),
("", "- Select an option -"),
("evaluate_policy_rules", "Evaluate policy rules"),
("mass_update", "Mass update"),
]
Expand Down
4 changes: 2 additions & 2 deletions product_portfolio/tests/test_admin_guardian.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def test_product_guardian_admin_security_attributes(self):
# actions = []
# actions_to_remove = ['copy_to', 'compare_with', 'delete_selected']
expected = [
("", "---------"),
("", "- Select an option -"),
("evaluate_policy_rules", "Evaluate policy rules"),
("mass_update", "Mass update"),
]
Expand Down Expand Up @@ -455,7 +455,7 @@ def test_productcomponent_admin_security_attributes(self):
# actions = []
# actions_to_remove = ['copy_to', 'compare_with']
expected = [
("", "---------"),
("", "- Select an option -"),
("delete_selected", "Delete selected product component relationships"),
("mass_update", "Mass update"),
]
Expand Down
2 changes: 1 addition & 1 deletion product_portfolio/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2754,7 +2754,7 @@ def test_product_portfolio_product_manage_packages_grid_fields_permissions(self)
expected = (
'<select name="form-0-review_status" class="select form-select" disabled'
' aria-describedby="id_form-0-review_status_helptext" id="id_form-0-review_status">'
' <option value="" selected>---------</option>'
' <option value="" selected>- Select an option -</option>'
"</select>"
)
self.assertContains(response, expected, html=True)
Expand Down
16 changes: 8 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ dependencies = [
"packaging==26.2",
"pip==26.2.1",
# Django
"django==6.0.8",
"django==6.1.1",
"asgiref==3.12.1",
"typing_extensions==4.15.0",
"sqlparse==0.6.0",
# Django apps
"django-crispy-forms==2.6",
"crispy_bootstrap5==2026.3",
"django-crispy-forms==2.7",
"crispy-bootstrap5==2026.9",
"django-grappelli==5.0.0",
"django-filter==25.2",
"django-filter==26.1",
"django-registration==5.2.1",
"confusable_homoglyphs==3.3.1",
"django-guardian==3.3.2",
"django-guardian==3.5.0",
"django-environ==0.14.0",
"django-debug-toolbar==7.1.1",
"django-debug-toolbar==8.0.0",
# Parallel testing
"tblib==3.2.2",
# CAPTCHA
"altcha==1.0.0",
"django-altcha==1.0.0",
# REST API
"djangorestframework==3.16.1",
"djangorestframework==3.18.1",
# API documentation
"drf-yasg==1.21.15",
"uritemplate==4.2.0",
Expand All @@ -65,7 +65,7 @@ dependencies = [
# Track failed login attempts
"django-axes==8.3.1",
# Multi-factor authentication
"django-otp==1.7.0",
"django-otp==1.7.3",
"qrcode==8.2",
"pypng==0.20220715.0",
# Database
Expand Down
Binary file not shown.
Binary file added thirdparty/dist/django-6.1.1-py3-none-any.whl
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading