django-basic-form-builder 0.1.2__py3-none-any.whl

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.
@@ -0,0 +1,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-basic-form-builder
3
+ Version: 0.1.2
4
+ Summary: Reusable Django app for building JSON-driven forms via the admin
5
+ Author-email: Göktürk Burak Köse <02macaw.others@icloud.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/gokturkbrk/django-basic-form-builder
8
+ Project-URL: Documentation, https://github.com/gokturkbrk/django-basic-form-builder
9
+ Project-URL: Source, https://github.com/gokturkbrk/django-basic-form-builder
10
+ Project-URL: Tracker, https://github.com/gokturkbrk/django-basic-form-builder/issues
11
+ Keywords: django,forms,builder,json,admin,schema
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Framework :: Django
15
+ Classifier: Framework :: Django :: 5.1
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Internet :: WWW/HTTP
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
25
+ Requires-Python: >=3.12
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: django<5.2,>=5.1
29
+ Requires-Dist: djangorestframework>=3.15.0
30
+ Requires-Dist: drf-spectacular>=0.29.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
33
+ Requires-Dist: pytest-django>=4.8.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.5.0; extra == "dev"
36
+ Requires-Dist: mypy>=1.11.0; extra == "dev"
37
+ Provides-Extra: postgres
38
+ Requires-Dist: psycopg[binary]>=3.2.0; extra == "postgres"
39
+ Provides-Extra: html
40
+ Requires-Dist: nh3>=0.3.2; extra == "html"
41
+ Dynamic: license-file
42
+
43
+ # django-formbuilder
44
+
45
+ Reusable Django app that lets admins define JSON-rendered forms directly in the Django admin, then expose them via a read-only API endpoint. Works with Django 5.1+, DRF 3.15+, and the dependency stack listed in `pyproject.toml`.
46
+
47
+ ## Installation
48
+
49
+ 1. Install with [uv](https://github.com/astral-sh/uv) (preferred) or pip:
50
+
51
+ ```bash
52
+ uv pip install django-formbuilder
53
+ ```
54
+
55
+ Optional extras:
56
+
57
+ - PostgreSQL support: `uv pip install "django-formbuilder[postgres]"`
58
+ - HTML sanitization utilities (if you integrate them yourself): `uv pip install "django-formbuilder[html]"`
59
+
60
+ 2. Add `formbuilder` (and `rest_framework` if not already present) to `INSTALLED_APPS`.
61
+ 3. Explicitly enable the read-only API endpoint (it is off by default to avoid exposing form data unintentionally):
62
+
63
+ ```python
64
+ FORMBUILDER_API_ENABLED = True
65
+ ```
66
+
67
+ 4. Include the API URLs in your project routes:
68
+
69
+ ```python
70
+ from django.urls import include, path
71
+
72
+ urlpatterns = [
73
+ path('api/forms/', include('formbuilder.api.urls')),
74
+ ]
75
+ ```
76
+
77
+ 5. Run migrations (`python manage.py migrate`).
78
+
79
+ ## Admin Usage
80
+
81
+ - Create a **Custom Form** entry in admin (name, slug, description, status).
82
+ - Add **Form Fields** using the stacked inline editor; supported types are `text`, `number`, `textarea`, `dropdown`, `radio`, `checkbox`, `rating`, `boolean`, `email`, `date`.
83
+ - For each field:
84
+ - **Label**: Short technical identifier (e.g., "Email", "Full Name") - used internally and in compact UIs
85
+ - **Question**: Detailed question or explanation for users (e.g., "What is your email address? We'll use this to send you updates.")
86
+ - For feedback forms, this is the primary text users see
87
+ - Can be left blank if the label is self-explanatory
88
+ - **Slug**: Technical field identifier (auto-generated from label)
89
+ - Configure shared attributes (required, placeholder, default value, help text)
90
+ - For dropdown, radio, and checkbox fields:
91
+ - After saving the form, click "Save and continue editing"
92
+ - Click on a field to edit it individually
93
+ - Use the "Field options" inline editor at the bottom to add options
94
+ - For text/number/rating fields:
95
+ - Expand the relevant configuration section (Text/Number/Rating Configuration)
96
+ - Use the dedicated config fields (min/max length, min/max value, rating scale)
97
+ - These fields are type-specific and only apply to their respective field types
98
+ - Or use the advanced JSON config section for power users
99
+ - **Position auto-update**: When you add or remove fields, positions are automatically renumbered (1, 2, 3, etc.)
100
+ - **Visual separation**: Each form field is shown in a separate bordered box for clarity
101
+ - On every save, the app regenerates a JSON snapshot stored on `CustomForm.json_schema`.
102
+ - Use the "Preview JSON" link to inspect the generated schema in a new tab.
103
+ - Running on Python 3.14? A compatibility shim automatically patches Django's template context copy routine.
104
+
105
+ ### Label vs Question - When to Use Which?
106
+
107
+ **Label** (required):
108
+
109
+ - Short, concise identifier: "Email", "Phone", "Rating"
110
+ - Used in compact form layouts, tables, and admin interfaces
111
+ - Technical reference for developers
112
+ - Appears in form labels and summaries
113
+
114
+ **Question** (optional but recommended for feedback forms):
115
+
116
+ - Full question or detailed explanation: "How satisfied are you with our service?"
117
+ - Primary text shown to users in feedback/survey forms
118
+ - Can include context, examples, or instructions
119
+ - Better user experience for participation forms
120
+
121
+ **Example:**
122
+
123
+ ```text
124
+ Label: "Service Quality"
125
+ Question: "On a scale of 1-5 stars, how would you rate the quality of service you received today?"
126
+
127
+ Label: "Email"
128
+ Question: "What email address should we use to send you updates about your inquiry?"
129
+ ```
130
+
131
+ ### Quick Start Guide
132
+
133
+ 1. **Create a form in Django admin:**
134
+ - Navigate to `/admin/formbuilder/customform/add/`
135
+ - Fill in: Name = "Contact Us", Slug = "contact-us", Status = "published"
136
+ - Click "Add another Form field" in the inline section:
137
+ - Label = "Full Name"
138
+ - Slug = "full_name"
139
+ - Question = "What is your full name?"
140
+ - Type = "text"
141
+ - Required = ✓
142
+ - Add another field:
143
+ - Label = "Department"
144
+ - Slug = "department"
145
+ - Question = "Which department would you like to contact?"
146
+ - Type = "dropdown"
147
+ - Click "Save and continue editing"
148
+ - Click on the Department field link to edit it
149
+ - In the "Field options" section at the bottom, add:
150
+ - Option 1: Value = "sales", Label = "Sales Team", Position = 1
151
+ - Option 2: Value = "support", Label = "Customer Support", Position = 2
152
+ - Add a rating field back in the main form:
153
+ - Label = "Satisfaction"
154
+ - Question = "How satisfied are you with our service?"
155
+ - Type = "rating"
156
+ - Expand "Rating Configuration" section
157
+ - Set Scale = 5, Style = "stars"
158
+ - Positions will auto-update as you add/remove fields
159
+ - Save the form
160
+
161
+ 2. **Fetch the JSON schema via API:**
162
+
163
+ ```bash
164
+ curl http://localhost:8000/api/forms/contact-us/
165
+ ```
166
+
167
+ You'll receive:
168
+
169
+ ```json
170
+ {
171
+ "form": {
172
+ "name": "Contact Us",
173
+ "slug": "contact-us",
174
+ "status": "published"
175
+ },
176
+ "fields": [
177
+ {
178
+ "id": "full_name",
179
+ "type": "text",
180
+ "label": "Full Name",
181
+ "question": "What is your full name?",
182
+ "required": true,
183
+ "position": 1,
184
+ ...
185
+ },
186
+ {
187
+ "id": "department",
188
+ "type": "dropdown",
189
+ "label": "Department",
190
+ "question": "Which department would you like to contact?",
191
+ "config": {
192
+ "options": [
193
+ {"value": "sales", "label": "Sales Team", "isDefault": false},
194
+ {"value": "support", "label": "Customer Support", "isDefault": false}
195
+ ]
196
+ },
197
+ "position": 2,
198
+ ...
199
+ },
200
+ {
201
+ "id": "satisfaction",
202
+ "type": "rating",
203
+ "label": "Satisfaction",
204
+ "question": "How satisfied are you with our service?",
205
+ "config": {
206
+ "scale": 5,
207
+ "style": "stars"
208
+ },
209
+ "position": 3,
210
+ ...
211
+ }
212
+ ]
213
+ }
214
+ ```
215
+
216
+ 3. **Preview before publishing:**
217
+ - While editing a form in admin, click the "Preview JSON" link to see the generated schema
218
+ - Forms with `status="draft"` return 404 from the API but are visible in admin preview
219
+
220
+ ## JSON Schema Contract
221
+
222
+ Returned from `/api/forms/<slug>/` when the form status is `published`.
223
+
224
+ ```json
225
+ {
226
+ "form": {
227
+ "name": "Contact Us",
228
+ "slug": "contact-us",
229
+ "description": "Lead capture form",
230
+ "status": "published"
231
+ },
232
+ "fields": [
233
+ {
234
+ "id": "full_name",
235
+ "type": "text",
236
+ "label": "Full Name",
237
+ "required": true,
238
+ "helpText": "As shown on ID",
239
+ "placeholder": "Jane Doe",
240
+ "defaultValue": null,
241
+ "position": 1,
242
+ "config": {
243
+ "minLength": 2,
244
+ "maxLength": 120,
245
+ "inputMode": "text",
246
+ "prefix": "",
247
+ "suffix": ""
248
+ }
249
+ }
250
+ ]
251
+ }
252
+ ```
253
+
254
+ ### Field Attribute Matrix
255
+
256
+ | Field Type | Config Keys | Notes |
257
+ | --- | --- | --- |
258
+ | `text` | `minLength`, `maxLength`, `pattern`, `inputMode`, `prefix`, `suffix` | Single-line text input |
259
+ | `number` | `min`, `max`, `step`, `prefix`, `suffix`, `unit` | Numeric input with validation |
260
+ | `textarea` | `rows`, `minLength`, `maxLength`, `autoResize` | Multi-line text input |
261
+ | `dropdown` | `allowMultiple`, `allowOther`, `options`, `defaultOption` | Options managed via FieldOption model (inline editor) |
262
+ | `radio` | `allowOther`, `options`, `defaultOption` | Single selection, options via FieldOption model |
263
+ | `checkbox` | `minSelections`, `maxSelections`, `allowOther`, `options`, `defaultOption` | Multiple selections, options via FieldOption model |
264
+ | `rating` | `scale` (5 or 10), `style` (stars/numeric/emoji), `minLabel`, `maxLabel` | Rating scale input |
265
+ | `boolean` | `trueLabel`, `falseLabel`, `style` | Yes/No or True/False |
266
+ | `email` | `confirmEmail` | Email with validation |
267
+ | `date` | `minDate`, `maxDate`, `format` | Date picker |
268
+
269
+ ## Sample Fixture
270
+
271
+ Load an example form (Contact Us) into any project:
272
+
273
+ ```bash
274
+ python manage.py loaddata formbuilder/fixtures/demo_form.json
275
+ ```
276
+
277
+ The fixture seeds one published `CustomForm` with two fields (text + dropdown) so you can immediately hit `/api/forms/contact-demo/` and inspect the JSON. Use this as a template when sharing schemas with frontend teams.
278
+
279
+ ## Testing Locally
280
+
281
+ This repo includes a tiny Django settings module (`formbuilder_test_site`) used only for running the test suite:
282
+
283
+ ```bash
284
+ uv sync --group dev
285
+ pytest
286
+ ```
287
+
288
+ The configured `pytest` run uses `-vv --cov=formbuilder --cov-report=term-missing`, so the CLI output lists each test, statuses, and line coverage to help you verify exactly what executed.
289
+
290
+ ## Development Setup
291
+
292
+ To enable pre-commit hooks for linting and formatting:
293
+
294
+ ```bash
295
+ uv tool install pre-commit
296
+ pre-commit install
297
+ ```
298
+
299
+ ## Feature Flag
300
+
301
+ Toggle the read-only API via the `FORMBUILDER_API_ENABLED` setting. The API is disabled unless you explicitly set `FORMBUILDER_API_ENABLED = True`; when left `False`, `/api/forms/<slug>/` returns 404 regardless of form status.
302
+
303
+ ## Compatibility Notes
304
+
305
+ - Django 5.1 on Python 3.14 has a known bug in `django.template.context.BaseContext.__copy__`. This package patches the method at import time so admin pages continue to work. No action is required from host projects besides including `formbuilder` in `INSTALLED_APPS`.
@@ -0,0 +1,29 @@
1
+ django_basic_form_builder-0.1.2.dist-info/licenses/LICENSE,sha256=DKWp0GaHtPLZnBBY0raAuoucn7eDZbDdQonqfV9b7wI,1078
2
+ formbuilder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ formbuilder/admin.py,sha256=RuRjkEoYupmHIqcbFH3AOVQ3svga9yTpF84cu89ffrs,16972
4
+ formbuilder/apps.py,sha256=60reK5EstcxIpiLCSo3ZObhEKUWLMVmKDvQMctrQBCw,297
5
+ formbuilder/compat.py,sha256=mDX0fqbRZ2j3MqVAhK_hd6R-CrzfkbTvVR7Nv6arlho,1016
6
+ formbuilder/models.py,sha256=txzygJvApWRA6UwjcxAa1nKslEGSEsYjTHb5veal8k8,13723
7
+ formbuilder/schema_types.py,sha256=qFRFiy-m5ADA9JA_iTQD82-theklzQ-TDsYtvRix9xo,2357
8
+ formbuilder/views.py,sha256=F42JXgnqFqK0fajXeutyJJxwOszRxoLMNkIhfc4Z7KI,26
9
+ formbuilder/api/serializers.py,sha256=VoE2-3MRMi5spFCCahooWBOs7Env1vuJ4L7Qw5_Y6Ns,278
10
+ formbuilder/api/urls.py,sha256=I7NaLFhJ_2m03mDvZztMlquBJmYZEVhTX8W4zyQKQSQ,191
11
+ formbuilder/api/views.py,sha256=VuQG4gk0mlGb3Jx5Zzomalj-DlgFt0ECAoui9ohVxNk,968
12
+ formbuilder/migrations/0001_initial.py,sha256=b4ygW7B8oDTmG0gRYb1eRd_ujYKg23NYcZCCKQ5BeG0,3569
13
+ formbuilder/migrations/0002_alter_formfield_field_type_fieldoption.py,sha256=PlRa9PgESWUkYS81Tit8s8vZYzZJbLn1BqNM_ibmiyE,2305
14
+ formbuilder/migrations/0003_formfield_question_alter_formfield_label.py,sha256=tDWUZyFkEvvLzZcBEzDlnEwspQrh2vlykB1sn-G3TF8,703
15
+ formbuilder/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ formbuilder/services/schema_builder.py,sha256=4MPpcUngzwd48NsmwKU5sbWWi_N7_YWUW0K4SoG9MIs,3524
17
+ formbuilder/static/formbuilder/admin/css/formfield_admin.css,sha256=NYIlkNeP3GupJ7QhaB2BizlaxfTT9OYTw4tOBIPkAaw,3683
18
+ formbuilder/static/formbuilder/admin/js/formfield_admin.js,sha256=H8L97Zb4IpuwUAZWjgeF2rAxDT7gSm9UADpR6O9tMpM,7016
19
+ formbuilder/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ formbuilder/tests/conftest.py,sha256=Vi7tIOGt8dbJcNksa1qQ2-RoxAGudUQknJbpRqFBiZc,191
21
+ formbuilder/tests/test_admin.py,sha256=sliE66mW2NXnQU8prtMne5auuEnkAfLapSfn1kXr-yQ,1655
22
+ formbuilder/tests/test_api.py,sha256=ym77heWCyWDRIYEDc2YAUtLkfeuqNNM1MvEjIsMu6Bc,1738
23
+ formbuilder/tests/test_compat.py,sha256=o55fcFV-rz8u2u1kI2uwHB9ZQBNHC0dx40h49oyNv8s,477
24
+ formbuilder/tests/test_models.py,sha256=_uj6818kcg9O053tYZrBhfk5_gAkKp86zDnBeJGMrho,8151
25
+ formbuilder/tests/test_schema_builder.py,sha256=HPgAiubf4nz8vsl2oWBgiuSXqc-d2r16HC_V64fYTwI,1992
26
+ django_basic_form_builder-0.1.2.dist-info/METADATA,sha256=-Z9MjXnbzkzKpls09wb8ZC9NIxIdJV4Rwt7OgsoFucI,11322
27
+ django_basic_form_builder-0.1.2.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
28
+ django_basic_form_builder-0.1.2.dist-info/top_level.txt,sha256=3cWOFLIgADOSoJAU12DQIg9n0Ju1cgI0PBAcZ-0CNgY,12
29
+ django_basic_form_builder-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Göktürk Burak Köse
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ formbuilder
File without changes