Open source feedback management system based on the Django framework. You can easily and flexibly embed any feedback form for your site. When the form is submitted you receive an email message containing the form data
Install package
pip install git+git://github.com/shoker174/django-simple-feedback.git
Create (or use) your own application for your feedback forms, for example custom_feedback
Configure your setting file:
FEEDBACK_ADMIN_EXTRA_CLASS = {'all': 'my-class'}
FEEDBACK_ADMIN_EXTRA_CSS = {'all': ['css/admin/common.css']}
Simple settings configuration:
# django email settings if they does not exist
DEFAULT_FROM_EMAIL = 'no-reply@mysite.com'
MANAGERS = [
('websupport', 'websupport+mysite@mycomany.com'),
]
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # for local testing
# feedback settings
INSTALLED_APPS += ['feedback', '<PROJECT_ROOT>.custom_feedback']
FEEDBACK_FORMS = {
'my_form': '<PROJECT_ROOT>.custom_feedback.forms.MyForm',
}
FEEDBACK_FORMS_NAMES = {
'default': '-- default --',
'my_form': 'My form name',
}
FEEDBACK_PREFIX_KEY_FIELDS = True
Add urlpattern to main urls.py:
urlpatterns = [
...
url(r'^feedback/', include('feedback.urls')),
...
]
Create your custom form in directory according to FEEDBACK_FORMS settings. For example in dir <PROJECT_ROOT>.custom_feedback.forms
from feedback.forms import BaseFeedbackForm
class CallForm(BaseFeedbackForm):
name = forms.CharField()
email = forms.EmailField()
phone = forms.CharField()
Call the form in the html template according FEEDBACK_FORMS settings
{% load feedback_tags %}
...
<!--noindex-->
{% show_feedback 'my_form' %}
<!--/noindex-->
Any feedback form include three states (and accordingly three templates):
Apply migrations and run local server
python manage.py migrate feedback
python manage.py runserver
Create and configure recipients email adresses and mailing list for your custom form in admin.
Pay attention to the next mailing list fields:
Name: {{ name }}
E-mail: {{ email }}
Phone: {{ phone }}
Configure is done!
To customize any feedback template, stick to the following template structure:
For example, when the "my_form" is rendered, the following priority applies:
The following structure is most userfull:
Default form contains javascript from {{ form.media }}
. If your customize templates we recomended instead of {{ form.media }}
include script in your base template footer:
<script type="text/javascript" src="https://github.com/redsolution/django-simple-feedback/raw/master/static/feedback/js/feedback.js"></script>
Or copy file content in your main.js file
About form customization:
To display form fields in the basic order, use default field output.
feedback.html:
{% load feedback_tags %}
<form>
...
{% for field in form.hidden_fields %}{{ field }}{% endfor %}
{% for field in form.visible_fields %}
{% show_field %}
{% endfor %}
...
</form>
In this example, hidden fields are rendered first, and then visible fields are rendered.
To separate fields into different groups:
forms.py:
from feedback.forms import BaseFeedbackForm
class CallForm(BaseFeedbackForm):
name = forms.CharField(widget=forms.TextInput(attrs={'data-set': 1}))
email = forms.EmailField(widget=forms.TextInput(attrs={'data-set': 2}))
phone = forms.CharField(widget=forms.TextInput(attrs={'data-set': 1}))
In this example we need to separate fields in two groups: "name" and "phone" in first group and "email" in second group.
feedback.html:
{% load feedback_tags %}
<form>
...
{% for field in form.hidden_fields %}{{ field }}{% endfor %}
<div class="form__row">
<div class="form__col">
{% for field in form %}
{% show_field field set 1 %}
{% endfor %}
</div>
<div class="form__col">
{% for field in form %}
{% show_field field set 2 %}
{% endfor %}
</div>
</div>
...
</form>
Field rendering is associated with code duplication. To avoid this, use the template tag {% show_field %}
.
Tag gets two parameters: "field" and "set" (optional). Rendered template get context and two additional varibles
field.html
<label {{ attrs }} {% if field.errors %}class="error"{% endif %}>
<span>{{ field.label }}</span>
{{ field }}
</label>
We can combine of field.name
and input_type
to identify any field:
{% if input_type == 'hidden' %}
{{ field }}
{% elif input_type == 'select' %}
<div class="{{ attrs.class }}{% if field.errors %} error{% endif %}">
<label>
<select required name="{{ field.html_name }}" id="id_{{ field.html_name }}">
{% for value, name in field.field.choices %}
<option {% if field.value|equal:value %}selected{% endif %} value="{{ value }}">{{ name }}</option>
{% endfor %}
</select>
{% if field.label %}<span>{{ field.label }}</span>{% endif %}
</label>
</div>
{% elif field.name == 'captcha' %}
{{ field }}
{% else %}
<div class="{{ attrs.class }}{% if field.errors %} error{% endif %}">
<label>
<span>{{ field.label }}</span>
{{ field }}
</label>
</div>
{% endif %}
Administrative interface: to connect the HTML-editor to the "success message" field, install django_tinymce
package (tested for version 2.6.0)
pip install django_tinymce==2.6.0
If you need additional protection, easy integration with Google reCaptcha v2. Package is available here:
pip install git+git://github.com/oldroute/django-nocaptcha-recaptcha.git