Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

Implemented conditional logic based on fields values and different re… #228

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e8ac852
Fix the HTML rendering function in the Form popup
yvladislav Feb 20, 2020
20fd9e6
Remove unicode characters, add the correct HTML rendering for the For…
yvladislav Feb 20, 2020
7153688
fixed flake8 error
vnosov93 May 27, 2020
f769d39
Implemented conditional logic based on fields values and different re…
sgordeychuk Nov 17, 2021
8f0c973
Fix for timeout
sgordeychuk Nov 18, 2021
feff7e2
Another fix for timeout
sgordeychuk Nov 18, 2021
104f7e6
Merge remote-tracking branch 'divio/master'
sgordeychuk Jan 23, 2023
6258618
Remove unicode characters, add the correct HTML rendering for the For…
yvladislav Feb 20, 2020
60ed640
Merge remote-tracking branch 'origin/master'
sgordeychuk Jan 23, 2023
02c04c9
Django 4 support
sgordeychuk Aug 20, 2023
0a4fd33
Bump version 6.2.2
sgordeychuk Aug 20, 2023
a1e35f7
Feature/filefield allowed extensions and attach files to email (#1)
blueshack112 Nov 7, 2023
2be38fc
avoid lower-casing files_to_attach field since uppercase names are al…
blueshack112 Nov 8, 2023
dca077f
add option to store file to filer (default=True) (#4)
blueshack112 Nov 8, 2023
2bc6494
create a copy of in-memory file to avoid unpredictability (#5)
blueshack112 Nov 9, 2023
d42a1d0
Feature/filefield custom error on allowed extensions validation (#6)
blueshack112 Nov 14, 2023
0c3ce4a
Merge branch 'master' into form-conditions-redirect-support
sgordeychuk Mar 8, 2024
ce63854
Added merge migration and some translations
sgordeychuk Mar 25, 2024
3327930
imp: open accordion on errors (#7)
kobecuppens1997 Mar 25, 2024
ed12275
fix for select and textarea
kobecuppens1997 Mar 26, 2024
3811be3
fix for select and textarea
kobecuppens1997 Mar 26, 2024
a720b86
Hotfix for the uploaded file
sgordeychuk Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aldryn_forms/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '6.2.1'
__version__ = '6.2.2'
2 changes: 1 addition & 1 deletion aldryn_forms/action_backends.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging

from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from .action_backends_base import BaseAction

Expand Down
6 changes: 3 additions & 3 deletions aldryn_forms/admin/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.contrib import admin
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _


str_dunder_method = '__str__'
Expand Down Expand Up @@ -51,11 +51,11 @@ def get_recipients_for_display(self, obj):
get_recipients_for_display.short_description = _('people notified')

def get_urls(self):
from django.conf.urls import url
from django.urls import re_path

def pattern(regex, fn, name):
args = [regex, self.admin_site.admin_view(fn)]
return url(*args, name=self.get_admin_url(name))
return re_path(*args, name=self.get_admin_url(name))

url_patterns = [
pattern(r'export/$', self.get_form_export_view(), 'export'),
Expand Down
6 changes: 3 additions & 3 deletions aldryn_forms/admin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from django.contrib.admin.widgets import AdminDateWidget
from django.utils import timezone
from django.utils.text import slugify
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _

from ..models import FormSubmission
from .exporter import Exporter
Expand Down Expand Up @@ -129,6 +129,6 @@ def clean(self):
fields = self.get_fields()

if not fields:
message = ugettext('Please select at least one field to export.')
message = gettext('Please select at least one field to export.')
raise forms.ValidationError(message)
return self.cleaned_data
4 changes: 2 additions & 2 deletions aldryn_forms/admin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.contrib import messages
from django.http import HttpResponse
from django.shortcuts import redirect
from django.utils.translation import get_language_from_request, ugettext
from django.utils.translation import get_language_from_request, gettext

from ..compat import SessionWizardView
from .exporter import Exporter
Expand Down Expand Up @@ -65,7 +65,7 @@ def render_next_step(self, form, **kwargs):

if next_step == self.steps.last and not form.get_queryset().exists():
self.storage.reset()
self.admin.message_user(self.request, ugettext("No records found"), level=messages.WARNING)
self.admin.message_user(self.request, gettext("No records found"), level=messages.WARNING)
export_url = 'admin:{}'.format(self.admin.get_admin_url('export'))
return redirect(export_url)
return super(FormExportWizardView, self).render_next_step(form, **kwargs)
Expand Down
2 changes: 1 addition & 1 deletion aldryn_forms/cms_apps.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
Expand Down
123 changes: 84 additions & 39 deletions aldryn_forms/cms_plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import io
from typing import Dict

from PIL import Image
from django.core.files.uploadedfile import InMemoryUploadedFile

from aldryn_forms.models import FormPlugin
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
Expand All @@ -9,8 +12,8 @@
from django.core.validators import MinLengthValidator
from django.db.models import query
from django.template.loader import select_template
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from emailit.api import send_mail
from filer.models import filemodels
from filer.models import imagemodels
Expand All @@ -32,15 +35,17 @@
from .forms import TextAreaFieldForm
from .forms import TextFieldForm
from .helpers import get_user_name
from .models import FileUploadFieldPlugin
from .models import SerializedFormField
from .signals import form_post_save
from .signals import form_pre_save
from .sizefield.utils import filesizeformat
from .utils import get_action_backends
from .validators import MaxChoicesValidator
from .validators import MinChoicesValidator
from .validators import is_valid_recipient
from .validators import (
MaxChoicesValidator,
MinChoicesValidator,
is_valid_recipient,
generate_file_extension_validator,
)


class FormElement(CMSPluginBase):
Expand Down Expand Up @@ -70,6 +75,14 @@ class FormPlugin(FieldContainer):
'url',
)
}),
(_('Condition Logic'), {
'classes': ('collapse',),
'fields': (
'redirect_page_negative_condition',
'condition_field',
'condition_value',
)
}),
(_('Advanced Settings'), {
'classes': ('collapse',),
'fields': (
Expand All @@ -92,7 +105,12 @@ def render(self, context, instance, placeholder):

if request.POST.get('form_plugin_id') == str(instance.id) and form.is_valid():
context['post_success'] = True
context['form_success_url'] = self.get_success_url(instance)
condition_value = None
field_data = form.get_cleaned_data()
if instance.condition_field in field_data:
condition_value = field_data[instance.condition_field]

context['form_success_url'] = self.get_success_url(instance, condition_value)
context['form'] = form
return context

Expand Down Expand Up @@ -186,7 +204,10 @@ def get_form_kwargs(self, instance, request):
kwargs['files'] = request.FILES
return kwargs

def get_success_url(self, instance):
def get_success_url(self, instance, condition_value):
if instance.redirect_page_negative_condition and instance.condition_field:
if instance.condition_value == condition_value:
return instance.redirect_page_negative_condition.get_absolute_url()
return instance.success_url

def send_notifications(self, instance, form):
Expand Down Expand Up @@ -286,7 +307,7 @@ class Field(FormElement):

def serialize_value(self, instance, value, is_confirmation=False):
if isinstance(value, query.QuerySet):
value = u', '.join(map(str, value))
value = ', '.join(map(str, value))
elif value is None:
value = '-'
return str(value)
Expand Down Expand Up @@ -543,9 +564,9 @@ class EmailField(BaseTextField):
form_field_widget = forms.EmailInput
form_field_widget_input_type = 'email'
fieldset_advanced_fields = [
'email_send_notification',
'email_subject',
'email_body',
"email_send_notification",
"email_subject",
"email_body",
] + Field.fieldset_advanced_fields
email_template_base = 'aldryn_forms/emails/user/notification'

Expand Down Expand Up @@ -586,11 +607,14 @@ class FileField(Field):
'validators',
]
fieldset_general_fields = [
'upload_to',
"upload_to",
] + Field.fieldset_general_fields
fieldset_advanced_fields = [
'store_to_filer',
'help_text',
'max_size',
'allowed_extensions',
'invalid_extension_message',
'required_message',
'custom_classes',
]
Expand All @@ -602,52 +626,71 @@ def get_form_field_kwargs(self, instance):
kwargs['help_text'] = kwargs['help_text'].replace(
'MAXSIZE', filesizeformat(instance.max_size))
kwargs['max_size'] = instance.max_size
if instance.allowed_extensions:
kwargs['allowed_extensions'] = instance.allowed_extensions
return kwargs

def get_form_field_validators(self, instance: models.FileFieldPluginBase):
validators = super().get_form_field_validators(instance)
validators.append(
generate_file_extension_validator(
instance.allowed_extensions, instance.invalid_extension_message
)
)
return validators

def serialize_value(self, instance, value, is_confirmation=False):
if value:
if value and hasattr(value, "absolute_uri"):
return value.absolute_uri
else:
return '-'

def form_pre_save(self, instance, form, **kwargs):
def form_pre_save(self, instance: models.FileUploadFieldPlugin, form, **kwargs):
"""Save the uploaded file to django-filer

The type of model (file or image) is automatically chosen by trying to
open the uploaded file.
"""

request = kwargs['request']

field_name = form.form_plugin.get_form_field_name(field=instance)

uploaded_file = form.cleaned_data[field_name]
uploaded_file: InMemoryUploadedFile = form.cleaned_data[field_name]

if uploaded_file is None:
return

try:
with Image.open(uploaded_file) as img:
img.verify()
except: # noqa
model = filemodels.File
else:
model = imagemodels.Image

filer_file = model(
folder=instance.upload_to,
file=uploaded_file,
name=uploaded_file.name,
original_filename=uploaded_file.name,
is_public=True,
)
filer_file.save()
copy = io.BytesIO(uploaded_file.read())
uploaded_file.seek(0)

if instance.store_to_filer:
try:
with Image.open(uploaded_file) as img:
img.verify()
except: # noqa
model = filemodels.File
else:
model = imagemodels.Image

filer_file = model(
folder=instance.upload_to,
file=uploaded_file,
name=uploaded_file.name,
original_filename=uploaded_file.name,
is_public=True,
)
filer_file.save()

# NOTE: This is a hack to make the full URL available later when we
# need to serialize this field. We avoid to serialize it here directly
# as we could still need access to the original filer File instance.
filer_file.absolute_uri = request.build_absolute_uri(filer_file.url)
# NOTE: This is a hack to make the full URL available later when we
# need to serialize this field. We avoid to serialize it here directly
# as we could still need access to the original filer File instance.
filer_file.absolute_uri = request.build_absolute_uri(filer_file.url)

form.cleaned_data[field_name] = filer_file
form.cleaned_data[field_name] = filer_file

uploaded_file.close()
form.cleaned_data[f"{field_name}__in_memory"] = {"name": uploaded_file.name, "file": copy}


class ImageField(FileField):
Expand All @@ -658,9 +701,10 @@ class ImageField(FileField):
form_field = RestrictedImageField
form_field_widget = RestrictedImageField.widget
fieldset_general_fields = [
'upload_to',
"upload_to",
] + Field.fieldset_general_fields
fieldset_advanced_fields = [
'store_to_filer',
'help_text',
'max_size',
('max_width', 'max_height',),
Expand Down Expand Up @@ -713,7 +757,7 @@ class BooleanField(Field):
]

def serialize_value(self, instance, value, is_confirmation=False):
return ugettext('Yes') if value else ugettext('No')
return gettext('Yes') if value else gettext('No')


class SelectOptionInline(TabularInline):
Expand Down Expand Up @@ -859,6 +903,7 @@ def serialize_field(self, *args, **kwargs):
# None means don't serialize me
return None


plugin_pool.register_plugin(CaptchaField)


Expand Down
Loading