Porównaj commity

...

7 Commity
0.4.1 ... main

Autor SHA1 Wiadomość Data
mtyton f8f3d35935 Merge pull request 'Renamed project to wagtail_store' (#23) from feature/project_rename into main
Reviewed-on: #23
2023-11-27 21:45:19 +00:00
mtyton 6bc385e47d Renamed project to wagtail_store 2023-11-27 22:34:44 +01:00
mtyton 345dbe3f46 Merge pull request 'Fixed tests' (#22) from feature/form_improvements into main
ci/woodpecker/push/build Pipeline was successful Szczegóły
ci/woodpecker/tag/build Pipeline was successful Szczegóły
Reviewed-on: #22
2023-11-12 09:30:30 +00:00
mtyton a5e243c55c Fixed tests
ci/woodpecker/push/build Pipeline was successful Szczegóły
ci/woodpecker/pr/build Pipeline was successful Szczegóły
2023-11-12 10:29:59 +01:00
mtyton 1ab8537c64 Merge pull request 'form anty-spam, hiden field rendering, added help_text showing' (#21) from feature/form_improvements into main
ci/woodpecker/push/build Pipeline was successful Szczegóły
Reviewed-on: #21
2023-11-12 09:08:56 +00:00
mtyton d365a1ee98 form anty-spam, hiden field rendering, added help_text showing
ci/woodpecker/push/build Pipeline was successful Szczegóły
ci/woodpecker/pr/build Pipeline failed Szczegóły
2023-11-12 09:51:09 +01:00
mtyton 19078bd03f Added submission_id to email context
ci/woodpecker/push/build Pipeline was successful Szczegóły
ci/woodpecker/tag/build Pipeline was successful Szczegóły
2023-11-05 20:03:03 +01:00
205 zmienionych plików z 124 dodań i 49 usunięć

6
.gitignore vendored
Wyświetl plik

@ -139,8 +139,8 @@ GitHub.sublime-settings
#postgres pass files
*.my_pgpass
*.sql
artel/static/
wagtail_store/static/
# media
artel/media/*
artel/store/data/*
wagtail_store/media/*
wagtail_store/store/data/*

Wyświetl plik

@ -1,35 +0,0 @@
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% load i18n %}
{% block content %}
<h1>{{ page.title }}</h1>
<p class="meta">{{ page.date }}</p>
{% if form %}
{{form.errors}}
<div>{{ page.intro|richtext }}</div>
<form enctype="multipart/form-data" action="{% pageurl page %}" method="POST">
{% csrf_token %}
{% for field in form %}
<div class="form-group mt-3">
<label for="{{field.id}}" class="form-label">
{% trans field.label %}
</label>
{{field}}
<small id="emailHelp" class="form-text text-muted">
{% trans field.help_text %}
</small>
{% if field.error %}
{{error}}
{% endif %}
</div>
{% endfor %}
<div class="text-end mt-3">
<input class="btn btn-lg btn-success" type="submit" value='{% trans "Submit" %}'>
</div>
</form>
{% else %}
<div>You can fill in the from only one time.</div>
{% endif %}
{% endblock %}

Wyświetl plik

@ -24,6 +24,23 @@ class MultipleFileField(forms.FileField):
return result
class HoneypotField(forms.BooleanField):
default_widget = forms.HiddenInput(
{'style': 'display:none !important;', 'tabindex': '-1', 'autocomplete': 'off'}
)
def __init__(self, *args, **kwargs):
kwargs.setdefault('widget', HoneypotField.default_widget)
kwargs['required'] = False
super().__init__(*args, **kwargs)
def clean(self, value):
if cleaned_value := super().clean(value):
raise forms.ValidationError('')
else:
return cleaned_value
class DynamicForm(forms.Form):
FIELD_TYPE_MAPPING = {
@ -54,6 +71,7 @@ class DynamicForm(forms.Form):
if hasattr(f, "choices"):
f.choices = [(v, v) for v in field.choices.split(",")]
f.required = field.required
f.help_text = field.help_text or ""
self.fields[field.clean_name] = f
if file_uploads:
self.fields["attachments"] = MultipleFileField(
@ -61,3 +79,21 @@ class DynamicForm(forms.Form):
attrs={"class": "form-control"}
)
)
# add honeypot field
self.fields["secret_honey"] = HoneypotField()
def clean(self):
cleaned_data = super().clean()
new_cleaned_data = {}
for key, value in cleaned_data.items():
if isinstance(value, list):
if isinstance(self.fields[key], MultipleFileField):
continue
cleaned_data[key] = ",".join(value)
if key=="secret_honey":
continue
new_cleaned_data[key] = value
return new_cleaned_data

Wyświetl plik

@ -59,7 +59,12 @@ class Form(FormMixin, Page):
class EmailFormSubmission(AbstractFormSubmission):
# TODO - make this optional, allow to set pattern in admin
def get_submission_id(self, form_slug):
case_number_daily = EmailFormSubmission.objects.filter(submit_time__date=datetime.date.today()).count()
return f"{form_slug}-{datetime.date.today()}-{case_number_daily}"
def send_mail(self, data):
# modify this, get proper template
to_addresses = data.pop("to_address").split(",")
@ -69,7 +74,8 @@ class EmailFormSubmission(AbstractFormSubmission):
)
for file in data.pop("attachments", [])
]
subject = data.get("subject")
subject = data.pop("subject")
form_slug = data.pop("form_slug")
from_address = data.pop("from_address", settings.DEFAULT_FROM_EMAIL)
for address in to_addresses:
OutgoingEmail.objects.send(
@ -77,7 +83,7 @@ class EmailFormSubmission(AbstractFormSubmission):
template_name="form_mail",
recipient=address,
sender=from_address,
context={"form_data": data},
context={"form_data": data, "submission_id": self.get_submission_id(form_slug)},
attachments=attachments
)
@ -112,7 +118,8 @@ class CustomEmailForm(Form):
"from_address": self.from_address,
"to_address": self.to_address,
"subject": self.subject,
"attachments": attachments
"attachments": attachments,
"form_slug": self.slug
})
submission.send_mail(data=mail_data)
return submission

Wyświetl plik

@ -0,0 +1,40 @@
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% load i18n %}
{% block content %}
<h1>{{ page.title }}</h1>
<p class="meta">{{ page.date }}</p>
{% if form %}
{{form.errors}}
<div>{{ page.intro|richtext }}</div>
<form enctype="multipart/form-data" action="{% pageurl page %}" method="POST">
{% csrf_token %}
{% for field in form %}
{% if field.is_hidden %}
<!--Empty space for reason, we don't want to show anything on empty fields-->
{{field}}
{% else %}
<div class="form-group mt-3">
<label for="{{field.id}}" class="form-label">
{% trans field.label %}
</label>
{{field}}
<small id="emailHelp" class="form-text text-muted">
{% trans field.help_text %}
</small>
{% if field.error %}
{{error}}
{% endif %}
</div>
{% endif %}
{% endfor %}
<div class="text-end mt-3">
<input class="btn btn-lg btn-success" type="submit" value='{% trans "Submit" %}'>
</div>
</form>
{% else %}
<div>You can fill in the from only one time.</div>
{% endif %}
{% endblock %}

Wyświetl plik

@ -104,7 +104,7 @@ class CustomEmailFormTestCase(WagtailPageTests):
def test_generate_html_form_from_model(self):
html_form = self.form.get_form()
self.assertIsInstance(html_form, DynamicForm)
self.assertEqual(len(html_form.fields), 13)
self.assertEqual(len(html_form.fields), 14)
self.assertEqual(html_form.fields["name"].label, "Name")
self.assertEqual(html_form.fields["name"].required, True)
self.assertEqual(html_form.fields["name"].widget.attrs["class"], "form-control")
@ -275,3 +275,30 @@ class CustomEmailFormTestCase(WagtailPageTests):
self.assertEqual(form.errors["name"], ['This field is required.'])
self.assertEqual(form.errors["url"], ['This field is required.'])
self.assertEqual(form.errors["attachments"], ['This field is required.'])
def test_no_hidden_field_in_clean_data_success(self):
form_data = {
# generate data for this class self.form.get_form()
"name": "Test",
"message": "Test message",
"email": "test@test.com",
"number": 1,
"url": "http://example.com",
"checkbox": True,
"checkboxes": ["a", "b"],
"dropdown": "a",
"multiselect": ["a", "b"],
"radio": "a",
"date": "2020-01-01",
"datetime": "2020-01-01 00:00:00",
"hidden": "hidden",
}
form = self.form.get_form(form_data)
self.assertTrue(form.is_valid())
cleaned_data = form.cleaned_data
self.assertIn("hidden", cleaned_data)
self.assertNotIn("secret_honey", cleaned_data)
self.assertIn("hidden", form.fields)
self.assertIn("secret_honey", form.fields)

Wyświetl plik

@ -3,7 +3,7 @@ import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "artel.settings.dev")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wagtail_store.settings.dev")
from django.core.management import execute_from_command_line

Some files were not shown because too many files have changed in this diff Show More