Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TP2000-1193 Upgrade to Django 4.2 #1163

Merged
merged 42 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
2c6cc6d
Fix invalid sequence deprecation warning
dalecannon Feb 16, 2024
5c65144
Fix logger.warn() deprecation warning
dalecannon Feb 16, 2024
dccc743
Bump django-staff-sso-client to 4.2.1
dalecannon Feb 16, 2024
7efe2b6
Bump django to 4.0.10
dalecannon Feb 16, 2024
a5ab5ee
Remove FormMixin now that DeleteView uses it
dalecannon Feb 16, 2024
5436cb9
Remove SECURE_BROWSER_XSS_FILTER deprecated setting
dalecannon Feb 16, 2024
1dc4672
Replace deprecated pytz module
dalecannon Feb 16, 2024
c887709
Bump django-crispy-forms to 1.14.0
dalecannon Feb 16, 2024
ee15216
Bump crispy-forms-gds
dalecannon Feb 16, 2024
02ebb5b
Bump django-cte to 1.3.1
dalecannon Feb 16, 2024
7ce72ea
Bump django-extensions to 3.2.3
dalecannon Feb 16, 2024
75306df
Bump django-filter to 23.5
dalecannon Feb 16, 2024
02549f1
Bump django-fsm to 2.8.1
dalecannon Feb 16, 2024
681377c
Bump django-health-check to 3.18.1
dalecannon Feb 16, 2024
68e07c3
Bump django-polymorphic to 3.1.0
dalecannon Feb 16, 2024
134c4ac
Bump django-redis to 5.4.0
dalecannon Feb 16, 2024
b21dadb
Bump django-storages to 1.13.2
dalecannon Feb 16, 2024
fc113a3
Bump django-test-migrations to 1.3.0
dalecannon Feb 16, 2024
3c2ab51
Bump django-webpack-loader to 3.0.1
dalecannon Feb 16, 2024
56fc3a4
Bump djangorestframework to 3.14.0
dalecannon Feb 16, 2024
38f86aa
Bump drf-extra-fields to 3.7.0
dalecannon Feb 16, 2024
39e13aa
Bump drf-flex-fields to 1.0.2
dalecannon Feb 16, 2024
6f551b9
Bump django-sequences to 3.0
dalecannon Feb 16, 2024
b78f2dd
Bump factory-boy to 3.3.0
dalecannon Feb 16, 2024
e8fade4
Bump django to 4.1.13
dalecannon Feb 16, 2024
ac81c43
Replace deprecated logout GET request with POST request
dalecannon Feb 18, 2024
682c37c
Bump django to 4.2.10
dalecannon Feb 18, 2024
71e77a6
Fix field error in workbasket changes view unit test
dalecannon Feb 18, 2024
7577ad2
Amend loading report unit tests
dalecannon Feb 18, 2024
3a82bb6
Use new STORAGES setting in favour of deprecated STATICFILES_STORAGE …
dalecannon Feb 18, 2024
4fa8f35
Bump django-storages to 1.14.2
dalecannon Feb 19, 2024
092f261
Bump pytest-django to 4.8.0
dalecannon Feb 19, 2024
7938c80
Add no-op migrations triggered by Django 4.0 changes to the migration…
dalecannon Feb 23, 2024
83dba31
Merge branch 'master' into TP2000-1193--upgrade-to-django-4-2
dalecannon Feb 23, 2024
7336cf2
Prevent reverse lookup on unsaved origin instance
dalecannon Feb 26, 2024
4730851
Give unsaved instances in importer tests a pk value to make them seri…
dalecannon Feb 26, 2024
8b5c733
Catch exception when calling related manager for unsaved instances wh…
dalecannon Feb 27, 2024
d879395
Merge branch 'master' into TP2000-1193--upgrade-to-django-4-2
dalecannon Feb 27, 2024
cee4cca
Nest sign out button styling
dalecannon Feb 27, 2024
60bd395
Remove redundant post() override in WorkBasketDelete view
dalecannon Feb 27, 2024
c722cf8
Add comment to ValueError exception
dalecannon Feb 28, 2024
226cfa1
Make renderer a class-wide attribute for FormSet
dalecannon Feb 28, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.10 on 2024-02-23 11:51

from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
dependencies = [
("commodities", "0012_TOPS_745_description_date_fix"),
]

operations = [
migrations.AlterField(
model_name="goodsnomenclature",
name="origins",
field=models.ManyToManyField(
through="commodities.GoodsNomenclatureOrigin",
to="commodities.goodsnomenclature",
),
),
migrations.AlterField(
model_name="goodsnomenclature",
name="successors",
field=models.ManyToManyField(
through="commodities.GoodsNomenclatureSuccessor",
to="commodities.goodsnomenclature",
),
),
]
5 changes: 3 additions & 2 deletions common/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ def get_bound_form(self, form_class, *args, **kwargs):
return bound_form

