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

Upgrade to Django 4.2 #25

Merged
merged 5 commits into from
Mar 1, 2024
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
8 changes: 2 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python: ['3.7', '3.8', '3.9', '3.10']
django: ['3.2', '4.1']
exclude:
- python: '3.7'
django: '4.1'

python: ['3.8', '3.9', '3.10', '3.11']
django: ['3.2', '4.2']
services:
postgres:
image: postgres:12
Expand Down
25 changes: 11 additions & 14 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ classifiers =
Development Status :: 5 - Production/Stable
Framework :: Django
Framework :: Django :: 3.2
Framework :: Django :: 4.1
Framework :: Django :: 4.2
Intended Audience :: Developers
Operating System :: Unix
Operating System :: MacOS
Operating System :: Microsoft :: Windows
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Topic :: Software Development :: Libraries :: Python Modules

[options]
Expand All @@ -36,10 +36,10 @@ scripts =
bin/patch_content_types
bin/use_external_components
install_requires =
django>=3.2.0,<4.2
django>=3.2.0
django-filter>=2.0
django-solo
djangorestframework~=3.12.0
djangorestframework>=3.11.0
djangorestframework_camel_case>=1.2.0
django-rest-framework-condition
drf-yasg>=1.20.0
Expand All @@ -50,7 +50,6 @@ install_requires =
notifications-api-common>=0.2.2
oyaml
PyJWT>=2.0.0
pyyaml
requests
coreapi
tests_require =
Expand Down Expand Up @@ -96,15 +95,13 @@ release =
test=pytest

