Skip to content

Commit dbc0376

Browse files
authored
Merge pull request #269 from mobinghoveoud/add-django-jalali-settings
Add django jalali settings
2 parents d0c09e4 + 3372775 commit dbc0376

File tree

5 files changed

+144
-23
lines changed

5 files changed

+144
-23
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
### Changed
4+
- Add Jalali settings
5+
36
## [7.2.0] - 2024-08-20
47
### Changed
58
- Confirm Django 5.1 support

README.rst

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,41 @@ Usage
6161
6262
$ python manage.py startapp foo
6363
64-
3. Edit settings.py_ and add django_jalali and your foo to your INSTALLED_APPS (also config DATABASES setting)
65-
66-
django_jalali should be added **before** your apps in order to work properly
64+
3. Edit your Django project's ``settings.py`` file to include ``django_jalali`` and your application in the ``INSTALLED_APPS`` list. Make sure that ``django_jalali`` is listed **before** your apps for proper functionality.
65+
66+
Additionally, you can configure library settings using the ``JALALI_SETTINGS`` dictionary. If a setting is not explicitly defined, the default values will be used.
67+
68+
.. code-block:: python
69+
70+
# settings.py
71+
INSTALLED_APPS = [
72+
"django.contrib.admin",
73+
"django.contrib.auth",
74+
"django.contrib.contenttypes",
75+
"django.contrib.sessions",
76+
"django.contrib.messages",
77+
"django.contrib.staticfiles",
78+
"django_jalali", # Place this before your custom apps
79+
]
80+
81+
JALALI_SETTINGS = {
82+
# JavaScript static files for the admin Jalali date widget
83+
"ADMIN_JS_STATIC_FILES": [
84+
"admin/jquery.ui.datepicker.jalali/scripts/jquery-1.10.2.min.js",
85+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.core.js",
86+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc.js",
87+
"admin/jquery.ui.datepicker.jalali/scripts/calendar.js",
88+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc-fa.js",
89+
"admin/main.js",
90+
],
91+
# CSS static files for the admin Jalali date widget
92+
"ADMIN_CSS_STATIC_FILES": {
93+
"all": [
94+
"admin/jquery.ui.datepicker.jalali/themes/base/jquery-ui.min.css",
95+
"admin/css/main.css",
96+
]
97+
},
98+
}
6799
68100
4. Edit foo/models.py_
69101

@@ -308,6 +340,16 @@ If you wish to limit the testing to specific environment(s), you can parametrize
308340
309341
$ tox -e py39-django42
310342
343+
To add a new value to the Jalali settings, just add its default value to the ``DEFAULTS`` dictionary located in ``django_jalali/setting.py``.
344+
345+
You can access the new setting in your code as shown below:
346+
347+
.. code-block:: python
348+
349+
from django_jalali.settings import jalali_settings
350+
351+
custom_settings = jalali_settings.CUSTOM_SETTINGS
352+
311353
.. _jdatetime: https://github.com/slashmili/python-jalali
312354
.. _Django: https://www.djangoproject.com/
313355
.. _settings.py: https://github.com/slashmili/django-jalali/blob/master/jalali_test/jalali_test/settings.py#L40

django_jalali/admin/widgets.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,17 @@
11
from django import forms
22
from django.contrib.admin.widgets import AdminTimeWidget
3-
from django.templatetags.static import static
43
from django.utils.safestring import mark_safe
54
from django.utils.translation import gettext as _
65

76
from django_jalali import forms as jforms
7+
from django_jalali.settings import jalali_settings
88

99

1010
class AdminjDateWidget(jforms.jDateInput):
11-
@property
12-
def media(self):
13-
js = [
14-
"jquery.ui.datepicker.jalali/scripts/jquery-1.10.2.min.js",
15-
"jquery.ui.datepicker.jalali/scripts/jquery.ui.core.js",
16-
"jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc.js",
17-
"jquery.ui.datepicker.jalali/scripts/calendar.js",
18-
"jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc-fa.js",
19-
"main.js",
20-
]
21-
22-
css = {
23-
"all": [
24-
"admin/jquery.ui.datepicker.jalali/themes/base/jquery-ui.min.css",
25-
"admin/css/main.css",
26-
]
27-
}
28-
29-
return forms.Media(js=[static("admin/%s" % path) for path in js], css=css)
11+
12+
class Media:
13+
js = jalali_settings.ADMIN_JS_STATIC_FILES
14+
css = jalali_settings.ADMIN_CSS_STATIC_FILES
3015

