djangobible 0.0.25__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. djangobible-0.3.0/PKG-INFO +270 -0
  2. {djangobible-0.0.25 → djangobible-0.3.0}/README.md +37 -38
  3. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/__init__.py +2 -3
  4. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/fields.py +14 -13
  5. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/migrations/0001_initial.py +0 -1
  6. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/models.py +5 -6
  7. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/templatetags/verse_tags.py +6 -10
  8. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/validators.py +9 -8
  9. djangobible-0.3.0/pyproject.toml +132 -0
  10. djangobible-0.0.25/.coveragerc +0 -5
  11. djangobible-0.0.25/.github/workflows/codeql-analysis.yml +0 -62
  12. djangobible-0.0.25/.github/workflows/django.yml +0 -41
  13. djangobible-0.0.25/.gitignore +0 -134
  14. djangobible-0.0.25/.pre-commit-config.yaml +0 -48
  15. djangobible-0.0.25/.sourcery.yaml +0 -2
  16. djangobible-0.0.25/CODE_OF_CONDUCT.md +0 -76
  17. djangobible-0.0.25/CONTRIBUTING.md +0 -30
  18. djangobible-0.0.25/LICENSE +0 -21
  19. djangobible-0.0.25/PKG-INFO +0 -7
  20. djangobible-0.0.25/manage.py +0 -24
  21. djangobible-0.0.25/pyproject.toml +0 -35
  22. djangobible-0.0.25/requirements-dev.txt +0 -1
  23. djangobible-0.0.25/requirements-test.txt +0 -3
  24. djangobible-0.0.25/requirements.txt +0 -2
  25. djangobible-0.0.25/setup.cfg +0 -49
  26. djangobible-0.0.25/setup.py +0 -31
  27. djangobible-0.0.25/test_django_app/__init__.py +0 -0
  28. djangobible-0.0.25/test_django_app/admin.py +0 -10
  29. djangobible-0.0.25/test_django_app/apps.py +0 -11
  30. djangobible-0.0.25/test_django_app/migrations/0001_initial.py +0 -33
  31. djangobible-0.0.25/test_django_app/migrations/0002_testsingleverseobject.py +0 -33
  32. djangobible-0.0.25/test_django_app/migrations/0003_alter_testsingleverseobject_verse.py +0 -22
  33. djangobible-0.0.25/test_django_app/migrations/__init__.py +0 -0
  34. djangobible-0.0.25/test_django_app/models.py +0 -29
  35. djangobible-0.0.25/test_django_app/templates/verse_tags.html +0 -19
  36. djangobible-0.0.25/test_django_app/tests/__init__.py +0 -0
  37. djangobible-0.0.25/test_django_app/tests/factories.py +0 -42
  38. djangobible-0.0.25/test_django_app/tests/test_admin.py +0 -77
  39. djangobible-0.0.25/test_django_app/tests/test_models.py +0 -292
  40. djangobible-0.0.25/test_django_app/tests/test_search.py +0 -56
  41. djangobible-0.0.25/test_django_app/tests/test_tags.py +0 -123
  42. djangobible-0.0.25/test_django_app/tests/test_tags_functional.py +0 -45
  43. djangobible-0.0.25/test_django_app/tests/test_validators.py +0 -29
  44. djangobible-0.0.25/test_django_app/views.py +0 -16
  45. djangobible-0.0.25/test_django_project/__init__.py +0 -0
  46. djangobible-0.0.25/test_django_project/asgi.py +0 -18
  47. djangobible-0.0.25/test_django_project/settings.py +0 -123
  48. djangobible-0.0.25/test_django_project/urls.py +0 -11
  49. djangobible-0.0.25/test_django_project/wsgi.py +0 -18
  50. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/apps.py +0 -0
  51. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/migrations/__init__.py +0 -0
  52. {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/templatetags/__init__.py +0 -0
@@ -0,0 +1,270 @@
1
+ Metadata-Version: 2.4
2
+ Name: djangobible
3
+ Version: 0.3.0
4
+ Author: Nathan Patton
5
+ Author-email: Nathan Patton <npatton@gmail.com>
6
+ License-Expression: MIT
7
+ Classifier: Framework :: Django
8
+ Classifier: Intended Audience :: Information Technology
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
12
+ Classifier: Topic :: Software Development :: Libraries
13
+ Classifier: Topic :: Software Development
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: License :: OSI Approved :: MIT License
23
+ Requires-Dist: django>=4.2.0
24
+ Requires-Dist: pythonbible==0.14.0
25
+ Requires-Python: >=3.10
26
+ Project-URL: Source, https://github.com/avendesora/djangobible
27
+ Description-Content-Type: text/markdown
28
+
29
+ # djangobible
30
+
31
+ The djangobible library is a Django app that wraps the [pythonbible](https://github.com/avendesora/pythonbible) library and provides models, managers, and other tools to easily index an object by a scripture reference.
32
+
33
+ <table>
34
+ <tr>
35
+ <td>Latest Version</td>
36
+ <td>
37
+ <a href="https://pypi.org/project/djangobible/"><img src="https://img.shields.io/pypi/v/djangobible?color=gold&logo=pypi&logoColor=lightgray"></a>
38
+ <img src="https://img.shields.io/pypi/dm/djangobible?color=gold">
39
+ </td>
40
+ </tr>
41
+ <tr>
42
+ <td>License</td>
43
+ <td><a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-orange.svg"></a></td>
44
+ </tr>
45
+ <tr>
46
+ <td>Tests</td>
47
+ <td>
48
+ <img src="https://github.com/avendesora/djangobible/actions/workflows/tests.yml/badge.svg">
49
+ <img src="https://github.com/avendesora/djangobible/workflows/Django%20CI/badge.svg"><br/>
50
+ <a href="https://app.codacy.com/gh/avendesora/djangobible/coverage/dashboard"><img src="https://app.codacy.com/project/badge/Coverage/83a28131bf6642ed9e439344122686fc"></a>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <td>Code Quality</td>
55
+ <td>
56
+ <img src="https://github.com/avendesora/djangobible/workflows/CodeQL/badge.svg">
57
+ <a href="https://app.codacy.com/gh/avendesora/djangobible?utm_source=github.com&utm_medium=referral&utm_content=avendesora/djangobible&utm_campaign=Badge_Grade_Settings"><img src="https://api.codacy.com/project/badge/Grade/ca34603bdaf8446ba288430b69092093"></a><br/>
58
+ <a href="https://results.pre-commit.ci/latest/github/avendesora/djangobible/main"><img src="https://results.pre-commit.ci/badge/github/avendesora/djangobible/main.svg"></a>
59
+ <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
60
+ </td>
61
+ </tr>
62
+ <tr>
63
+ <td>Supported Python/Django Versions</td>
64
+ <td>
65
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue?logo=python&logoColor=lightgray"></a><br />
66
+ <a href="https://www.djangoproject.com/download/"><img src="https://img.shields.io/badge/Django-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2-blue"></a><br />
67
+ </td>
68
+ </tr>
69
+ </table>
70
+
71
+ ## Installation
72
+
73
+ Pip install the djangobible library.
74
+
75
+ ```shell script
76
+ pip install djangobible
77
+ ```
78
+
79
+ Add djangobible to your Django project's ``INSTALLED_APPS`` setting:
80
+
81
+ ```python
82
+ INSTALLED_APPS = [
83
+ ..., # other apps
84
+ "djangobible",
85
+ ]
86
+ ```
87
+
88
+ Run the django migrations for djangobible
89
+
90
+ ```shell script
91
+ ./manage.py migrate djangobible
92
+ ```
93
+
94
+ ### Settings
95
+
96
+ There currently are no settings (other than INSTALLED_APPS) related to the djangobible project. In the future, it would be nice to have settings that determine things like the available versions of the Bible and the default version.
97
+
98
+ Also, once support is implemented for multiple locales and languages, there could be related settings for that functionality.
99
+
100
+ ## Features
101
+
102
+ The djangobible library is a complete wrapper for the [pythonbible](https://github.com/avendesora/pythonbible) library, so importing the djangobible library as:
103
+
104
+ ```python
105
+ import djangobible as bible
106
+ ```
107
+
108
+ will provide all the same functionality as importing the pythonbible library as:
109
+
110
+ ```python
111
+ import pythonbible as bible
112
+ ```
113
+
114
+ This includes features such as:
115
+ - Searching text for Scripture references
116
+ - Converting a normalized scripture reference into a list of integer verse ids
117
+ - Converting a list of verse id integers into a list of normalized scripture references
118
+ - Converting a list of normalized scripture references into a formatted string scripture reference
119
+ - Retrieving the Biblical text (in one or more open-source or public domain versions) for a given verse ID integer
120
+
121
+ For more information, see the [pythonbible documentation](https://github.com/avendesora/pythonbible).
122
+
123
+ In addition, the djangobible library includes the following features:
124
+
125
+ ### Template Tags
126
+
127
+ There are currently two template tags provided by the djangobible library: ``verse_reference`` and ``verse_text``.
128
+
129
+ #### verse_reference
130
+
131
+ The ``verse_reference`` template tag, given a verse ID and a Bible version, returns the appropriate Scripture reference string.
132
+
133
+ For example, given ``verse_id = 1001001`` and ``version = djangobible.Version.KING_JAMES``, the following snippet from a Django template:
134
+
135
+ ```html
136
+ {% load verse_tags %}
137
+ ...
138
+ {% verse_reference verse_id version=version %}
139
+ ```
140
+
141
+ would display:
142
+
143
+ ```
144
+ Genesis 1:1
145
+ ```
146
+
147
+ The version parameter is optional, and the current default is King James, though that will ideally be configurable in the future.
148
+
149
+ There is another optional parameter, ``full_title``, which is a boolean flag to determine whether to display the long version or the short version of the book of the Bible title. It defaults to ``False``, which displays the short version. For example, given ``verse_id = 1001001`` and ``version = djangobible.Version.KING_JAMES`` and ``full_title = True``, the following snippet from a Django template:
150
+
151
+ ```html
152
+ {% load verse_tags %}
153
+ ...
154
+ {% verse_reference verse_id version=version full_title=full_title %}
155
+ ```
156
+
157
+ would display:
158
+
159
+ ```
160
+ The First Book of Moses, called Genesis 1:1
161
+ ```
162
+
163
+ #### verse_text
164
+
165
+ The ``verse_text`` template tag, given a verse ID and a Bible version, returns the appropriate text of that Bible verse.
166
+
167
+ For example, given ``verse_id = 1001001`` and ``version = djangobible.Version.KING_JAMES``, the following snippet from a Django template:
168
+
169
+ ```html
170
+ {% load verse_tags %}
171
+ ...
172
+ {% verse_text verse_id %}
173
+ ```
174
+
175
+ would display:
176
+
177
+ ```
178
+ In the beginning God created the heaven and the earth.
179
+ ```
180
+
181
+ The version parameter is optional, and the current default is King James, though that will ideally be configurable in the future.
182
+
183
+ ### One-to-many style relationships between verses and Django models
184
+
185
+ For situations where an instance of a Django model needs to be associated with a single verse, that Django model can have a field of type ``VerseField``.
186
+
187
+ For example:
188
+
189
+ ```python
190
+ from django.db import models
191
+
192
+ import djangobible as bible
193
+
194
+
195
+ class MyModel(models.Model):
196
+ ... # other fields
197
+
198
+ verse = bible.VerseField()
199
+ ```
200
+
201
+ The underlying implementation of ``VerseField`` is an ``IntegerField`` which stores the verse ID of the associated verse.
202
+
203
+ Having this custom field type provides several benefits:
204
+ - The Django admin (and Wagtail) form contains a text field for the verse rather than an integer field and allows the user to enter the Scripture reference text rather than the verse id, which they may not know. It then validates that text to ensure it references one, and only one, verse.
205
+ - As just mentioned, this allows for validation, not only that the value is one, and only one, verse id, but that it is also a valid verse id (i.e. that it represents a book, chapter, and verse of the Bible that actually exists).
206
+ - More readable query filters (e.g. ``MyModel.objects.filter(verse=1001001)`` is valid, but so is ``MyModel.objects.filter(verse="Genesis 1:1")``).
207
+
208
+ You can set the verse field with either the int verse ID or the string reference:
209
+
210
+ ```python
211
+ my_object = MyModel.objects.create(name="my object")
212
+ my_object.verse = 1001001
213
+ my_object.save()
214
+ ```
215
+
216
+ or
217
+
218
+ ```python
219
+ my_object = MyModel.objects.create(name="my object")
220
+ my_object.verse = "Genesis 1:1"
221
+ my_object.save()
222
+ ```
223
+
224
+ You can filter the objects in the query set by either the int verse ID or the string reference:
225
+
226
+ ```python
227
+ MyModel.objects.filter(verse=1001001)
228
+ ```
229
+
230
+ or
231
+
232
+ ```python
233
+ MyModel.objects.filter(verse="Genesis 1:1")
234
+ ```
235
+
236
+ In any of the above examples, if the verse is not a valid verse ID integer or string reference for a single verse, then a ``ValidationError`` will be raised.
237
+
238
+ ### Many-to-many style relationships between verses and Django models
239
+
240
+ > **WARNING**: This is still a work in progress, and this functionality does not yet exist in a stable form.
241
+
242
+ There are situations where an instance of a Django model needs to be associated with multiple verses. The current intended solution, inspired by the [django-taggit](https://github.com/jazzband/django-taggit) library, is to implement this feature in such a way that you would add this relationship to your model like:
243
+
244
+ ```python
245
+ from django.db import models
246
+
247
+ import djangobible as bible
248
+
249
+
250
+ class MyModel(models.Model):
251
+ ... # other fields
252
+
253
+ verses = bible.VerseManager()
254
+ ```
255
+
256
+ Then you could add, remove, and reference those verses with something like:
257
+
258
+ ```
259
+ >>> my_object = MyModel.objects.create(name="My Object")
260
+ >>> my_object.verses.add("Genesis 1:1-3")
261
+ >>> my_object.verses.all()
262
+ [<Verse: Genesis 1:1>, <Verse: Genesis 1:2>, <Verse: Genesis 1:3>]
263
+ >>> my_object.verses.remove("Genesis 1:2")
264
+ >>> my_object.verses.all()
265
+ [<Verse: Genesis 1:1>, <Verse: Genesis 1:3>]
266
+ >>> MyModel.objects.filter(verses__in=[1001001])
267
+ [<MyModel: My Object>]
268
+ ```
269
+
270
+ Ideally, the form field would be a text field where the user could enter a list of Scripture references (e.g. "Genesis 1:1,3-10;Psalm 119;Luke 2:1-18;John 3:16")
@@ -2,20 +2,43 @@
2
2
 
3
3
  The djangobible library is a Django app that wraps the [pythonbible](https://github.com/avendesora/pythonbible) library and provides models, managers, and other tools to easily index an object by a scripture reference.
4
4
 
5
- [![PyPI version](https://img.shields.io/pypi/v/djangobible?color=blue&logo=pypi&logoColor=lightgray)](https://pypi.org/project/djangobible/)
6
- [![license MIT](https://img.shields.io/badge/license-MIT-orange.svg)](https://opensource.org/licenses/MIT)
7
-
8
- ![Django CI](https://github.com/avendesora/djangobible/workflows/Django%20CI/badge.svg)
9
- [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/83a28131bf6642ed9e439344122686fc)](https://www.codacy.com/gh/avendesora/djangobible/dashboard?utm_source=github.com&utm_medium=referral&utm_content=avendesora/djangobible&utm_campaign=Badge_Coverage)
10
-
11
- ![CodeQL](https://github.com/avendesora/djangobible/workflows/CodeQL/badge.svg)
12
- [![Codacy Badge](https://api.codacy.com/project/badge/Grade/ca34603bdaf8446ba288430b69092093)](https://app.codacy.com/gh/avendesora/djangobible?utm_source=github.com&utm_medium=referral&utm_content=avendesora/djangobible&utm_campaign=Badge_Grade_Settings)
13
-
14
- [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/avendesora/djangobible/main.svg)](https://results.pre-commit.ci/latest/github/avendesora/djangobible/main)
15
- [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
16
-
17
- [![Python 3.10](https://img.shields.io/badge/python-3.7%20%7C%203.8%20%7C%203.9%20%7C%203.10-blue?logo=python&logoColor=lightgray)](https://www.python.org/downloads/)
18
- [![Django 3.2+](https://img.shields.io/badge/Django-3.2%20%7C%204.0-blue)](https://www.djangoproject.com/download/)
5
+ <table>
6
+ <tr>
7
+ <td>Latest Version</td>
8
+ <td>
9
+ <a href="https://pypi.org/project/djangobible/"><img src="https://img.shields.io/pypi/v/djangobible?color=gold&logo=pypi&logoColor=lightgray"></a>
10
+ <img src="https://img.shields.io/pypi/dm/djangobible?color=gold">
11
+ </td>
12
+ </tr>
13
+ <tr>
14
+ <td>License</td>
15
+ <td><a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-orange.svg"></a></td>
16
+ </tr>
17
+ <tr>
18
+ <td>Tests</td>
19
+ <td>
20
+ <img src="https://github.com/avendesora/djangobible/actions/workflows/tests.yml/badge.svg">
21
+ <img src="https://github.com/avendesora/djangobible/workflows/Django%20CI/badge.svg"><br/>
22
+ <a href="https://app.codacy.com/gh/avendesora/djangobible/coverage/dashboard"><img src="https://app.codacy.com/project/badge/Coverage/83a28131bf6642ed9e439344122686fc"></a>
23
+ </td>
24
+ </tr>
25
+ <tr>
26
+ <td>Code Quality</td>
27
+ <td>
28
+ <img src="https://github.com/avendesora/djangobible/workflows/CodeQL/badge.svg">
29
+ <a href="https://app.codacy.com/gh/avendesora/djangobible?utm_source=github.com&utm_medium=referral&utm_content=avendesora/djangobible&utm_campaign=Badge_Grade_Settings"><img src="https://api.codacy.com/project/badge/Grade/ca34603bdaf8446ba288430b69092093"></a><br/>
30
+ <a href="https://results.pre-commit.ci/latest/github/avendesora/djangobible/main"><img src="https://results.pre-commit.ci/badge/github/avendesora/djangobible/main.svg"></a>
31
+ <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
32
+ </td>
33
+ </tr>
34
+ <tr>
35
+ <td>Supported Python/Django Versions</td>
36
+ <td>
37
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue?logo=python&logoColor=lightgray"></a><br />
38
+ <a href="https://www.djangoproject.com/download/"><img src="https://img.shields.io/badge/Django-4.2%20%7C%205.0%20%7C%205.1%20%7C%205.2-blue"></a><br />
39
+ </td>
40
+ </tr>
41
+ </table>
19
42
 
20
43
  ## Installation
21
44
 
@@ -46,30 +69,6 @@ There currently are no settings (other than INSTALLED_APPS) related to the djang
46
69
 
47
70
  Also, once support is implemented for multiple locales and languages, there could be related settings for that functionality.
48
71
 
49
- ### Optional Dependencies
50
-
51
- If the [defusedxml](https://github.com/tiran/defusedxml) library is installed, djangobible/pythonbible will use it to parse XML files rather than the builtin xml.etree library.
52
-
53
- To install djangobible with all optional dependencies, use the following command.
54
-
55
- ```shell script
56
- pip install djangobible[all]
57
- ```
58
-
59
- ### Python 3.6
60
-
61
- Python 3.6 is not officially supported (djangobible is only tested on Python 3.7+). However, djangobible should work on Python 3.6 if you have the dataclasses library installed:
62
-
63
- ```shell script
64
- pip install dataclasses
65
- ```
66
-
67
- If you are using Python 3.7+, the dataclasses library is included in the Python standard library, and you do not need to explicitly install the dataclasses library.
68
-
69
- ### Django versions
70
-
71
- The djangobible library is actively tested on Django 3.0 and 3.1, and support for Django 3.2 is planned. It may work on previous versions, but it has not been tested on other versions.
72
-
73
72
  ## Features
74
73
 
75
74
  The djangobible library is a complete wrapper for the [pythonbible](https://github.com/avendesora/pythonbible) library, so importing the djangobible library as:
@@ -1,5 +1,4 @@
1
- """
2
- djangobible python library.
1
+ """djangobible python library.
3
2
 
4
3
  djangobible lets you easily associate Django models with Bible Scripture references and
5
4
  search accordingly.
@@ -7,6 +6,6 @@ search accordingly.
7
6
 
8
7
  from __future__ import annotations
9
8
 
10
- __version__ = "0.0.25"
9
+ __version__ = "0.3.0"
11
10
 
12
11
  from pythonbible import *
@@ -2,7 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable
5
+ from typing import Any
6
+ from typing import Callable
6
7
 
7
8
  import pythonbible as bible
8
9
  from django import forms
@@ -24,7 +25,8 @@ class VerseField(models.Field):
24
25
  bible.get_references(value),
25
26
  )[0]
26
27
  elif isinstance(value, int) and not bible.is_valid_verse_id(value):
27
- raise ValidationError(f"{value} is not a valid verse id.")
28
+ error_message = f"{value} is not a valid verse id."
29
+ raise ValidationError(error_message)
28
30
 
29
31
  return super().get_prep_value(value)
30
32
 
@@ -56,8 +58,8 @@ class VerseField(models.Field):
56
58
 
57
59
  def formfield(
58
60
  self: VerseField,
59
- form_class: Any = None,
60
- choices_form_class: Any = None,
61
+ form_class: type[forms.Field] | None = None,
62
+ choices_form_class: type[forms.Field] | None = None,
61
63
  **kwargs: Any,
62
64
  ) -> forms.Field:
63
65
  """Make sure the form field is a CharField."""
@@ -70,7 +72,7 @@ class VerseField(models.Field):
70
72
 
71
73
  def get_db_prep_save(
72
74
  self: VerseField,
73
- value: Any,
75
+ value: int | str | None,
74
76
  **kwargs: Any,
75
77
  ) -> int | None:
76
78
  """Validate and convert the value to a verse id int before saving to the DB."""
@@ -79,17 +81,16 @@ class VerseField(models.Field):
79
81
 
80
82
  if isinstance(value, str):
81
83
  references = bible.get_references(value)
82
- verse_ids = bible.convert_references_to_verse_ids(references)
83
-
84
- if not verse_ids:
85
- raise ValidationError(
86
- f"{value} does not contain a valid Scripture reference.",
87
- )
88
84
 
89
- value = verse_ids[0]
85
+ if verse_ids := bible.convert_references_to_verse_ids(references):
86
+ value = verse_ids[0]
87
+ else:
88
+ error_message = f"{value} does not contain a valid Scripture reference."
89
+ raise ValidationError(error_message)
90
90
 
91
91
  if not bible.is_valid_verse_id(value):
92
- raise ValidationError(f"{value} is not a valid verse id.")
92
+ error_message = f"{value} is not a valid verse id."
93
+ raise ValidationError(error_message)
93
94
 
94
95
  return int(value)
95
96
 
@@ -7,7 +7,6 @@ from django.db import migrations, models
7
7
 
8
8
 
9
9
  class Migration(migrations.Migration):
10
-
11
10
  initial = True
12
11
 
13
12
  dependencies = [
@@ -2,10 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any
6
-
7
5
  import pythonbible as bible
8
- from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
6
+ from django.contrib.contenttypes.fields import GenericForeignKey
7
+ from django.contrib.contenttypes.fields import GenericRelation
9
8
  from django.contrib.contenttypes.models import ContentType
10
9
  from django.db import models
11
10
 
@@ -29,8 +28,8 @@ class VerseRelation(models.Model):
29
28
  self: VerseRelation,
30
29
  force_insert: bool = False,
31
30
  force_update: bool = False,
32
- using: Any = None,
33
- update_fields: Any = None,
31
+ using: str | None = None,
32
+ update_fields: list[str] | None = None,
34
33
  ) -> None:
35
34
  """Save the instance to the DB."""
36
35
  if not bible.is_valid_verse_id(self.verse):
@@ -45,7 +44,7 @@ class ScriptureIndexedModelManager(models.Manager):
45
44
  def filter_by_verse_ids(
46
45
  self: ScriptureIndexedModelManager,
47
46
  verse_ids: list[int] | None,
48
- ) -> Any:
47
+ ) -> models.QuerySet:
49
48
  """Return the Query Set for the objects related to the given verse ids."""
50
49
  content_type = ContentType.objects.get_for_model(self.model)
51
50
  verse_relations = VerseRelation.objects.filter(
@@ -13,8 +13,7 @@ register = template.Library()
13
13
 
14
14
  @register.simple_tag
15
15
  def verse_reference(verse_id: int, **kwargs: Any) -> str:
16
- """
17
- For a given verse id return the formatted scripture reference string.
16
+ """For a given verse id return the formatted scripture reference string.
18
17
 
19
18
  :param verse_id:
20
19
  :return: the scripture reference string for the given verse id
@@ -24,10 +23,8 @@ def verse_reference(verse_id: int, **kwargs: Any) -> str:
24
23
  verse: int
25
24
  book, chapter, verse = bible.get_book_chapter_verse(verse_id)
26
25
 
27
- version_id: str | None = kwargs.get("version")
28
-
29
- if version_id:
30
- kwargs["version"] = _get_version(version_id)
26
+ if version_id := kwargs.get("version"):
27
+ kwargs["version"] = _get_version(version_id) # type: ignore[arg-type,assignment]
31
28
 
32
29
  reference = bible.NormalizedReference(book, chapter, verse, chapter, verse)
33
30
 
@@ -36,19 +33,18 @@ def verse_reference(verse_id: int, **kwargs: Any) -> str:
36
33
 
37
34
  @register.simple_tag
38
35
  def verse_text(verse_id: int, **kwargs: Any) -> str:
39
- """
40
- For a given verse id and version, return the verse text string.
36
+ """For a given verse id and version, return the verse text string.
41
37
 
42
38
  :param verse_id:
43
39
  :return: the verse text for the given verse id and version
44
40
  """
45
- version_id: str | None = kwargs.get("version")
41
+ version_id: str | None = kwargs.get("version") # type: ignore[assignment]
46
42
  text: str = (
47
43
  bible.get_verse_text(verse_id, _get_version(version_id))
48
44
  if version_id
49
45
  else bible.get_verse_text(verse_id)
50
46
  )
51
- include_verse_numbers: bool = kwargs.get("include_verse_numbers", False)
47
+ include_verse_numbers: bool = kwargs.get("include_verse_numbers", False) # type: ignore[assignment]
52
48
 
53
49
  return (
54
50
  f"{bible.get_verse_number(verse_id)}. {text}" if include_verse_numbers else text
@@ -3,11 +3,9 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from django.core.exceptions import ValidationError
6
- from pythonbible import (
7
- NormalizedReference,
8
- convert_references_to_verse_ids,
9
- get_references,
10
- )
6
+ from pythonbible import NormalizedReference
7
+ from pythonbible import convert_references_to_verse_ids
8
+ from pythonbible import get_references
11
9
 
12
10
 
13
11
  def validate_verse(verse_value: str | None) -> None:
@@ -18,12 +16,15 @@ def validate_verse(verse_value: str | None) -> None:
18
16
  references: list[NormalizedReference] = get_references(verse_value)
19
17
 
20
18
  if not references:
21
- raise ValidationError("Not a valid reference.")
19
+ error_message = "Not a valid reference."
20
+ raise ValidationError(error_message)
22
21
 
23
22
  if len(references) > 1:
24
- raise ValidationError("Only single verse references allowed.")
23
+ error_message = "Only single verse references allowed."
24
+ raise ValidationError(error_message)
25
25
 
26
26
  verse_ids: list[int] = convert_references_to_verse_ids(references)
27
27
 
28
28
  if len(verse_ids) > 1:
29
- raise ValidationError("Only single verse references allowed.")
29
+ error_message = "Only single verse references allowed."
30
+ raise ValidationError(error_message)