[isort]
profile = black
combine_as_imports = true
default_section = THIRDPARTY
include_trailing_comma = true
line_length = 88
multi_line_output = 3
force_grid_wrap = 0
use_parentheses = True
ensure_newline_before_comments = True
skip = env,.tox,.history,.eggs
skip =
env
node_modules
.tox
skip_glob = **/migrations/**
known_django=django
known_first_party=vng_api_common
sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
Expand All @@ -113,7 +110,7 @@ sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
testpaths = tests
DJANGO_SETTINGS_MODULE=testapp.settings

[pep8]
[pycodestyle]
max-line-length=88
exclude=env,.tox,doc

Expand Down
3 changes: 3 additions & 0 deletions testapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

SITE_ID = 1


DEBUG = os.getenv("DEBUG", "no").lower() in ["yes", "true", "1"]

BASE_DIR = os.path.abspath(os.path.dirname(__file__))
Expand All @@ -12,6 +13,8 @@

ALLOWED_HOSTS = ["*"]

USE_TZ = True

DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
Expand Down
13 changes: 6 additions & 7 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
[tox]
envlist =
py37-django32
py{38,39,310}-django{32,41}
py{38,39,310,311}-django{32,42}
isort
docs
black
skip_missing_interpreters = true

[gh-actions]
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311

[gh-actions:env]
DJANGO =
3.2: django32
4.1: django41
4.2: django42

[testenv]
extras =
tests
coverage
deps =
django32: Django~=3.2.0
django41: Django~=4.1.0
django42: Django~=4.2.0
passenv =
PGUSER
PGPORT
PGPASSWORD
commands =
py.test tests \
pytest tests \
--cov --cov-report xml \
{posargs}

Expand All @@ -54,6 +53,6 @@ extras =
tests
docs
commands=
py.test check_sphinx.py -v \
pytest check_sphinx.py -v \
--tb=auto \
{posargs}
16 changes: 5 additions & 11 deletions vng_api_common/authorizations/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,14 @@ class UniqueClientIDValidator:
message = _(
"The clientID(s) {client_id} are already used in application(s) {app_id}"
)
requires_context = True

def set_context(self, serializer_field):
"""
This hook is called by the serializer instance,
prior to the validation call being made.
"""
# Determine the existing instance, if this is an update operation.
self.instance = getattr(serializer_field.parent, "instance", None)

def __call__(self, value: List[str]):
def __call__(self, value: List[str], serializer_field):
instance = getattr(serializer_field.parent, "instance", None)
qs = Applicatie.objects.all()

if self.instance:
qs = qs.exclude(id=self.instance.id)
if instance:
qs = qs.exclude(id=instance.id)

existing = qs.filter(client_ids__overlap=value).values_list(
"uuid", "client_ids"
Expand Down
3 changes: 2 additions & 1 deletion vng_api_common/caching/etags.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ def mark_affected(cls, obj: models.Model, using=None) -> None:
connection = transaction.get_connection(using)

func = MethodCallback(etag_update.calculate_new_value)
for _, _func in connection.run_on_commit:
for run_on_commit in connection.run_on_commit:
_func = run_on_commit[1]
annashamray marked this conversation as resolved.
Show resolved Hide resolved
if func == _func:
logger.debug(
"Update for model instance %r with pk %s was already scheduled",
Expand Down
7 changes: 1 addition & 6 deletions vng_api_common/inspectors/query.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
from django.db import models

try:
from django.utils.encoding import force_str
except ImportError: # Django < 4.0
from django.utils.encoding import force_text as force_str

from django.utils.encoding import force_str
from django.utils.translation import gettext as _

from django_filters.filters import BaseCSVFilter, ChoiceFilter
Expand Down
69 changes: 24 additions & 45 deletions vng_api_common/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,18 @@ def __call__(self, url: str):


class InformatieObjectUniqueValidator(validators.UniqueTogetherValidator):
requires_context = True

def __init__(self, parent_field, field: str):
self.parent_field = parent_field
self.field = field
super().__init__(None, (parent_field, field))

def set_context(self, serializer_field):
serializer = serializer_field.parent
super().set_context(serializer)

self.queryset = serializer.Meta.model._default_manager.all()
self.parent_object = serializer.context["parent_object"]

def __call__(self, informatieobject: str):
attrs = {self.parent_field: self.parent_object, self.field: informatieobject}
def __call__(self, informatieobject: str, serializer):
attrs = {
self.parent_field: serializer.context["parent_object"],
self.field: informatieobject,
}
super().__call__(attrs)


Expand All @@ -232,17 +230,12 @@ class ObjectInformatieObjectValidator:
"Het informatieobject is in het DRC nog niet gerelateerd aan dit object."
)
code = "inconsistent-relation"
requires_context = True

def set_context(self, serializer):
"""
This hook is called by the serializer instance,
prior to the validation call being made.
"""
self.parent_object = serializer.context["parent_object"]
self.request = serializer.context["request"]

def __call__(self, informatieobject: str):
object_url = self.parent_object.get_absolute_api_url(self.request)
def __call__(self, informatieobject: str, serializer):
object_url = serializer.context["parent_object"].get_absolute_api_url(
self.request
)

# dynamic so that it can be mocked in tests easily
client = get_client(informatieobject)
Expand Down Expand Up @@ -311,40 +304,33 @@ class UniekeIdentificatieValidator:

message = _("Deze identificatie bestaat al binnen de organisatie")
code = "identificatie-niet-uniek"
requires_context = True

def __init__(self, organisatie_field: str, identificatie_field="identificatie"):
self.organisatie_field = organisatie_field
self.identificatie_field = identificatie_field

def set_context(self, serializer):
"""
This hook is called by the serializer instance,
prior to the validation call being made.
"""
# Determine the existing instance, if this is an update operation.
self.instance = getattr(serializer, "instance", None)
self.model = serializer.Meta.model

def __call__(self, attrs: dict):
def __call__(self, attrs: dict, serializer):
instance = getattr(serializer, "instance", None)
identificatie = attrs.get(self.identificatie_field)
if not identificatie:
if self.instance:
if instance:
# In case of a partial update
identificatie = self.instance.identificatie
identificatie = instance.identificatie
else:
# identification is being generated, and the generation checks for
# uniqueness
return

organisatie = attrs.get(self.organisatie_field)
pk = self.instance.pk if self.instance else None
pk = instance.pk if instance else None

# if we're updating an instance, setting the current values will not
# trigger an error because the instance-to-be-updated is excluded from
# the queryset. If either bronorganisatie or identificatie changes,
# and it already exists, it will raise a validation error
combination_exists = (
self.model.objects
serializer.Meta.model.objects
# in case of an update, exclude the current object. for a create, this
# will be None
.exclude(pk=pk)
Expand All @@ -370,22 +356,15 @@ class IsImmutableValidator:

message = _("Dit veld mag niet gewijzigd worden.")
code = "wijzigen-niet-toegelaten"
requires_context = True

def set_context(self, serializer_field):
"""
This hook is called by the serializer instance,
prior to the validation call being made.
"""
# Determine the existing instance, if this is an update operation.
self.serializer_field = serializer_field
self.instance = getattr(serializer_field.parent, "instance", None)

def __call__(self, new_value):
def __call__(self, new_value, serializer_field):
instance = getattr(serializer_field.parent, "instance", None)
# no instance -> it's not an update
if not self.instance:
if not instance:
return

current_value = getattr(self.instance, self.serializer_field.field_name)
current_value = getattr(instance, serializer_field.field_name)

if new_value != current_value:
raise serializers.ValidationError(self.message, code=self.code)
Expand Down
Loading