Skip to content

Commit 51845bd

Browse files
authored
Merge branch 'main' into updated
2 parents 16d3ac6 + a4889f5 commit 51845bd

39 files changed

+448
-1923
lines changed

.github/workflows/codecov.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: [ 3.8, 3.9, "3.10", "3.11"] # latest release minus two
15+
python-version: [ 3.9, "3.10", "3.11", "3.12"] # latest release minus two
1616
requirements-file: [
17-
dj32_cms38.txt,
18-
dj32_cms39.txt,
19-
dj32_cms310.txt,
20-
dj32_cms311.txt,
21-
dj40_cms311.txt,
22-
dj41_cms311.txt,
23-
dj41_cms41.txt,
17+
dj42_cms311.txt,
18+
dj42_cms41.txt,
19+
dj50_cms41.txt,
20+
dj51_cms41.txt,
2421
]
2522
os: [
2623
ubuntu-20.04,
2724
]
25+
exclude:
26+
- python-version: 3.9
27+
requirements-file: dj50_cms41.txt
28+
- python-version: 3.9
29+
requirements-file: dj51_cms41.txt
2830

2931
steps:
3032
- uses: actions/checkout@v3
@@ -38,7 +40,8 @@ jobs:
3840
- name: Generate Report
3941
run: |
4042
pip install -r tests/requirements/${{ matrix.requirements-file }}
41-
coverage run setup.py test
43+
pip install -e .
44+
coverage run ./run_tests.py
4245
- name: Upload Coverage to Codecov
4346
uses: codecov/codecov-action@v3
4447

.github/workflows/publish-to-test-pypi.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
push:
55
branches:
66
- main
7+
workflow_dispatch:
8+
branches:
9+
- main
710

811
jobs:
912
build-n-publish:
@@ -38,3 +41,4 @@ jobs:
3841
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
3942
repository_url: https://test.pypi.org/legacy/
4043
skip_existing: true
44+
verbose: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ build/
1818
dist/
1919
env/
2020
.venv/
21+
venv/
2122

2223
/~
2324
/node_modules

.pre-commit-config.yaml

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,9 @@ repos:
66
rev: v2.32.1
77
hooks:
88
- id: pyupgrade
9-
args: [ "--py37-plus" ]
9+
args: [ "--py38-plus" ]
1010
- repo: https://github.com/adamchainz/django-upgrade
11-
rev: '1.7.0'
11+
rev: '1.16.0'
1212
hooks:
1313
- id: django-upgrade
14-
args: [ --target-version, "2.2" ]
15-
- repo: https://github.com/pycqa/isort
16-
rev: 5.10.1
17-
hooks:
18-
- id: isort
19-
name: isort (python)
20-
- repo: https://github.com/PyCQA/flake8
21-
rev: 4.0.1
22-
hooks:
23-
- id: flake8
24-
additional_dependencies:
25-
- flake8-bugbear
26-
- flake8-builtins
27-
- flake8-django
28-
- flake8-length
29-
- flake8-logging-format
30-
- flake8-spellcheck
14+
args: [ --target-version, "4.2" ]

CHANGELOG.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,37 @@
22
Changelog
33
=========
44

5+
0.3.0 (2025-01-07)
6+
==================
7+
8+
* feat: Success message and redirect action by @fsbraun
9+
* fix: forms did not redirect to same page if sent from alias by @fsbraun
10+
11+
0.2.0 (2025-01-06)
12+
==================
13+
14+
* fix: github coverage action by @fsbraun in https://github.com/django-cms/djangocms-form-builder/pull/12
15+
* fix: an error when an anonymous user fills the form by @arunk in https://github.com/django-cms/djangocms-form-builder/pull/13
16+
* fix: Add support for Django-entangled 0.6+ by @fsbraun in https://github.com/django-cms/djangocms-form-builder/pull/19
17+
* docs: Updated README.rst to show where to add actions by @arunk in https://github.com/django-cms/djangocms-form-builder/pull/14
18+
* chore: Added venv/ directory to .gitignore by @arunk in https://github.com/django-cms/djangocms-form-builder/pull/15
19+
20+
**New Contributors**
21+
* @arunk made their first contribution in https://github.com/django-cms/djangocms-form-builder/pull/13
22+
23+
24+
0.1.1 (2021-09-14)
25+
==================
26+
27+
* feat: updated captcha optional til active by @svandeneertwegh in https://github.com/fsbraun/djangocms-form-builder/pull/4
28+
* feat: Allow actions to add form fields for configuration by @fsbraun in https://github.com/fsbraun/djangocms-form-builder/pull/6
29+
* fix: Update converage action by @fsbraun in https://github.com/fsbraun/djangocms-form-builder/pull/10
30+
* feat: move to hatch build process by @fsbraun
31+
* ci: Add tests for registry by @fsbraun in https://github.com/fsbraun/djangocms-form-builder/pull/5
32+
33+
New Contributors
34+
35+
* @svandeneertwegh made their first contribution in https://github.com/fsbraun/djangocms-form-builder/pull/4
536

