django-pfx 1.2.dev105__tar.gz → 1.2.dev110__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.
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/.gitlab-ci.yml +37 -1
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/PKG-INFO +6 -8
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/README.md +1 -4
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/django_pfx.egg-info/PKG-INFO +6 -8
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/django_pfx.egg-info/requires.txt +1 -1
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/index.rst +1 -7
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/decorator.md +18 -6
- django-pfx-1.2.dev110/doc/source/getting_started.md +179 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/internationalisation.md +1 -1
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/model.md +21 -13
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/pfx_views.md +49 -21
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/testing.md +40 -13
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/authentication_views.py +3 -1
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/setup.cfg +5 -4
- django-pfx-1.2.dev105/doc/source/getting_started.md +0 -81
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/.gitignore +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/.pre-commit-config.yaml +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/LICENSE +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/MANIFEST.in +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/django_pfx.egg-info/SOURCES.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/django_pfx.egg-info/dependency_links.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/django_pfx.egg-info/top_level.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/Makefile +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/conf.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/api.views.rst +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/authentication.md +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/doc/source/cookbook.md +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/img/pfx.png +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/img/pfx.svg +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/apidoc/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/apidoc/parameters.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/apidoc/schema.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/apidoc/tags.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/apps.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/decorator/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/decorator/rest.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/default_settings.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/exceptions.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/http/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/http/json_response.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/management/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/management/commands/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/middleware/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/middleware/authentication.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/middleware/locale.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/models/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/models/cache_mixins.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/models/not_null_fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/models/pfx_models.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/serializers/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/serializers/json.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/settings.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/shortcuts.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/storage/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/storage/s3_storage.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/test.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/urls.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/filters_views.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/locale_views.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/date_format.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/groups.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/list_count.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/list_items.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/list_order.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/list_search.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pfx/pfxcore/views/rest_views.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/pyproject.toml +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/requirements.txt +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/runtest.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/setup.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/models.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/ci.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/common.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/dev.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/dev_custom_example.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/settings/dev_default.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/__init__.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/basic_api_errors.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/basic_api_test.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_api_doc.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_auth_api.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_cache.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_filters.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_locale_api.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_perm_tests.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_perms_api.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_shortcuts.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_timezone_middleware.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_tools.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_user_queryset.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_view_decorators.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/tests/test_view_fields.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/urls.py +0 -0
- {django-pfx-1.2.dev105 → django-pfx-1.2.dev110}/tests/views.py +0 -0
|
@@ -8,7 +8,7 @@ variables:
|
|
|
8
8
|
|
|
9
9
|
cache:
|
|
10
10
|
paths:
|
|
11
|
-
-
|
|
11
|
+
- .cache/pip/
|
|
12
12
|
|
|
13
13
|
before_script:
|
|
14
14
|
- python -V # Print out python version for debugging
|
|
@@ -20,6 +20,7 @@ before_script:
|
|
|
20
20
|
|
|
21
21
|
stages:
|
|
22
22
|
- test
|
|
23
|
+
- build
|
|
23
24
|
- package
|
|
24
25
|
|
|
25
26
|
test:
|
|
@@ -34,9 +35,13 @@ test:
|
|
|
34
35
|
- coverage run --source='.' runtest.py
|
|
35
36
|
- coverage report
|
|
36
37
|
- coverage xml
|
|
38
|
+
- coverage html
|
|
37
39
|
coverage: '/TOTAL.*\s([.\d]+)%/'
|
|
38
40
|
artifacts:
|
|
39
41
|
when: always
|
|
42
|
+
paths:
|
|
43
|
+
- htmlcov/**
|
|
44
|
+
expire_in: 7 day
|
|
40
45
|
reports:
|
|
41
46
|
junit: testreport.xml
|
|
42
47
|
coverage_report:
|
|
@@ -48,6 +53,37 @@ test:
|
|
|
48
53
|
- DJANGO_VERSION: 'Django>=3.2,<4.0'
|
|
49
54
|
- DJANGO_VERSION: 'Django>=4.0,<5.0'
|
|
50
55
|
- DJANGO_VERSION: 'Django>=4.2.*' # LTS
|
|
56
|
+
|
|
57
|
+
build doc:
|
|
58
|
+
stage: build
|
|
59
|
+
needs: []
|
|
60
|
+
interruptible: true
|
|
61
|
+
script:
|
|
62
|
+
- cd doc
|
|
63
|
+
- make html
|
|
64
|
+
artifacts:
|
|
65
|
+
when: always
|
|
66
|
+
paths:
|
|
67
|
+
- doc/_build/**
|
|
68
|
+
expire_in: 7 day
|
|
69
|
+
|
|
70
|
+
pages:
|
|
71
|
+
stage: package
|
|
72
|
+
needs:
|
|
73
|
+
- job: build doc
|
|
74
|
+
artifacts: true
|
|
75
|
+
- job: test
|
|
76
|
+
artifacts: true
|
|
77
|
+
script:
|
|
78
|
+
- mkdir public
|
|
79
|
+
- mv doc/_build/html public/doc
|
|
80
|
+
- mv htmlcov public/coverage
|
|
81
|
+
artifacts:
|
|
82
|
+
paths:
|
|
83
|
+
- public
|
|
84
|
+
only:
|
|
85
|
+
- master
|
|
86
|
+
|
|
51
87
|
package:
|
|
52
88
|
only:
|
|
53
89
|
refs:
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: Django PFX is a toolkit to build
|
|
3
|
+
Version: 1.2.dev110
|
|
4
|
+
Summary: Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
7
7
|
License: BSD-3-Clause
|
|
8
|
-
Project-URL: Source, https://gitlab.com/
|
|
9
|
-
Project-URL: Tracker, https://gitlab.com/
|
|
8
|
+
Project-URL: Source, https://gitlab.com/pfx4/django-pfx
|
|
9
|
+
Project-URL: Tracker, https://gitlab.com/pfx4/django-pfx/-/issues
|
|
10
|
+
Project-URL: Documentation, https://pfx4.gitlab.io/django-pfx/doc/
|
|
10
11
|
Classifier: Environment :: Web Environment
|
|
11
12
|
Classifier: Framework :: Django
|
|
12
13
|
Classifier: Framework :: Django :: 3.2
|
|
@@ -31,11 +32,8 @@ License-File: LICENSE
|
|
|
31
32
|
|
|
32
33
|
![logo]
|
|
33
34
|
|
|
34
|
-
Django PFX is a toolkit to build
|
|
35
|
+
Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
35
36
|
|
|
36
|
-
> **WARNING**
|
|
37
|
-
>
|
|
38
|
-
> This is an experimental projet. It should not be used in real project because it is incomplete and there is no warranty of keeping compatibility in future version.
|
|
39
37
|
|
|
40
38
|
[logo]: https://gitlab.com/hmartinet/django-pfx/-/raw/master/img/pfx.png "PFX"
|
|
41
39
|
[pipeline]: https://gitlab.com/hmartinet/django-pfx/badges/master/pipeline.svg "Pipeline Status"
|
|
@@ -5,11 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
![logo]
|
|
7
7
|
|
|
8
|
-
Django PFX is a toolkit to build
|
|
8
|
+
Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
9
9
|
|
|
10
|
-
> **WARNING**
|
|
11
|
-
>
|
|
12
|
-
> This is an experimental projet. It should not be used in real project because it is incomplete and there is no warranty of keeping compatibility in future version.
|
|
13
10
|
|
|
14
11
|
[logo]: https://gitlab.com/hmartinet/django-pfx/-/raw/master/img/pfx.png "PFX"
|
|
15
12
|
[pipeline]: https://gitlab.com/hmartinet/django-pfx/badges/master/pipeline.svg "Pipeline Status"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-pfx
|
|
3
|
-
Version: 1.2.
|
|
4
|
-
Summary: Django PFX is a toolkit to build
|
|
3
|
+
Version: 1.2.dev110
|
|
4
|
+
Summary: Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
5
5
|
Author: Hervé Martinet
|
|
6
6
|
Author-email: herve.martinet@gmail.com
|
|
7
7
|
License: BSD-3-Clause
|
|
8
|
-
Project-URL: Source, https://gitlab.com/
|
|
9
|
-
Project-URL: Tracker, https://gitlab.com/
|
|
8
|
+
Project-URL: Source, https://gitlab.com/pfx4/django-pfx
|
|
9
|
+
Project-URL: Tracker, https://gitlab.com/pfx4/django-pfx/-/issues
|
|
10
|
+
Project-URL: Documentation, https://pfx4.gitlab.io/django-pfx/doc/
|
|
10
11
|
Classifier: Environment :: Web Environment
|
|
11
12
|
Classifier: Framework :: Django
|
|
12
13
|
Classifier: Framework :: Django :: 3.2
|
|
@@ -31,11 +32,8 @@ License-File: LICENSE
|
|
|
31
32
|
|
|
32
33
|
![logo]
|
|
33
34
|
|
|
34
|
-
Django PFX is a toolkit to build
|
|
35
|
+
Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
35
36
|
|
|
36
|
-
> **WARNING**
|
|
37
|
-
>
|
|
38
|
-
> This is an experimental projet. It should not be used in real project because it is incomplete and there is no warranty of keeping compatibility in future version.
|
|
39
37
|
|
|
40
38
|
[logo]: https://gitlab.com/hmartinet/django-pfx/-/raw/master/img/pfx.png "PFX"
|
|
41
39
|
[pipeline]: https://gitlab.com/hmartinet/django-pfx/badges/master/pipeline.svg "Pipeline Status"
|
|
@@ -6,13 +6,7 @@
|
|
|
6
6
|
Welcome to Django PFX's documentation!
|
|
7
7
|
======================================
|
|
8
8
|
|
|
9
|
-
Django PFX is a toolkit to build
|
|
10
|
-
to be used by React progressive web app.
|
|
11
|
-
|
|
12
|
-
.. warning::
|
|
13
|
-
This is a project in development.
|
|
14
|
-
It should not be used in real project because it is incomplete
|
|
15
|
-
and changes may break the compatibility in future version.
|
|
9
|
+
Django PFX is a toolkit to build rest APIs with the Django framework.
|
|
16
10
|
|
|
17
11
|
|
|
18
12
|
Topics
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# View decorator and URL
|
|
2
2
|
## @rest_view
|
|
3
3
|
Used to provide the base path of a view class
|
|
4
|
-
```
|
|
4
|
+
```python
|
|
5
|
+
from pfx.pfxcore.decorator import rest_view
|
|
6
|
+
|
|
5
7
|
@rest_view("/base-path")
|
|
6
8
|
class ViewClass():
|
|
7
9
|
```
|
|
@@ -9,13 +11,18 @@ class ViewClass():
|
|
|
9
11
|
## @rest_api
|
|
10
12
|
Used to annotate the rest services method.
|
|
11
13
|
Parameters are the path and the HTTP method.
|
|
12
|
-
```
|
|
14
|
+
```python
|
|
15
|
+
from pfx.pfxcore.decorator import rest_api
|
|
16
|
+
|
|
13
17
|
@rest_api("/path", method="get")
|
|
14
18
|
def class_method(self):
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
A short example
|
|
18
|
-
```
|
|
22
|
+
```python
|
|
23
|
+
from pfx.pfxcore.decorator import rest_view, rest_api
|
|
24
|
+
from pfx.pfxcore.http import JsonResponse
|
|
25
|
+
|
|
19
26
|
@rest_view("/books")
|
|
20
27
|
class BookRestView():
|
|
21
28
|
|
|
@@ -27,7 +34,9 @@ class BookRestView():
|
|
|
27
34
|
|
|
28
35
|
### path parameters
|
|
29
36
|
Path can contain parameters that are passed to the method.
|
|
30
|
-
```
|
|
37
|
+
```python
|
|
38
|
+
from pfx.pfxcore.decorator import rest_api
|
|
39
|
+
|
|
31
40
|
@rest_api("/path/<int:pk>/test/<slug:slug>", method="get")
|
|
32
41
|
def class_method(self, pk, slug):
|
|
33
42
|
```
|
|
@@ -35,7 +44,8 @@ def class_method(self, pk, slug):
|
|
|
35
44
|
## Registering urls
|
|
36
45
|
To be available, annotated view class must be registered
|
|
37
46
|
in your urls.py file as follows.
|
|
38
|
-
|
|
47
|
+
|
|
48
|
+
```python
|
|
39
49
|
from pfx.pfxcore import register_views
|
|
40
50
|
|
|
41
51
|
from . import views
|
|
@@ -44,9 +54,11 @@ urlpatterns = register_views(
|
|
|
44
54
|
views.AuthorRestView,
|
|
45
55
|
views.BookRestView)
|
|
46
56
|
```
|
|
57
|
+
|
|
47
58
|
You can include multiple views under one path, or add a path
|
|
48
59
|
wih a specific class method for each HTTP methods:
|
|
49
|
-
```
|
|
60
|
+
```python
|
|
61
|
+
from django.urls import include, path
|
|
50
62
|
from pfx.pfxcore import register_views
|
|
51
63
|
|
|
52
64
|
from . import views
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# Getting Started with PFX
|
|
2
|
+
|
|
3
|
+
## Install django pfx
|
|
4
|
+
|
|
5
|
+
Using pip
|
|
6
|
+
```bash
|
|
7
|
+
pip install django-pfx
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Configuration
|
|
11
|
+
|
|
12
|
+
Add pfxcore to the installed app
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
INSTALLED_APPS = [
|
|
16
|
+
'pfx.pfxcore',
|
|
17
|
+
]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Create your services
|
|
21
|
+
|
|
22
|
+
### Model class
|
|
23
|
+
Create a simple model class.
|
|
24
|
+
```python
|
|
25
|
+
from django.db import models
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Book(models.Model):
|
|
29
|
+
BOOK_TYPES = [
|
|
30
|
+
('science_fiction', 'Science Fiction'),
|
|
31
|
+
('heroic_fantasy', 'Heroic Fantasy'),
|
|
32
|
+
('detective', 'Detective')]
|
|
33
|
+
|
|
34
|
+
title = models.CharField("Title", max_length=30)
|
|
35
|
+
author = models.CharField("Author", max_length=150)
|
|
36
|
+
type = models.CharField("Type", max_length=20, choices=BOOK_TYPES)
|
|
37
|
+
pub_date = models.DateField("Pub Date")
|
|
38
|
+
created_at = models.DateField("Created at", auto_now_add=True)
|
|
39
|
+
|
|
40
|
+
class Meta:
|
|
41
|
+
verbose_name = "Book"
|
|
42
|
+
verbose_name_plural = "Books"
|
|
43
|
+
|
|
44
|
+
def __str__(self):
|
|
45
|
+
return f"{self.name}"
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Views
|
|
50
|
+
Create a new view
|
|
51
|
+
```python
|
|
52
|
+
from pfx.pfxcore.decorator import rest_view
|
|
53
|
+
from pfx.pfxcore.views import RestView
|
|
54
|
+
|
|
55
|
+
from book.models import Book
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@rest_view("/books")
|
|
59
|
+
class BookRestView(RestView):
|
|
60
|
+
default_public = True
|
|
61
|
+
queryset = Book.objects
|
|
62
|
+
fields = ['title', 'author', 'type', 'pub_date', 'created_at']
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### URLs
|
|
66
|
+
Register the url in urls.py.
|
|
67
|
+
```python
|
|
68
|
+
from django.urls import path, include
|
|
69
|
+
from pfx.pfxcore import register_views
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
from book import views
|
|
73
|
+
|
|
74
|
+
apipatterns = register_views(views.BookRestView)
|
|
75
|
+
|
|
76
|
+
urlpatterns = [
|
|
77
|
+
path('api/', include(apipatterns)),
|
|
78
|
+
]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You now have a fully functional public API for the book objet.
|
|
82
|
+
|
|
83
|
+
### Test the API
|
|
84
|
+
The next step is to create a test class to test your new API.
|
|
85
|
+
PFX provides [some tools](testing.md) to ease the testing.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from datetime import date
|
|
89
|
+
from django.test import TransactionTestCase
|
|
90
|
+
from pfx.pfxcore.test import TestAssertMixin, APIClient
|
|
91
|
+
|
|
92
|
+
from book.models import Book, Author
|
|
93
|
+
|
|
94
|
+
class BookTestClass(TestAssertMixin, TransactionTestCase):
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def setUpTestData(cls):
|
|
98
|
+
# create some test data
|
|
99
|
+
cls.author = Author.objects.create(
|
|
100
|
+
first_name='Isaac',
|
|
101
|
+
last_name='Asimov')
|
|
102
|
+
cls.book1 = Book.objects.create(
|
|
103
|
+
author=cls.author,
|
|
104
|
+
title="The Caves of Steel",
|
|
105
|
+
type='science_fiction',
|
|
106
|
+
pub_date=date(1954, 1, 1))
|
|
107
|
+
cls.book2 = Book.objects.create(
|
|
108
|
+
author=cls.author,
|
|
109
|
+
title="The Naked Sun",
|
|
110
|
+
type='science_fiction',
|
|
111
|
+
pub_date=date(1957, 1, 1))
|
|
112
|
+
|
|
113
|
+
def test_get_book_list(self):
|
|
114
|
+
client = APIClient()
|
|
115
|
+
response = client.get('/api/books')
|
|
116
|
+
|
|
117
|
+
# assert response status is 200 OK
|
|
118
|
+
self.assertRC(response, 200)
|
|
119
|
+
# assert number of item returned
|
|
120
|
+
self.assertSize(response, 'items', 2)
|
|
121
|
+
# test the author of the second item is Asimov
|
|
122
|
+
self.assertJE(response, 'items.@1.author.pk', self.author.pk)
|
|
123
|
+
|
|
124
|
+
def test_get_book(self):
|
|
125
|
+
client = APIClient()
|
|
126
|
+
response = client.get(f'/api/books/{self.book2.pk}')
|
|
127
|
+
|
|
128
|
+
# assert response status is 200 OK
|
|
129
|
+
self.assertRC(response, 200)
|
|
130
|
+
# assert json content of the response
|
|
131
|
+
self.assertJE(response, 'title', "The Naked Sun")
|
|
132
|
+
self.assertJE(response, 'pub_date', "1957-01-01")
|
|
133
|
+
|
|
134
|
+
def test_create_book(self):
|
|
135
|
+
client = APIClient()
|
|
136
|
+
response = client.post(
|
|
137
|
+
'/api/books/',dict(
|
|
138
|
+
title="The Robots of Dawn",
|
|
139
|
+
author=self.author,
|
|
140
|
+
type='science_fiction',
|
|
141
|
+
pub_date=date(1983, 1, 1)
|
|
142
|
+
))
|
|
143
|
+
self.assertRC(response, 200)
|
|
144
|
+
self.assertJE(response, 'title', "The Robots of Dawn")
|
|
145
|
+
|
|
146
|
+
def test_create_book_validation(self):
|
|
147
|
+
client = APIClient()
|
|
148
|
+
# make a post request
|
|
149
|
+
response = client.post(
|
|
150
|
+
'/api/books/',dict(
|
|
151
|
+
title=None,
|
|
152
|
+
author=self.author,
|
|
153
|
+
type='science_fiction',
|
|
154
|
+
pub_date=date(1983, 1, 1)
|
|
155
|
+
))
|
|
156
|
+
self.assertRC(response, 422)
|
|
157
|
+
self.assertJE(
|
|
158
|
+
response, 'title.@0', "This field cannot be null.")
|
|
159
|
+
|
|
160
|
+
def test_update_book(self):
|
|
161
|
+
client = APIClient()
|
|
162
|
+
response = client.put(
|
|
163
|
+
f'/api/books/{self.book2.pk}',dict(
|
|
164
|
+
title="The Robots of Dawn",
|
|
165
|
+
pub_date=date(1983, 1, 1),
|
|
166
|
+
))
|
|
167
|
+
self.assertRC(response, 200)
|
|
168
|
+
self.assertJE(response, 'title', "The Robots of Dawn")
|
|
169
|
+
|
|
170
|
+
def test_delete_book(self):
|
|
171
|
+
client = APIClient()
|
|
172
|
+
response = client.delete(
|
|
173
|
+
f'/api/books/{self.book2.pk}')
|
|
174
|
+
self.assertRC(response, 200)
|
|
175
|
+
|
|
176
|
+
books = Book.objects.filter(pk=self.book2.pk)
|
|
177
|
+
self.assertEqual(books.count(), 0)
|
|
178
|
+
|
|
179
|
+
```
|
|
@@ -12,7 +12,7 @@ In Django, `USE_I18N` must be `True` to use internationalization. Use `LANGUAGE_
|
|
|
12
12
|
You can optionally set `USE_L10N` to `True` (see Django documentation).
|
|
13
13
|
|
|
14
14
|
In Addition, you can set the list of available languages for web services with `LANGUAGES`:
|
|
15
|
-
```
|
|
15
|
+
```python
|
|
16
16
|
LANGUAGES = [
|
|
17
17
|
('fr', "French"),
|
|
18
18
|
('en', "English"),
|
|
@@ -5,15 +5,19 @@ Django PFX use plain Django Models classes.
|
|
|
5
5
|
This library only provides some helpers for properties
|
|
6
6
|
and foreign keys representations.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## @rest_property
|
|
9
9
|
If you want to use properties in your model,
|
|
10
|
-
you have to annotate them with
|
|
10
|
+
you have to annotate them with `@rest_property`.
|
|
11
11
|
|
|
12
12
|
Rest property takes 2 parameters, a name and
|
|
13
13
|
the type of the Field (CharField, IntegerField, etc.)
|
|
14
14
|
|
|
15
15
|
Rest properties can be listed as fields to be returned in list and detail views.
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from django.db import models
|
|
19
|
+
from pfx.pfxcore.decorator import rest_property
|
|
20
|
+
|
|
17
21
|
class Book(models.Model):
|
|
18
22
|
name = models.CharField("Name", max_length=30)
|
|
19
23
|
author = models.ForeignKey(
|
|
@@ -35,12 +39,11 @@ class Book(models.Model):
|
|
|
35
39
|
```
|
|
36
40
|
|
|
37
41
|
## JSONReprMixin
|
|
38
|
-
|
|
39
|
-
Foreign keys are returned by {doc}`Django PFX views <pfx_views>` as a JSON
|
|
42
|
+
Foreign keys are returned by [Django PFX views <pfx_views>](./pfx_views.md) as a JSON
|
|
40
43
|
structure with two fields : pk, resource_name
|
|
41
44
|
|
|
42
45
|
For instance for the book class, with the author foreign key :
|
|
43
|
-
```
|
|
46
|
+
```python
|
|
44
47
|
{
|
|
45
48
|
"author": {
|
|
46
49
|
"pk": 1,
|
|
@@ -60,8 +63,11 @@ by inheriting JSONReprMixin on the Model class and
|
|
|
60
63
|
by overriding the json_repr method.
|
|
61
64
|
|
|
62
65
|
For instance for the Author class :
|
|
63
|
-
```
|
|
64
|
-
|
|
66
|
+
```python
|
|
67
|
+
from django.db import models
|
|
68
|
+
from pfx.pfxcore.models import JSONReprMixin
|
|
69
|
+
|
|
70
|
+
class Author(JSONReprMixin, models.Model):
|
|
65
71
|
first_name = models.CharField("First Name", max_length=30)
|
|
66
72
|
last_name = models.CharField("Last Name", max_length=30)
|
|
67
73
|
slug = models.SlugField("Slug", unique=True)
|
|
@@ -80,11 +86,11 @@ class Author(models.Model):
|
|
|
80
86
|
```
|
|
81
87
|
|
|
82
88
|
Which give the following result on the book service :
|
|
83
|
-
```
|
|
89
|
+
```python
|
|
84
90
|
{
|
|
85
91
|
"author": {
|
|
86
92
|
"pk": 1,
|
|
87
|
-
"resource_name": "John Ronald Reuel Tolkien"
|
|
93
|
+
"resource_name": "John Ronald Reuel Tolkien",
|
|
88
94
|
"resource_slug": "john-ronald-reuel-tolkien"
|
|
89
95
|
},
|
|
90
96
|
"created_at": "2022-01-14",
|
|
@@ -104,9 +110,11 @@ converting `null` values to empty strings, you can use the following model field
|
|
|
104
110
|
* `NotNullCharField`
|
|
105
111
|
* `NotNullTextField`
|
|
106
112
|
* `NotNullURLField`
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
|
|
113
|
+
```python
|
|
114
|
+
from pfx.pfxcore.models import NotNullCharField
|
|
115
|
+
|
|
116
|
+
a_string_field = NotNullCharField(
|
|
117
|
+
"A string", max_length=255, blank=True, default="")
|
|
110
118
|
```
|
|
111
119
|
|
|
112
120
|
The `null` parameter of these fields is automatically set to `False`.
|