labd / wagtailstreamforms Goto Github PK
View Code? Open in Web Editor NEWWhat happened when a FormBuilder met a StreamField
Home Page: http://wagtailstreamforms.readthedocs.io
License: MIT License
What happened when a FormBuilder met a StreamField
Home Page: http://wagtailstreamforms.readthedocs.io
License: MIT License
This happens because {% csrf_token %}
tag in form_block.html
template can not render without request in context.
wagtail: 1.13.1
Due to the work in wagtail first hatch and the redevelopment of forms, look into and gather requirements into separating the project from the internal forms module.
Is this project still needed?
Does it bring enough once their work is complete.
How to handle form fields?
Adding additional fields?
Admin layout could be improved
Form field widget attrs
Anything else
What we dont want is to keep it as is, if we decide to continue with it, it will need form field code pulled out as wagtail is where the form fields are defined. We want to keep it consistent ie if they are adding fields via a stream field it seems odd to do it here a different way.
Currently there is a known issue where if you have multiple of the same form in a streamfield when it posts and comes back with any validation issues, both forms will see these as there is nothing to tell them apart.
The form_id is the same for both.
Needs investigating to find a method of uniquely identifying them.
While selecting the DateField to show on the form, the input type should be type=date
While selecting the TimeField to show on the form, the input type should be type=time
While selecting the DateField to show on the form, the input type should be type=text
While selecting the TimeField to show on the form, the input type should be type=text
Create a form and put as a field DateField or TimeField
I'm new using this package, i get this bug:
TemplateDoesNotExist at /admin/wagtailstreamforms/basicform/
modeladmin/wagtailstreamforms/basicform/index.html, modeladmin/wagtailstreamforms/index.html, modeladmin/index.html
I though it was a wagtail 2.0
related problem, but not, i'm testing it now with 1.13.x
version and i am still getting this problem.
What's happening?
Allow a developer using this package to only load fields they require, ie you should be able to stop a content editor from building forms with the likes of file fields.
Question on Stack Overflow
Would be nice if we could modify the SubmissionListView in order to achieve customisations for example in the CSV export.
I believe the only way that this could be done now is to add a button on the template and linking it to local view. Is this the case?
Thanks
...
raises invalid literal for int() with base 10: ''
possible usage with thanks to @AimeeHendrycks
<script>
$("#id_streamforms_{{ form.initial.form_id }}").submit(function(e) {
e.preventDefault();
var data = new FormData($(this).get(0));
$.ajax({
type: "POST",
url: ".",
data: data,
processData: false,
contentType: false,
success: function(data) {
// do something with data
console.log(data);
},
error: function(data) {
// do something with data
console.log(data);
}
});
});
</script>
To save the developer remembering to use the mixin.
Where can I get public url of created form?
If a form is deleted and in use we need to gracefully handle a non-existent template error.
When wagtail announced they were rebuilding the forms module we decided we did not want to keep supporting a package that did not provide at least the minimum amount of functionality that they would be implementing or that would be vastly different in look and feel as this would feel odd and would probably not be used in it's current state.
There were several things we wanted to implement and more we felt needed to change for our own purposes but did not want to impose these on yourselves without you buying into it as an upgrade/downgrade would be near impossible.
It quickly became apparent that the idea of creating additional form classes for things like emailing was getting unruly. Below is a list of some of the basic things we needed to handle:
Trying to handle all these scenarios was quickly getting out of control and wanted a simpler idea that we could build upon.
This very quickly became a must and could not be done as is.
We wanted to simplify the codebase as much as possible and allow the functionality to reside in our own apps codebase that would maximise the potential.
At some point this would either need to be done or the project will stop in its tracks.
These are the main points but others exist.
We have stripped away the layers that allowed functionality to be provided like emailing and have been left with a single form model that on submit searches your codebase for hooks that will process the forms cleaned_data in what ever manner you feel fit. These you can enable and disable at a form level in the ui so you can choose to run one, two or all if you want.
Hooks are added to your project via a wagtailstreamforms_hooks.py
file. See the docs for an example.
We have provided the basic save submission hook which will always be available.
In addition to this to allow you to save the information that was in these additional form classes you can now define a model that will act as an extension to the form. See advanced settings for more info.
We made adding fields possible by replacing the FormField
model with a StreamField as will wagtail when they complete the work. This has many benefits like:
forms.ModelChoiceField
We are even saving files that get uploaded from form file fields along with the submission.
Fields are added to your project via a wagtailstreamforms_fields.py
file. See the docs for more info.
All of this meant alot of code came out of the project and with the use of hooks to add functionality and fields the project is much simpler to manage. Also with the help of the StreamField the UI is much more friendlier to look at.
Doing all this means it now has no dependency on wagtail.forms
so is more future proof.
The big downside of all this is due to the massive model refactor there was no way to migrate without lots of work and without loosing data from an older install. So we made sure that any attempt to install it over an existing migration would fail by resetting the migrations.
Unfortunately this means your existing wagtailstreamforms_
tables will need to be either removed/renamed and any migrations would also need to be removed if you did want to upgrade.
To install it via pip:
pip install wagtailstreamforms==3.0
or clone the repo on the 3-dev
branch and follow the readme to have a play with the example site in docker.
Docs are at http://wagtailstreamforms.readthedocs.io/
I decided install and test the new version and i have the next problem:
salahaddin@TulipanROG ~/Proyectos/Works/recipes/cms/cms master ↑1 cms ✔ 2293 15:29:02./manage.py migrate
/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
Operations to perform:
Apply all migrations: admin, auth, axes, contenttypes, core, home, robots, sessions, sites, taggit, wagtail_embed_videos, wagtail_feeds, wagtailadmin, wagtailcore, wagtaildocs, wagtailembeds, wagtailforms, wagtailimages, wagtailmenus, wagtailmetadata, wagtailredirects, wagtailsearch, wagtailsearchpromotions, wagtailstreamforms, wagtailusers
Running migrations:
No migrations to apply.
salahaddin@TulipanROG ~/Proyectos/Works/recipes/cms/cms master ↑1 cms ✔ 2294 15:29:10./manage.py runserver
/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
Performing system checks...
System check identified no issues (0 silenced).
May 19, 2018 - 15:29:21
Django version 2.0.5, using settings 'cms.settings.dev'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[19/May/2018 15:29:39] "GET /admin/settings/core/globalsettings/2/ HTTP/1.1" 200 5640
[19/May/2018 15:29:43] "GET /admin/wagtailmenus/flatmenu/ HTTP/1.1" 200 4239
[19/May/2018 15:29:43] "GET /static/wagtailmodeladmin/css/index.css HTTP/1.1" 200 2089
Internal Server Error: /admin/wagtailstreamforms/form/
Traceback (most recent call last):
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: no existe la relación «wagtailstreamforms_form»
LINE 1: SELECT COUNT(*) AS "__count" FROM "wagtailstreamforms_form"
^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/views/decorators/cache.py", line 31, in _cache_controlled
response = viewfunc(request, *args, **kw)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/admin/urls/__init__.py", line 102, in wrapper
return view_func(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/admin/decorators.py", line 34, in decorated_view
return view_func(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/contrib/modeladmin/options.py", line 315, in index_view
return view_class.as_view(**kwargs)(request)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/utils/decorators.py", line 62, in _wrapper
return bound_func(*args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/utils/decorators.py", line 58, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/contrib/modeladmin/views.py", line 248, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/utils/decorators.py", line 62, in _wrapper
return bound_func(*args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/utils/decorators.py", line 58, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/contrib/modeladmin/views.py", line 68, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, *args, **kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/views/generic/base.py", line 150, in get
context = self.get_context_data(**kwargs)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/wagtail/contrib/modeladmin/views.py", line 616, in get_context_data
all_count = self.get_base_queryset().count()
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/models/query.py", line 387, in count
return self.query.get_count(using=self.db)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/models/sql/query.py", line 491, in get_count
number = obj.get_aggregation(using, ['__count'])['__count']
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/models/sql/query.py", line 476, in get_aggregation
result = compiler.execute_sql(SINGLE)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1066, in execute_sql
cursor.execute(sql, params)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 164, in execute
return self._record(self.cursor.execute, sql, params)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/debug_toolbar/panels/sql/tracking.py", line 106, in _record
return method(sql, params)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
return super().execute(sql, params)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: no existe la relación «wagtailstreamforms_form»
LINE 1: SELECT COUNT(*) AS "__count" FROM "wagtailstreamforms_form"
^
[19/May/2018 15:29:45] "GET /admin/wagtailstreamforms/form/ HTTP/1.1" 500 23235
^C% salahaddin@TulipanROG ~/Proyectos/Works/recipes/cms/cms master ↑1 cms ✔ 2295 15:29:54./manage.py makemigrations
/home/salahaddin/Proyectos/Works/recipes/cms/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
""")
No changes detected
As you can see there is no changes or new migrations in this version, but i get a problem with tables, that's because i used the previous version before.
There is any solution for this problem?
I have an issue with the package migrations changes.
After a fresh install of wagtailstreamforms I get this..
Migrations for 'wagtailstreamforms':
env/lib/python3.6/site-packages/wagtailstreamforms/migrations/0012_auto_20180315_1532.py
- Alter field field_type on formfield
Steps to recreate..
pip install wagtailstreamforms
python manage.py makemigrations --check
The functionality seems to be fine, however it does bring up some errors when I run tests against my site.
Hi, we are using wagtailstreamforms in our project and we really like it. Recently, we encountered an issue where we were not able to set links as "nofollow" rel. https://github.com/wagtail/wagtail/issues/4474#issuecomment-474430048 This answer solved our issue but for this to run we needed wagtail 2.5 and wagtailstreamforms doesn't support 2.5 yet. So, I would like to know when you are planning to support wagtail 2.5?
Thanks
try:
return BaseForm.objects.get_subclass(pk=pk)
except self.model.DoesNotExist:
raise Http404(_("No BaseForm found matching the query"))
I tried to append classes with a decorator as suggested here https://stackoverflow.com/a/18962481
which means defining a filter
from django import template
register = template.Library()
@register.filter(name='addcss')
def addcss(value, arg):
css_classes = value.field.widget.attrs.get('class', None).split(' ')
if css_classes and arg not in css_classes:
css_classes = '%s %s' % (css_classes, arg)
return value.as_widget(attrs={'class': css_classes})
```
and applying it
{% load myfilters %}
{{ form.non_field_errors }}ended up changing the filter to:
@register.filter(name='addCls')
def addCls(field, arg):
css_classes = field.css_classes(extra_classes=arg)
return field.as_widget(attrs={'class': css_classes})
after reading a bit into django's BoundField code (https://docs.djangoproject.com/en/1.11/_modules/django/forms/boundfield/)
specifically the css_classes
method, and it worked.
I think this should be customizable via the GUI. Am i missing something?
PS: same should apply for extra attributes in general, i think.
PS2:
ended up doing something like this:
@register.simple_tag(name="richerField")
def richerField(field, **kwargs):
extra_classes = kwargs.get('class', '')
css_classes = field.css_classes(extra_classes=extra_classes)
placeholder = kwargs.get('placeholder', '')
attrs = {
'class': css_classes,
'placeholder': placeholder,
}
return field.as_widget(attrs=attrs)
for the template tag
and this in the field template:
{% richerField field class="custom-class" placeholder=field.help_text %}
When django 2 and wagtail 2 are released do last checks and publish
I was checking on docs but did not see any information file upload field. Could you help me please how can I limit file upload size and file extensions limited?
https://github.com/wagtail/wagtail/blob/master/wagtail/contrib/forms/forms.py#L80
remember to handle any migrations of existing data
formsubmission_set
Due to wagtails first hatch and the work on their forms module scheduled this year, it's not decided yet if this will be released on PyPi. Currently it's being developed for our own internal use.
This will not install over an old version as the migrations were all binned due to it being re-written. None of the old tables now exist with the exception of the FormSubmission.
The only way currently to get this on an existing install is to:
wagtailstreamforms_*
django_migrations
table alsothen go from there.
http://wagtailstreamforms.readthedocs.io/en/v3-dev/#backwards-compatibility
To install it via pip:
pip install -e git+https://github.com/AccentDesign/wagtailstreamforms.git@3-dev#egg=wagtailstreamforms
or clone the repo on the 3-dev
branch and follow the readme to have a play with the example site in docker.
Docs are at http://wagtailstreamforms.readthedocs.io/en/v3-dev/
I'd appreciate the ability to add a field's help_text as a placeholder using a filter similar to {{ form.name|addcss:'full' }}
The ability to duplicate a form, including all data for form fields.
This will allow more control to default layout of the form fields without the need to redefine template code. Such as a multi column form
Please comment below or +1's etc do give us an idea on priorities.
Please add any extra things that are not listed.
I was reviewing this package and i saw some code lines that could be a problem with the next wagtail
release version: some imports for example.
Have you thought update this package for the next version?
Outstanding
dig into to see why this is maybe because no title field - guess
as in wagtails page serve method:
https://github.com/wagtail/wagtail/blob/master/wagtail/wagtailforms/models.py#L241
is it needed?
should it be order=-1 to ensure its first etc
Hi,
I am creating form field which requires Row and Column as in Google's Forms of Multiple Choice Grid.
Specifing Rows as listblock of charfields doesn't show in submission form. However choices which defined by Columns shows because as widget which is set to RadioButtons.
What to do to show Row names too?
Hello!
I tried installing the package and checking things out and when I try to select some forms in the wagtail admin menu I get the following error:
TemplateDoesNotExist at /cmsadmin/wagtailstreamforms/basicform/
modeladmin/wagtailstreamforms/basicform/index.html, modeladmin/wagtailstreamforms/index.html, modeladmin/index.html
Request Method: GET
Request URL: http://localhost:32776/cmsadmin/wagtailstreamforms/basicform/
Django Version: 1.11.6
Exception Type: TemplateDoesNotExist
Exception Value:
modeladmin/wagtailstreamforms/basicform/index.html, modeladmin/wagtailstreamforms/index.html, modeladmin/index.html
Exception Location: /usr/local/lib/python3.5/dist-packages/django/template/loader.py in select_template, line 53
Python Executable: /usr/bin/python3
Python Version: 3.5.2
Python Path:
['/usr/local/bin',
'/app/website/surehire',
'/app/website/surehire/apps',
'/usr/lib/python35.zip',
'/usr/lib/python3.5',
'/usr/lib/python3.5/plat-x86_64-linux-gnu',
'/usr/lib/python3.5/lib-dynload',
'/usr/local/lib/python3.5/dist-packages',
'/usr/lib/python3/dist-packages',
'/app/website/surehire/surehire',
'/app/website/surehire']
Server time: Thu, 26 Oct 2017 15:46:35 -0600
I don't see any admin templates in the package either so I'm just wondering where those are supposed to come from.
Hi there,
I'm currently working on a project that requires some smart handling of forms to gather various visitor feedback.
Those forms often have to change depending on the content they will be linked to.
Anyway, this is how I ended up here but I'm now struggling to decide if I should use https://github.com/noripyt/wagtail-flexible-forms which seems way more "alpha-ish" than this project but on the other hand, seems to be considered the "official" way.
Could you give me your feeling about this?
Thanks!
Right now wagtailstreamforms
can add fielfield to let user to upload files.
If the size is small, the file is <_io.BytesIO object at 0x7f6afc2a88e0>
If the size is big, the file is <tempfile._TemporaryFileWrapper object at 0x7f71500e9da0>
When uploading big file (5 MB PDF file), I would get this error.
File "/home/vagrant/.virtualenvs/michael/lib/python3.6/site-packages/wagtailstreamforms/wagtailstreamforms_hooks.py", line 16, in save_form_submission_data
submission_data = deepcopy(form.cleaned_data)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 150, in deepcopy
y = copier(x, memo)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 240, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 180, in deepcopy
y = _reconstruct(x, memo, *rv)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 280, in _reconstruct
state = deepcopy(state, memo)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 150, in deepcopy
y = copier(x, memo)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 240, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/copy.py", line 169, in deepcopy
rv = reductor(4)
File "/home/vagrant/.virtualenvs/besttransport/lib/python3.6/tempfile.py", line 483, in func_wrapper
return func(*args, **kwargs)
TypeError: cannot serialize '_io.BufferedRandom' object
I can write custom hooks deal with this problem but I have no good way to disable built-in hook method without creating new process_form
method.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.