Skip to content

Commit da15957

Browse files
committed
refactor: rename 'ObjectsClientConfiguration' to 'ObjectsAPIServiceConfiguration'
The naming of the configuration class was confusing. Also changed the field names for the ZGW API client configurations for the same reason.
1 parent 733ed43 commit da15957

File tree

7 files changed

+156
-98
lines changed

7 files changed

+156
-98
lines changed

CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ Maintenance and refactoring
3333
- Replaced magic number for cache timeout with named constant.
3434
- Replaced old '.format()' syntax with modern f-strings.
3535
* Improved error-handling for API clients.
36+
* Renamed 'ObjectsClientConfiguration' to 'ObjectsAPIServiceConfiguration'
37+
as well as the fields for the ZGW client configurations. This is lesss
38+
confusing and captures the intent of the code better.
3639

3740

3841
0.4.1 (2025-12-03)

objectsapiclient/admin.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44

55
from solo.admin import SingletonModelAdmin
66

7-
from .models import ObjectsClientConfiguration
7+
from .models import ObjectsAPIServiceConfiguration
88

99

10-
@admin.register(ObjectsClientConfiguration)
11-
class ObjectsClientConfigurationAdmin(SingletonModelAdmin):
10+
@admin.register(ObjectsAPIServiceConfiguration)
11+
class ObjectsAPIServiceConfigurationAdmin(SingletonModelAdmin):
1212
fieldsets = (
1313
(
1414
None,
1515
{
1616
"fields": (
17-
"objects_api_service_config",
18-
"object_type_api_service_config",
17+
"objects_api_client_config",
18+
"objecttype_api_client_config",
1919
"status",
2020
)
2121
},
@@ -24,7 +24,7 @@ class ObjectsClientConfigurationAdmin(SingletonModelAdmin):
2424
readonly_fields = ("status",)
2525

2626
@admin.display
27-
def status(self, obj: ObjectsClientConfiguration) -> SafeString:
27+
def status(self, obj: ObjectsAPIServiceConfiguration) -> SafeString:
2828
from django.contrib.admin.templatetags.admin_list import _boolean_icon
2929
from django.core.exceptions import ImproperlyConfigured
3030

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Generated manually for model and field renames
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
dependencies = [
9+
("objectsapiclient", "0004_alter_objectsclientconfiguration_options_and_more"),
10+
("zgw_consumers", "0016_auto_20220818_1412"),
11+
]
12+
13+
operations = [
14+
migrations.RenameModel(
15+
old_name="ObjectsClientConfiguration",
16+
new_name="ObjectsAPIServiceConfiguration",
17+
),
18+
migrations.AlterModelOptions(
19+
name="objectsapiserviceconfiguration",
20+
options={"verbose_name": "Objects API service configuration"},
21+
),
22+
migrations.RenameField(
23+
model_name="objectsapiserviceconfiguration",
24+
old_name="objects_api_service_config",
25+
new_name="objects_api_client_config",
26+
),
27+
migrations.RenameField(
28+
model_name="objectsapiserviceconfiguration",
29+
old_name="object_type_api_service_config",
30+
new_name="objecttype_api_client_config",
31+
),
32+
migrations.AlterField(
33+
model_name="objectsapiserviceconfiguration",
34+
name="objects_api_client_config",
35+
field=models.ForeignKey(
36+
blank=True,
37+
null=True,
38+
on_delete=django.db.models.deletion.CASCADE,
39+
related_name="objects_api_client_config",
40+
to="zgw_consumers.service",
41+
),
42+
),
43+
migrations.AlterField(
44+
model_name="objectsapiserviceconfiguration",
45+
name="objecttype_api_client_config",
46+
field=models.ForeignKey(
47+
blank=True,
48+
null=True,
49+
on_delete=django.db.models.deletion.CASCADE,
50+
related_name="objecttype_api_client_config",
51+
to="zgw_consumers.service",
52+
),
53+
),
54+
]

objectsapiclient/models.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,31 @@
1919
OBJECTTYPE_CACHE_TIMEOUT = 60 # seconds
2020

2121

22-
class ObjectsClientConfiguration(SingletonModel):
22+
class ObjectsAPIServiceConfiguration(SingletonModel):
2323
"""
24-
The Objects API client configuration to retrieve and render forms.
24+
The Objects API service configuration to retrieve and render forms.
2525
"""
2626

27-
objects_api_service_config = models.ForeignKey(
27+
objects_api_client_config = models.ForeignKey(
2828
"zgw_consumers.Service",
2929
on_delete=models.CASCADE,
3030
null=True,
3131
blank=True,
32-
related_name="objects_api_service_config",
32+
related_name="objects_api_client_config",
3333
)
34-
object_type_api_service_config = models.ForeignKey(
34+
objecttype_api_client_config = models.ForeignKey(
3535
"zgw_consumers.Service",
3636
on_delete=models.CASCADE,
3737
null=True,
3838
blank=True,
39-
related_name="object_type_api_service_config",
39+
related_name="objecttype_api_client_config",
4040
)
4141

4242
class Meta:
43-
verbose_name = _("Objects API client configuration")
43+
verbose_name = _("Objects API service configuration")
4444

4545
def __str__(self):
46-
return "Objects API client configuration"
46+
return "Objects API service configuration"
4747

4848

4949
class ObjectTypeField(models.SlugField):
@@ -115,7 +115,7 @@ def get_choices(
115115
# Check if database table exists (migrations have been run)
116116
# Prevents errors during startup before migrations are applied
117117
try:
118-
config = ObjectsClientConfiguration.get_solo()
118+
config = ObjectsAPIServiceConfiguration.get_solo()
119119
except (ProgrammingError, OperationalError):
120120
logger.info(
121121
"objectsapiclient_configuration table does not exist yet, "
@@ -128,8 +128,8 @@ def get_choices(
128128
# Check if Objects API services are configured
129129
# Prevents HTTP requests when services aren't set up
130130
if (
131-
not config.objects_api_service_config
132-
or not config.object_type_api_service_config
131+
not config.objects_api_client_config
132+
or not config.objecttype_api_client_config
133133
):
134134
logger.info(
135135
"Objects API services not configured, skipping objecttypes fetch"

objectsapiclient/services.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,40 @@
1111

1212
from .dataclasses import Object, ObjectType
1313
from .exceptions import ObjectsAPIClientValidationError
14-
from .models import ObjectsClientConfiguration
14+
from .models import ObjectsAPIServiceConfiguration
1515

1616
logger = logging.getLogger(__name__)
1717

1818

1919
class ObjectsAPIService:
20-
def __init__(self, config: ObjectsClientConfiguration | None = None):
20+
def __init__(self, config: ObjectsAPIServiceConfiguration | None = None):
2121
self.config = cast(
22-
ObjectsClientConfiguration, config or ObjectsClientConfiguration.get_solo()
22+
ObjectsAPIServiceConfiguration,
23+
config or ObjectsAPIServiceConfiguration.get_solo(),
2324
)
2425

2526
if (
26-
not self.config.objects_api_service_config
27-
or not self.config.object_type_api_service_config
27+
not self.config.objects_api_client_config
28+
or not self.config.objecttype_api_client_config
2829
):
2930
raise ImproperlyConfigured(
3031
"ObjectsAPIService cannot be instantiated without configurations for "
3132
"Objects API and Objecttypes API"
3233
)
3334

3435
self.objects_client: APIClient = build_zgw_client(
35-
service=self.config.objects_api_service_config
36+
service=self.config.objects_api_client_config
3637
)
3738
self.object_types_client: APIClient = build_zgw_client(
38-
service=self.config.object_type_api_service_config
39+
service=self.config.objecttype_api_client_config
3940
)
4041

4142
def is_healthy(self) -> tuple[bool, str]:
4243
try:
4344
self.objects_client.request(
4445
"head",
4546
urljoin(
46-
base=self.config.objects_api_service_config.api_root, url="objects"
47+
base=self.config.objects_api_client_config.api_root, url="objects"
4748
),
4849
)
4950
return True, ""

tests/test_model_fields.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from objectsapiclient.models import (
1414
LazyObjectTypeField,
15-
ObjectsClientConfiguration,
15+
ObjectsAPIServiceConfiguration,
1616
ObjectTypeField,
1717
)
1818

@@ -203,7 +203,7 @@ def test_get_choices_handles_exception_with_blank(
203203

204204

205205
class TestLazyObjectTypeField:
206-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
206+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
207207
@pytest.mark.parametrize(
208208
"include_blank,expected", [(True, BLANK_CHOICE_DASH), (False, [])]
209209
)
@@ -222,7 +222,7 @@ def test_get_choices_when_table_does_not_exist(
222222
assert choices == expected
223223
mock_get_solo.assert_called_once()
224224

225-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
225+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
226226
@pytest.mark.parametrize(
227227
"include_blank,expected", [(True, BLANK_CHOICE_DASH), (False, [])]
228228
)
@@ -240,24 +240,24 @@ def test_get_choices_when_operational_error(
240240
assert choices == expected
241241
mock_get_solo.assert_called_once()
242242

243-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
243+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
244244
@pytest.mark.parametrize(
245245
"include_blank,expected", [(True, BLANK_CHOICE_DASH), (False, [])]
246246
)
247247
def test_get_choices_when_services_not_configured(
248248
self, mock_get_solo, include_blank, expected
249249
):
250-
mock_config = Mock(spec=ObjectsClientConfiguration)
251-
mock_config.objects_api_service_config = None
252-
mock_config.object_type_api_service_config = None
250+
mock_config = Mock(spec=ObjectsAPIServiceConfiguration)
251+
mock_config.objects_api_client_config = None
252+
mock_config.objecttype_api_client_config = None
253253
mock_get_solo.return_value = mock_config
254254

255255
field = LazyObjectTypeField()
256256
choices = field.get_choices(include_blank=include_blank)
257257

258258
assert choices == expected
259259

260-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
260+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
261261
@pytest.mark.parametrize(
262262
"objects_api,object_type_api,include_blank,expected",
263263
[
@@ -275,9 +275,9 @@ def test_get_choices_when_only_one_service_configured(
275275
include_blank,
276276
expected,
277277
):
278-
mock_config = Mock(spec=ObjectsClientConfiguration)
279-
mock_config.objects_api_service_config = objects_api
280-
mock_config.object_type_api_service_config = object_type_api
278+
mock_config = Mock(spec=ObjectsAPIServiceConfiguration)
279+
mock_config.objects_api_client_config = objects_api
280+
mock_config.objecttype_api_client_config = object_type_api
281281
mock_get_solo.return_value = mock_config
282282

283283
field = LazyObjectTypeField()
@@ -286,7 +286,7 @@ def test_get_choices_when_only_one_service_configured(
286286
assert choices == expected
287287

288288
@patch("objectsapiclient.models.get_object_type_choices")
289-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
289+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
290290
@pytest.mark.parametrize(
291291
"include_blank,expected",
292292
[
@@ -297,9 +297,9 @@ def test_get_choices_when_only_one_service_configured(
297297
def test_get_choices_when_fully_configured(
298298
self, mock_get_solo, mock_get_choices, clear_cache, include_blank, expected
299299
):
300-
mock_config = Mock(spec=ObjectsClientConfiguration)
301-
mock_config.objects_api_service_config = Mock()
302-
mock_config.object_type_api_service_config = Mock()
300+
mock_config = Mock(spec=ObjectsAPIServiceConfiguration)
301+
mock_config.objects_api_client_config = Mock()
302+
mock_config.objecttype_api_client_config = Mock()
303303
mock_get_solo.return_value = mock_config
304304

305305
mock_get_choices.return_value = [
@@ -313,7 +313,7 @@ def test_get_choices_when_fully_configured(
313313
assert choices == expected
314314
mock_get_choices.assert_called_once()
315315

316-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
316+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
317317
def test_database_error_prevention_during_migrations(self, mock_get_solo):
318318
"""
319319
Test that LazyObjectTypeField prevents errors during migrations
@@ -328,16 +328,16 @@ def test_database_error_prevention_during_migrations(self, mock_get_solo):
328328
assert choices == BLANK_CHOICE_DASH
329329

330330
@patch("objectsapiclient.models.get_object_type_choices")
331-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
331+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
332332
def test_prevents_unnecessary_http_requests_on_startup(
333333
self, mock_get_solo, mock_get_choices
334334
):
335335
"""
336336
Test that LazyObjectTypeField doesn't make HTTP requests when not configured
337337
"""
338-
mock_config = Mock(spec=ObjectsClientConfiguration)
339-
mock_config.objects_api_service_config = None
340-
mock_config.object_type_api_service_config = None
338+
mock_config = Mock(spec=ObjectsAPIServiceConfiguration)
339+
mock_config.objects_api_client_config = None
340+
mock_config.objecttype_api_client_config = None
341341
mock_get_solo.return_value = mock_config
342342

343343
field = LazyObjectTypeField()
@@ -347,18 +347,18 @@ def test_prevents_unnecessary_http_requests_on_startup(
347347
mock_get_choices.assert_not_called()
348348

349349
@patch("objectsapiclient.models.get_object_type_choices")
350-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
350+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
351351
def test_uses_correct_field_names_when_checking_configuration(
352352
self, mock_get_solo, mock_get_choices
353353
):
354354
"""
355355
Regression test 1 for accessing non-existent config.objects_api_service
356-
instead of config.objects_api_service_config: no API services configured
356+
instead of config.objects_api_client_config: no API services configured
357357
"""
358358
# A SimpleNamespace object only has the exact attributes we set (unlike Mock)
359359
# Will raise AttributeError if code tries to access wrong attribute names
360360
mock_config = SimpleNamespace(
361-
objects_api_service_config=None, object_type_api_service_config=None
361+
objects_api_client_config=None, objecttype_api_client_config=None
362362
)
363363

364364
mock_get_solo.return_value = mock_config
@@ -374,22 +374,22 @@ def test_uses_correct_field_names_when_checking_configuration(
374374
mock_get_choices.assert_not_called()
375375

376376
@patch("objectsapiclient.models.get_object_type_choices")
377-
@patch("objectsapiclient.models.ObjectsClientConfiguration.get_solo")
377+
@patch("objectsapiclient.models.ObjectsAPIServiceConfiguration.get_solo")
378378
def test_correctly_detects_configured_services(
379379
self, mock_get_solo, mock_get_choices, clear_cache
380380
):
381381
"""
382382
Regression test 2 for accessing non-existent config.objects_api_service
383-
instead of config.objects_api_service_config: both API services configured
383+
instead of config.objects_api_client_config: both API services configured
384384
"""
385385
mock_service = Mock()
386386
mock_service.api_root = "https://example.com/api/"
387387

388388
# A SimpleNamespace object only has the exact attributes we set (unlike Mock)
389389
# Will raise AttributeError if code tries to access wrong attribute names
390390
mock_config = SimpleNamespace(
391-
objects_api_service_config=mock_service,
392-
object_type_api_service_config=mock_service,
391+
objects_api_client_config=mock_service,
392+
objecttype_api_client_config=mock_service,
393393
)
394394

395395
mock_get_solo.return_value = mock_config

0 commit comments

Comments
 (0)