637
0.2.0 (unreleased)
738
=================

MANIFEST.in

Lines changed: 0 additions & 7 deletions
This file was deleted.

README.rst

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,21 @@ A Form plugin must not be used within another Form plugin.
8686
Actions
8787
-------
8888

89-
Upon submission of a valid form actions can be performed. A project can register as many actions as it likes::
89+
Upon submission of a valid form actions can be performed.
90+
91+
Four actions come with djangocms-form-builder comes with four actions built-in
92+
93+
* **Save form submission** - Saves each form submission to the database. See the
94+
results in the admin interface.
95+
* **Send email** - Sends an email to the site admins with the form data.
96+
* **Success message** - Specify a message to be shown to the user upon
97+
successful form submission.
98+
* **Redirect after submission** - Specify a link to a page where the user is
99+
redirected after successful form submission.
100+
101+
Actions can be configured in the form plugin.
102+
103+
A project can register as many actions as it likes::
90104

91105
from djangocms_form_builder import actions
92106

@@ -98,6 +112,33 @@ Upon submission of a valid form actions can be performed. A project can register
98112
... # This method is run upon successful submission of the form
99113

100114

115+
To add this action, might need to be added to your project only after all Django apps have loaded at startup.
116+
You can put these actions in your apps models.py file. Another options is your apps, apps.py file::
117+
118+
from django.apps import AppConfig
119+
120+
class MyAppConfig(AppConfig):
121+
default_auto_field = 'django.db.models.BigAutoField'
122+
name = 'myapp'
123+
label = 'myapp'
124+
verbose_name = _("My App")
125+
126+
def ready(self):
127+
super().ready()
128+
129+
from djangocms_form_builder import actions
130+
131+
@actions.register
132+
class MyAction(actions.FormAction): # Or import from within the ready method
133+
verbose_name = _("Everything included action")
134+
135+
def execute(self, form, request):
136+
... # This method is run upon successful submission of the form
137+
# Process form and request data, you can send an email to the person who filled the form
138+
# Or admins though that functionality is available from the default SendMailAction
139+
140+
141+
101142
Using (existing) Django forms with djangocms-form-builder
102143
=========================================================
103144

@@ -131,8 +172,8 @@ Actions are not available for Django forms. Any actions to be performed upon sub
131172
.. |pypi| image:: https://badge.fury.io/py/djangocms-form-builder.svg
132173
:target: http://badge.fury.io/py/djangocms-form-builder
133174

134-
.. |coverage| image:: https://codecov.io/gh/fsbraun/djangocms-form-builder/branch/master/graph/badge.svg
135-
:target: https://codecov.io/gh/fsbraun/djangocms-form-builder
175+
.. |coverage| image:: https://codecov.io/gh/django-cms/djangocms-form-builder/branch/main/graph/badge.svg
176+
:target: https://codecov.io/gh/django-cms/djangocms-form-builder
136177

137178
.. |python| image:: https://img.shields.io/badge/python-3.7+-blue.svg
138179
:target: https://pypi.org/project/djangocms-form-builder/

djangocms_form_builder/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
try:
44
from django.utils.translation import gettext_lazy as _
55
except ModuleNotFoundError:
6-
_ = lambda x: x
6+
_ = lambda x: x # noqa: E731
77

88

9-
__version__ = "0.1"
9+
__version__ = "0.3.0"
1010

1111
_form_registry = {}
1212

djangocms_form_builder/actions.py

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import hashlib
22

33
from django import forms
4+
from django.apps import apps
45
from django.core.exceptions import ImproperlyConfigured
5-
from django.core.mail import mail_admins, send_mail
66
from django.core.validators import EmailValidator
77
from django.template import TemplateDoesNotExist
88
from django.template.loader import render_to_string
99
from django.utils.html import strip_tags
1010
from django.utils.translation import gettext_lazy as _
11+
from djangocms_text_ckeditor.fields import HTMLFormField
1112
from entangled.forms import EntangledModelFormMixin
1213