3116
def __init__(self, attrs=None, format=None):
3217
final_attrs = {"class": "vjDateField", "size": "10"}

django_jalali/settings.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from django.conf import settings
2+
from django.core.signals import setting_changed
3+
4+
DEFAULTS = {
5+
# JavaScript static files for the admin Jalali date widget
6+
"ADMIN_JS_STATIC_FILES": [
7+
"admin/jquery.ui.datepicker.jalali/scripts/jquery-1.10.2.min.js",
8+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.core.js",
9+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc.js",
10+
"admin/jquery.ui.datepicker.jalali/scripts/calendar.js",
11+
"admin/jquery.ui.datepicker.jalali/scripts/jquery.ui.datepicker-cc-fa.js",
12+
"admin/main.js",
13+
],
14+
# CSS static files for the admin Jalali date widget
15+
"ADMIN_CSS_STATIC_FILES": {
16+
"all": [
17+
"admin/jquery.ui.datepicker.jalali/themes/base/jquery-ui.min.css",
18+
"admin/css/main.css",
19+
]
20+
},
21+
}
22+
23+
24+
class JalaliSetting:
25+
def __init__(self, defaults=None):
26+
self._defaults = defaults or DEFAULTS
27+
self._attrs = set()
28+
29+
@property
30+
def user_settings(self):
31+
if not hasattr(self, "_user_settings"):
32+
self._user_settings = getattr(settings, "JALALI_SETTINGS", {})
33+
34+
return self._user_settings
35+
36+
def __getattr__(self, attr):
37+
if attr not in self._defaults:
38+
raise AttributeError(f"Invalid Jalali setting: {attr}")
39+
40+
try:
41+
val = self.user_settings[attr]
42+
except KeyError:
43+
val = self._defaults[attr]
44+
45+
# Cache the result
46+
self._attrs.add(attr)
47+
setattr(self, attr, val)
48+
49+
return val
50+
51+
def reload(self):
52+
for attr in self._attrs:
53+
delattr(self, attr)
54+
55+
self._attrs.clear()
56+
if hasattr(self, "_user_settings"):
57+
delattr(self, "_user_settings")
58+
59+
60+
jalali_settings = JalaliSetting()
61+
62+
63+
def reload_jalali_settings(*args, **kwargs):
64+
setting = kwargs["setting"]
65+
if setting == "JALALI_SETTINGS":
66+
jalali_settings.reload()
67+
68+
69+
setting_changed.connect(reload_jalali_settings)

tests/test_settings.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from django.test import TestCase, override_settings
2+
3+
from django_jalali.settings import DEFAULTS, jalali_settings
4+
5+
6+
class TestJalaliSettings(TestCase):
7+
def test_default_settings_loaded(self):
8+
for key, value in DEFAULTS.items():
9+
self.assertEqual(getattr(jalali_settings, key), value)
10+
11+
def test_override_settings(self):
12+
js = ["admin/scripts/custom.js"]
13+
with override_settings(JALALI_SETTINGS={"ADMIN_JS_STATIC_FILES": js}):
14+
self.assertEqual(jalali_settings.ADMIN_JS_STATIC_FILES, js)
15+
16+
self.assertEqual(
17+
jalali_settings.ADMIN_JS_STATIC_FILES, DEFAULTS["ADMIN_JS_STATIC_FILES"]
18+
)
19+
20+
def test_invalid_setting_access_raise_attribute_error(self):
21+
with self.assertRaises(AttributeError):
22+
jalali_settings.INVALID_SETTING

0 commit comments

Comments
 (0)