Skip to content

Commit 555c30d

Browse files
committed
Introduce app settings
Following the blueprint from [this blog post](https://overtag.dk/v2/blog/a-settings-pattern-for-reusable-django-apps/). Refactor DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH to use the new setting namespace and document it.
1 parent f57dbcf commit 555c30d

File tree

9 files changed

+80
-64
lines changed

9 files changed

+80
-64
lines changed

django_celery_results/conf.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Application settings."""
2+
from dataclasses import dataclass
3+
from typing import Any
4+
5+
from django.conf import settings as django_settings
6+
7+
# All attributes accessed with this prefix are possible
8+
# to overwrite through django.conf.settings.
9+
SETTINGS_PREFIX = "DJANGO_CELERY_RESULTS_"
10+
11+
12+
@dataclass(frozen=True)
13+
class AppSettings:
14+
"""Proxy class to encapsulate all the app settings.
15+
16+
This instance should be accessed via the singleton
17+
``django_celery_results.conf.app_settings``.
18+
19+
You shouldn't have to set any of these yourself, the class checks a Django
20+
settings with the same name and use these if defined, defaulting to the
21+
values documented here.
22+
"""
23+
24+
DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH: int = 255
25+
26+
def __getattribute__(self, __name: str) -> Any:
27+
"""Check if a Django project settings should override the app default.
28+
29+
In order to avoid returning any random properties of the Django
30+
settings, we first inspect the prefix.
31+
"""
32+
if (
33+
__name.startswith(SETTINGS_PREFIX)
34+
and hasattr(django_settings, __name)
35+
):
36+
return getattr(django_settings, __name)
37+
38+
return super().__getattribute__(__name)
39+
40+
41+
app_settings = AppSettings()

django_celery_results/migrations/0001_initial.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from django.conf import settings
21
from django.db import migrations, models
32

3+
from django_celery_results.conf import app_settings
4+
45

56
class Migration(migrations.Migration):
67

@@ -18,11 +19,7 @@ class Migration(migrations.Migration):
1819
serialize=False,
1920
verbose_name='ID')),
2021
('task_id', models.CharField(
21-
max_length=getattr(
22-
settings,
23-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
24-
255
25-
),
22+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
2623
unique=True,
2724
verbose_name='task id'
2825
)),

django_celery_results/migrations/0004_auto_20190516_0412.py

+4-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from django.conf import settings
88
from django.db import migrations, models
99

10+
from django_celery_results.conf import app_settings
11+
1012

1113
class Migration(migrations.Migration):
1214

@@ -61,11 +63,7 @@ class Migration(migrations.Migration):
6163
field=models.CharField(
6264
db_index=True,
6365
help_text='Celery ID for the Task that was run',
64-
max_length=getattr(
65-
settings,
66-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
67-
255
68-
),
66+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
6967
unique=True,
7068
verbose_name='Task ID'
7169
),
@@ -81,11 +79,7 @@ class Migration(migrations.Migration):
8179
field=models.CharField(
8280
db_index=True,
8381
help_text='Name of the Task which was run',
84-
max_length=getattr(
85-
settings,
86-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
87-
255
88-
),
82+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
8983
null=True,
9084
verbose_name='Task Name'),
9185
),

django_celery_results/migrations/0008_chordcounter.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Generated by Django 3.0.6 on 2020-05-12 12:05
22

3-
from django.conf import settings
43
from django.db import migrations, models
54

5+
from django_celery_results.conf import app_settings
6+
67

78
class Migration(migrations.Migration):
89

@@ -22,11 +23,7 @@ class Migration(migrations.Migration):
2223
('group_id', models.CharField(
2324
db_index=True,
2425
help_text='Celery ID for the Chord header group',
25-
max_length=getattr(
26-
settings,
27-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
28-
255
29-
),
26+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
3027
unique=True,
3128
verbose_name='Group ID')),
3229
('sub_tasks', models.TextField(

django_celery_results/migrations/0009_groupresult.py

+6-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Generated by Django 3.2 on 2021-04-19 14:55
2-
from django.conf import settings
32
from django.db import migrations, models
43

4+
from django_celery_results.conf import app_settings
5+
56

67
class FakeAddIndex(migrations.AddIndex):
78
"""Fake AddIndex to correct for duplicate index
@@ -35,11 +36,7 @@ class Migration(migrations.Migration):
3536
verbose_name='ID')),
3637
('group_id', models.CharField(
3738
help_text='Celery ID for the Group that was run',
38-
max_length=getattr(
39-
settings,
40-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
41-
255
42-
),
39+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
4340
unique=True,
4441
verbose_name='Group ID')),
4542
('date_created', models.DateTimeField(
@@ -81,11 +78,7 @@ class Migration(migrations.Migration):
8178
name='group_id',
8279
field=models.CharField(
8380
help_text='Celery ID for the Chord header group',
84-
max_length=getattr(
85-
settings,
86-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
87-
255
88-
),
81+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
8982
unique=True,
9083
verbose_name='Group ID'),
9184
),
@@ -128,11 +121,7 @@ class Migration(migrations.Migration):
128121
name='task_id',
129122
field=models.CharField(
130123
help_text='Celery ID for the Task that was run',
131-
max_length=getattr(
132-
settings,
133-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
134-
255
135-
),
124+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
136125
unique=True,
137126
verbose_name='Task ID'),
138127
),
@@ -141,11 +130,7 @@ class Migration(migrations.Migration):
141130
name='task_name',
142131
field=models.CharField(
143132
help_text='Name of the Task which was run',
144-
max_length=getattr(
145-
settings,
146-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
147-
255
148-
),
133+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH, # noqa: E501
149134
null=True,
150135
verbose_name='Task Name'),
151136
),