1314
from . import models
@@ -125,7 +126,7 @@ def execute(self, form, request):
125126
keys = {}
126127
defaults = {
127128
"form_name": get_option(form, "form_name"),
128-
"form_user": form_user,
129+
"form_user": None if request.user.is_anonymous else request.user
129130
}
130131
defaults.update(
131132
{
@@ -190,14 +191,16 @@ class Meta:
190191
)
191192

192193
def execute(self, form, request):
193-
recipients = (self.get_parameter(form, "sendemail_recipients") or []).split()
194+
from django.core.mail import mail_admins, send_mail
195+
196+
recipients = self.get_parameter(form, "sendemail_recipients") or ""
194197
template_set = self.get_parameter(form, "sendemail_template") or "default"
195198
context = dict(
196199
cleaned_data=form.cleaned_data,
197200
form_name=getattr(form.Meta, "verbose_name", ""),
198201
user=request.user,
199-
user_agent=request.headers["User-Agent"],
200-
referer=request.headers["Referer"],
202+
user_agent=request.headers["User-Agent"] if "User-Agent" in request.headers else "",
203+
referer=request.headers["Referer"] if "Referer" in request.headers else "",
201204
)
202205

203206
html_message = render_to_string(f"djangocms_form_builder/mails/{template_set}/mail_html.html", context)
@@ -209,19 +212,73 @@ def execute(self, form, request):
209212
subject = render_to_string(f"djangocms_form_builder/mails/{template_set}/subject.txt", context)
210213
except TemplateDoesNotExist:
211214
subject = self.subject % dict(form_name=context["form_name"])
215+
212216
if not recipients:
213-
mail_admins(
217+
return mail_admins(
214218
subject,
215219
message,
216220
fail_silently=True,
217221
html_message=html_message,
218222
)
219223
else:
220-
send_mail(
224+
return send_mail(
221225
subject,
222226
message,
223-
recipients,
224227
self.from_mail,
228+
recipients.split(),
225229
fail_silently=True,
226230
html_message=html_message,
227231
)
232+
233+
234+
@register
235+
class SuccessMessageAction(FormAction):
236+
verbose_name = _("Success message")
237+
238+
class Meta:
239+
entangled_fields = {
240+
"action_parameters": [
241+
"submitmessage_message",
242+
]
243+
}
244+
245+
submitmessage_message = HTMLFormField(
246+
label=_("Message"),
247+
required=True,
248+
initial=_("<p>Thank you for your submission.</p>"),
249+
)
250+
251+
def execute(self, form, request):
252+
from .cms_plugins.ajax_plugins import SAME_PAGE_REDIRECT
253+
254+
message = self.get_parameter(form, "submitmessage_message")
255+
# Overwrite the success context and render template
256+
form.get_success_context = lambda *args, **kwargs: {"message": message}
257+
form.Meta.options["render_success"] = "djangocms_form_builder/actions/submit_message.html"
258+
# Overwrite the default redirect to same page
259+
if form.Meta.options.get("redirect") == SAME_PAGE_REDIRECT:
260+
form.Meta.options["redirect"] = None
261+
262+
263+
if apps.is_installed("djangocms_link"):
264+
from djangocms_link.fields import LinkFormField
265+
from djangocms_link.helpers import get_link
266+
267+
@register
268+
class RedirectAction(FormAction):
269+
verbose_name = _("Redirect after submission")
270+
271+
class Meta:
272+
entangled_fields = {
273+
"action_parameters": [
274+
"redirect_link",
275+
]
276+
}
277+
278+
redirect_link = LinkFormField(
279+
label=_("Link"),
280+
required=True,
281+
)
282+
283+
def execute(self, form, request):
284+
form.Meta.options["redirect"] = get_link(self.get_parameter(form, "redirect_link"))

djangocms_form_builder/admin.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ class FormEntryAdmin(admin.ModelAdmin):
88
date_hierarchy = "entry_created_at"
99
list_display = ("__str__", "form_user", "entry_created_at")
1010
list_filter = ("form_name", "form_user", "entry_created_at")
11+
readonly_fields = ["form_name", "form_user"]
12+
13+
def has_add_permission(self, request):
14+
return False
1115

1216
def get_form(self, request, obj=None, **kwargs):
1317
if obj:

0 commit comments

Comments
 (0)