def bind_nested_forms(self, *args, **kwargs):
if kwargs.get("instance"):
kwargs.pop("instance") # this mixin does not support ModelForm as subforms
# this mixin does not support ModelForm as subforms
kwargs.pop("instance", None)

for name, field in self.fields.items():
if isinstance(field, RadioNested):
Expand Down Expand Up @@ -550,6 +550,7 @@ class FormSet(forms.BaseFormSet):
validate_min = False
validate_max = False
prefix = None
renderer = get_default_renderer()

def __init__(
self,
Expand Down
8 changes: 4 additions & 4 deletions common/jinja2.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.timezone import template_localtime
from govuk_frontend_jinja.templates import Environment
from govuk_frontend_jinja.templates import NunjucksExtension
from jinja2.utils import markupsafe
from webpack_loader.templatetags.webpack_loader import render_bundle
from webpack_loader.contrib.jinja2ext import _render_bundle
from webpack_loader.templatetags.webpack_loader import webpack_static

from govuk_frontend_jinja.templates import Environment
from govuk_frontend_jinja.templates import NunjucksExtension
from workbaskets.models import WorkBasket


Expand Down Expand Up @@ -140,7 +140,7 @@ def environment(**kwargs):
"get_current_workbasket": WorkBasket.current,
"localtime": template_localtime,
"pluralize": pluralize,
"render_bundle": render_bundle,
"render_bundle": _render_bundle,
"settings": settings,
"static": static,
"format_date_string": format_date_string,
Expand Down
6 changes: 3 additions & 3 deletions common/jinja2/layouts/_generic.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
{% endif %}

<!--[if !IE 8]><!-->
{{ render_bundle("main", "css") }}
{{ render_bundle(bundle_name="main", extension="css") }}
<!--<![endif]-->
<!--[if IE 8]>
{# render_bundle("ie8", "css") #}
{# render_bundle(bundle_name="ie8", extension="css") #}
<![endif]-->
{% block styles %}{% endblock %}
{% endblock %}
Expand All @@ -55,5 +55,5 @@

{% block bodyEnd %}
{% set csp_nonce -%}nonce="{{ cspNonce }}"{% endset %}
{{ render_bundle("main", "js", attrs=csp_nonce) }}
{{ render_bundle(bundle_name="main", extension="js", attrs=csp_nonce) }}
{% endblock %}
25 changes: 23 additions & 2 deletions common/jinja2/layouts/layout.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,41 @@
{% endif %}
{% endset %}

{% set logout_login_link %}
{% if request.user.is_authenticated %}
<form action="{{ url('logout') }}" method="post">
{{ csrf_input }}
<button
class="fake-link govuk-header__link"
id="sign-out"
name="submit"
value="logout"
>
Sign out
</button>
</form>
{% else %}
<a
class="govuk-header__link"
href="{{ settings.LOGIN_URL }}"
>Sign in</a>
{% endif %}
{% endset %}

{{ govukHeader({
"homepageUrl": "https://gov.uk/",
"serviceName": service_name,
"serviceUrl": "/",
"navigation": [
{ "html": workbasket_html } if workbasket_html else "",
{
"href": url("logout") if request.user.is_authenticated else settings.LOGIN_URL,
"text": "Sign out" if request.user.is_authenticated else "Sign In"
"html": logout_login_link,
} if not settings.SSO_ENABLED else "",
],
"useTudorCrown": true,
}) }}
{% endblock %}

{% block beforeContent %}
{{ govukPhaseBanner({
"tag": {
Expand Down
26 changes: 26 additions & 0 deletions common/migrations/0011_alter_trackedmodel_polymorphic_ctype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 4.2.10 on 2024-02-23 11:51

import django.db.models.deletion
from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
dependencies = [
("contenttypes", "0002_remove_content_type_name"),
("common", "0010_set_tracked_model_datetime"),
]

operations = [
migrations.AlterField(
model_name="trackedmodel",
name="polymorphic_ctype",
field=models.ForeignKey(
editable=False,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="polymorphic_%(app_label)s.%(class)s_set+",
to="contenttypes.contenttype",
),
),
]
10 changes: 7 additions & 3 deletions common/models/trackedmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,12 @@ def copy(
kwargs.update(nested_fields)

if not ignore:
for model in queryset.approved_up_to_transaction(transaction):
model.copy(transaction, **kwargs)
try:
for model in queryset.approved_up_to_transaction(transaction):
model.copy(transaction, **kwargs)
except ValueError:
# Calling a related manager for an unsaved instance would nevertheless result in an empty queryset
pass
dalecannon marked this conversation as resolved.
Show resolved Hide resolved

return new_object

Expand All @@ -528,7 +532,7 @@ def in_use_by(self, via_relation: str, transaction=None) -> QuerySet[TrackedMode
remote_field_name = get_accessor(relation.remote_field)

return remote_model.objects.filter(
**{f"{remote_field_name}__version_group": self.version_group}
**{f"{remote_field_name}__version_group": self.version_group},
).approved_up_to_transaction(transaction)

def in_use(self, transaction=None, *relations: str) -> bool:
Expand Down
13 changes: 13 additions & 0 deletions common/static/common/scss/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@
margin-bottom: -4px;
}
}

button#sign-out {
color: govuk-colour("white");
font-weight: bold;
text-decoration: none;

&:hover {
text-decoration: underline;
text-decoration-thickness: 3px;
text-underline-offset: 0.1em;
}
}

}

.workbasket-navigation {
Expand Down
4 changes: 2 additions & 2 deletions common/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_index_displays_logout_buttons_correctly_SSO_off_logged_in(valid_user_cl
assert response.status_code == 200

page = BeautifulSoup(str(response.content), "html.parser")
assert page.find_all("a", {"href": "/logout"})
assert page.find("form", {"action": reverse("logout")})


def test_index_redirects_to_login_page_logged_out_SSO_off(client):
Expand All @@ -69,7 +69,7 @@ def test_index_displays_login_buttons_correctly_SSO_on(valid_user_client):
assert response.status_code == 200

page = BeautifulSoup(str(response.content), "html.parser")
assert not page.find_all("a", {"href": "/logout"})
assert not page.find("form", {"action": reverse("logout")})
assert not page.find_all("a", {"href": "/login"})


Expand Down
15 changes: 9 additions & 6 deletions common/tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from unittest.mock import patch

import pytest
from backports.zoneinfo import ZoneInfo
from dateutil.parser import parse as parse_date
from dateutil.relativedelta import relativedelta
from django import forms
Expand All @@ -29,7 +30,6 @@
from django_filters.views import FilterView
from freezegun import freeze_time
from lxml import etree
from pytz import timezone

from commodities.models.orm import GoodsNomenclature
from common.business_rules import BusinessRule
Expand Down Expand Up @@ -98,7 +98,9 @@ def raises_if(exception, expected):

@contextlib.contextmanager
def add_business_rules(
model: Type[TrackedModel], *rules: Type[BusinessRule], indirect=False
model: Type[TrackedModel],
*rules: Type[BusinessRule],
indirect=False,
):
"""Attach BusinessRules to a TrackedModel."""
target = f"{'indirect_' if indirect else ''}business_rules"
Expand Down Expand Up @@ -135,7 +137,7 @@ def make_duplicate_record(factory, identifying_fields=None):
identifying_fields = list(factory._meta.model.identifying_fields)

return factory.create(
**dict(get_field_tuple(existing, field) for field in identifying_fields)
**dict(get_field_tuple(existing, field) for field in identifying_fields),
)


Expand Down Expand Up @@ -627,7 +629,8 @@ def wraps(
)

current_instance = instance or factory.create(
transaction=approved_transaction, **factory_kwargs or {}
transaction=approved_transaction,
**factory_kwargs or {},
)

xml = export_workbasket(
Expand Down Expand Up @@ -731,7 +734,7 @@ def now(self):

@property
def datetime_now(self):
return datetime.now(timezone(settings.TIME_ZONE)).replace(
return datetime.now(ZoneInfo(settings.TIME_ZONE)).replace(
hour=0,
minute=0,
second=0,
Expand Down Expand Up @@ -895,7 +898,7 @@ def get_form_data(form: forms.ModelForm) -> Dict[str, Any]:
del data[field]
value = form.fields[field].widget.decompress(value)
data.update(
**{f"{field}_{i}": v for i, v in enumerate(value) if v is not None}
**{f"{field}_{i}": v for i, v in enumerate(value) if v is not None},
)
elif value is not None:
data.setdefault(field, value)
Expand Down
2 changes: 2 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,9 @@ def check(
kwargs.update(previous_version.get_identifying_fields())

updated_model = run_xml_import(
# Give the unsaved instance a placeholder pk value to make it serializable
lambda: factory.build(
pk=1234,
update_type=update_type,
**kwargs,
),
Expand Down
21 changes: 21 additions & 0 deletions geo_areas/migrations/0006_alter_geographicalarea_memberships.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 4.2.10 on 2024-02-23 11:51

from django.db import migrations
from django.db import models


class Migration(migrations.Migration):
dependencies = [
("geo_areas", "0005_rename_described_area"),
]

operations = [
migrations.AlterField(
model_name="geographicalarea",
name="memberships",
field=models.ManyToManyField(
through="geo_areas.GeographicalMembership",
to="geo_areas.geographicalarea",
),
),
]
Loading
Loading