django_celery_results/models.py

+6-20
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
from celery import states
66
from celery.result import GroupResult as CeleryGroupResult
77
from celery.result import result_from_tuple
8-
from django.conf import settings
98
from django.db import models
109
from django.utils.translation import gettext_lazy as _
1110

1211
from . import managers
12+
from .conf import app_settings
1313

1414
ALL_STATES = sorted(states.ALL_STATES)
1515
TASK_STATE_CHOICES = sorted(zip(ALL_STATES, ALL_STATES))
@@ -19,11 +19,7 @@ class TaskResult(models.Model):
1919
"""Task result/status."""
2020

2121
task_id = models.CharField(
22-
max_length=getattr(
23-
settings,
24-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
25-
255
26-
),
22+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
2723
unique=True,
2824
verbose_name=_('Task ID'),
2925
help_text=_('Celery ID for the Task that was run'))
@@ -32,11 +28,8 @@ class TaskResult(models.Model):
3228
verbose_name=_('Periodic Task Name'),
3329
help_text=_('Name of the Periodic Task which was run'))
3430
task_name = models.CharField(
35-
null=True, max_length=getattr(
36-
settings,
37-
'DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH',
38-
255
39-
),
31+
null=True,
32+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
4033
verbose_name=_('Task Name'),
4134
help_text=_('Name of the Task which was run'))
4235
task_args = models.TextField(
@@ -140,10 +133,7 @@ class ChordCounter(models.Model):
140133
"""Chord synchronisation."""
141134

142135
group_id = models.CharField(
143-
max_length=getattr(
144-
settings,
145-
"DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH",
146-
255),
136+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
147137
unique=True,
148138
verbose_name=_("Group ID"),
149139
help_text=_("Celery ID for the Chord header group"),
@@ -181,11 +171,7 @@ class GroupResult(models.Model):
181171
"""Task Group result/status."""
182172

183173
group_id = models.CharField(
184-
max_length=getattr(
185-
settings,
186-
"DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH",
187-
255
188-
),
174+
max_length=app_settings.DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH,
189175
unique=True,
190176
verbose_name=_("Group ID"),
191177
help_text=_("Celery ID for the Group that was run"),

docs/configuration.rst

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Configuration
2+
=============
3+
4+
These are the available settings that can be configured in your Django
5+
project's settings module by defining a setting with the same name.
6+
7+
.. _settings-task_id_max_length:
8+
9+
* ``DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH`` (Default: ``255``)
10+
11+
The max length, as an integer, of the ``task_id`` and ``task_name``
12+
fields on the ``TaskResult`` model. Defaults to 255.
13+
14+
Also used for the max length of the ``group_id`` fields on the
15+
``GroupResult`` and ``ChordCounter`` models.

docs/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Contents
1212

1313
getting_started
1414
injecting_metadata
15+
configuration
1516
copyright
1617

1718
.. toctree::

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ markers =
99
[flake8]
1010
# classes can be lowercase, arguments and variables can be uppercase
1111
# whenever it makes the code more readable.
12-
ignore = N806, N802, N801, N803
12+
ignore = N806, N802, N801, N803, W503
1313

1414
[pep257]
1515
convention=google

0 commit comments

Comments
 (0)