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.
- djangobible-0.3.0/PKG-INFO +270 -0
- {djangobible-0.0.25 → djangobible-0.3.0}/README.md +37 -38
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/__init__.py +2 -3
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/fields.py +14 -13
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/migrations/0001_initial.py +0 -1
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/models.py +5 -6
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/templatetags/verse_tags.py +6 -10
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/validators.py +9 -8
- djangobible-0.3.0/pyproject.toml +132 -0
- djangobible-0.0.25/.coveragerc +0 -5
- djangobible-0.0.25/.github/workflows/codeql-analysis.yml +0 -62
- djangobible-0.0.25/.github/workflows/django.yml +0 -41
- djangobible-0.0.25/.gitignore +0 -134
- djangobible-0.0.25/.pre-commit-config.yaml +0 -48
- djangobible-0.0.25/.sourcery.yaml +0 -2
- djangobible-0.0.25/CODE_OF_CONDUCT.md +0 -76
- djangobible-0.0.25/CONTRIBUTING.md +0 -30
- djangobible-0.0.25/LICENSE +0 -21
- djangobible-0.0.25/PKG-INFO +0 -7
- djangobible-0.0.25/manage.py +0 -24
- djangobible-0.0.25/pyproject.toml +0 -35
- djangobible-0.0.25/requirements-dev.txt +0 -1
- djangobible-0.0.25/requirements-test.txt +0 -3
- djangobible-0.0.25/requirements.txt +0 -2
- djangobible-0.0.25/setup.cfg +0 -49
- djangobible-0.0.25/setup.py +0 -31
- djangobible-0.0.25/test_django_app/__init__.py +0 -0
- djangobible-0.0.25/test_django_app/admin.py +0 -10
- djangobible-0.0.25/test_django_app/apps.py +0 -11
- djangobible-0.0.25/test_django_app/migrations/0001_initial.py +0 -33
- djangobible-0.0.25/test_django_app/migrations/0002_testsingleverseobject.py +0 -33
- djangobible-0.0.25/test_django_app/migrations/0003_alter_testsingleverseobject_verse.py +0 -22
- djangobible-0.0.25/test_django_app/migrations/__init__.py +0 -0
- djangobible-0.0.25/test_django_app/models.py +0 -29
- djangobible-0.0.25/test_django_app/templates/verse_tags.html +0 -19
- djangobible-0.0.25/test_django_app/tests/__init__.py +0 -0
- djangobible-0.0.25/test_django_app/tests/factories.py +0 -42
- djangobible-0.0.25/test_django_app/tests/test_admin.py +0 -77
- djangobible-0.0.25/test_django_app/tests/test_models.py +0 -292
- djangobible-0.0.25/test_django_app/tests/test_search.py +0 -56
- djangobible-0.0.25/test_django_app/tests/test_tags.py +0 -123
- djangobible-0.0.25/test_django_app/tests/test_tags_functional.py +0 -45
- djangobible-0.0.25/test_django_app/tests/test_validators.py +0 -29
- djangobible-0.0.25/test_django_app/views.py +0 -16
- djangobible-0.0.25/test_django_project/__init__.py +0 -0
- djangobible-0.0.25/test_django_project/asgi.py +0 -18
- djangobible-0.0.25/test_django_project/settings.py +0 -123
- djangobible-0.0.25/test_django_project/urls.py +0 -11
- djangobible-0.0.25/test_django_project/wsgi.py +0 -18
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/apps.py +0 -0
- {djangobible-0.0.25 → djangobible-0.3.0}/djangobible/migrations/__init__.py +0 -0
- {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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
60
|
-
choices_form_class:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -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
|
|
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:
|
|
33
|
-
update_fields:
|
|
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
|
-
) ->
|
|
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
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
|
|
19
|
+
error_message = "Not a valid reference."
|
|
20
|
+
raise ValidationError(error_message)
|
|
22
21
|
|
|
23
22
|
if len(references) > 1:
|
|
24
|
-
|
|
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
|
-
|
|
29
|
+
error_message = "Only single verse references allowed."
|
|
30
|
+
raise ValidationError(error_message)
|