This is my working FormWizard that I made by following this and this
views.py
from django.shortcuts import render
from django.template import RequestContext
from django.http import HttpResponseRedirect
from formtools.wizard.views import SessionWizardView
# Create your views here.
def index(request):
return render(request, 'wizardApp/index.html')
class ContactWizard(SessionWizardView):
template_name = "wizardApp/contact_form.html"
def done(self, form_list, **kwargs):
process_form_data(form_list)
return HttpResponseRedirect('../home')
def process_form_data(form_list):
form_data = [form.cleaned_data for form in form_list]
print(form_data[0]['subject'])
print(form_data[0]['info1'])
print(form_data[0]['info2'])
print(form_data[1]['sender'])
print(form_data[1]['info1'])
print(form_data[1]['info2'])
print(form_data[2]['message'])
print(form_data[2]['info1'])
print(form_data[2]['info2'])
return form_data
urls.py
from django.conf.urls import url
from wizardApp import views
from wizardApp.forms import ContactForm1, ContactForm2, ContactForm3
from wizardApp.views import ContactWizard
app_name = 'wizardApp'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^home/$', views.index, name='index'),
url(r'^admin/', admin.site.urls),
url(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2, ContactForm3])),
]
forms.py
from django import forms
class ContactForm1(forms.Form):
subject = forms.CharField(max_length=100)
info1 = forms.CharField(max_length=100)
info2 = forms.CharField(max_length=100)
class ContactForm2(forms.Form):
sender = forms.EmailField()
info1 = forms.CharField(max_length=100)
info2 = forms.CharField(max_length=100)
class ContactForm3(forms.Form):
info1 = forms.CharField(max_length=100)
info2 = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
contact_form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
{{ wizard.form.media }}
</head>
<body>
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="/contact/" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">first step</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">prev step</button>
{% endif %}
<input type="submit" value="submit"/>
</form>
</body>
</html>
I am having a lot of trouble understanding how customizing each step of the form works. There is very little help out there for this unfortunately. I saw this post about creating multiple templates and that kind of helps, but my main disconnect is on how i create those templates and how they are implemented in each step.
In a normal form i can do something like this
<form novalidate="novalidate" autocomplete="on" method="POST">
{% csrf_token %}
<div class="form-horizontal">
<div class="form-left">
{{form.first_name}}
{{form.first_name.errors}}
</div>
<div class="form-right">
{{form.last_name}}
{{form.last_name.errors}}
</div>
</div>
<div>
{{form.email}}
{{form.email.errors}}
</div>
<div>
<input type="submit" value="Submit">
</div>
</form>
How do i access each individual field? Where i can add in html and other bits to help with general styling? How should i go about making one of these for each steps? Should i basically be copy and pasting the html and everything into other "templates"? How do i call each template for each step?
Thanks!
Hope you figured it out. For the sake of anyone who runs into this, this is how I solved this. I replaced {{ wizard.form }} with a for loop to manually render the inputs:
<form action="/contact/" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{% for field in wizard.form %}
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<span class="message">{{ field.errors }}</span>
{% endfor %}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">first step</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">prev step</button>
{% endif %}
<input type="submit" value="submit"/>
You can create a template for each of your forms and then associate it to its corresponding form as described in the docs or if you want each form to use the same template, all you need to do is set your template_name attribute in your ContactWizard class:
class ContactWizard(SessionWizardView):
template_name = "contact_form.html"
Related
forms.py
from django import forms
from tinymce import TinyMCE
from .models import Article
class TinyMCEWidget(TinyMCE):
def use_required_attribute(self, *args):
return False
class PostForm(forms.ModelForm):
content = forms.CharField(
widget=TinyMCEWidget(
attrs={'required': False, 'cols': 30, 'rows': 10}
)
)
class Meta:
model = Article
fields = ('title', 'major', 'semester', 'book', 'unit', 'content')
article_form.html
{% extends "base.html" %}
{% load static %}
{% load tailwind_filters %}
{% block title %}Create{% endblock title %}
{% block content %}
{{ form.media }}
<div class="row form-error">
<div class="column" id="content">
<form method="post" action='' enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<input class="button" type="submit" value="Save">
</form>
</div>
</div>
{% endblock %}
I using TinyMCE to implement a rich text editor.
when I reload the page it gives me this:
AttributeError at /article/new/
'CSSContainer' object has no attribute 'tinymce'
I just want to use crispy forms on all fields and exclude the content field from crispy forms.
I did some google and I found this
[simpleisbetterthancomplex.com]
then I modified my code to:
{% extends "base.html" %}
{% load static %}
{% load tailwind_filters %}
{% block title %}Create{% endblock title %}
{% block content %}
{{ form.media }}
<div class="row form-error">
<div class="column" id="content">
<form method="post" action='' enctype="multipart/form-data">
{% csrf_token %}
{{ form.title|as_crispy_field }}
{{ form.major|as_crispy_field }}
{{ form.semester|as_crispy_field }}
{{ form.book|as_crispy_field }}
{{ form.unit|as_crispy_field }}
{{ form.content }}
<input class="button" type="submit" value="Save">
</form>
</div>
</div>
{% endblock %}
My Views Page:
from django.shortcuts import render
from django.http import HttpResponse
from formtools.wizard.views import SessionWizardView
from .forms import ContactForm1,ContactForm2,ContactForm3
class ContactWizard(SessionWizardView):
template_name = 'contact.html'
form_list = [ContactForm1,ContactForm2]
def done(self, form_list, **kwargs):
form_data = process_form_data(form_list)
return render_to_response('done.html', {'form_data': form_data})
def process_form_data(form_list):
form_data = [form.cleaned_data for form in form_list]
return form_data
My form page:
from django import forms
class ContactForm1(forms.Form):enter code here
subject = forms.CharField(max_length=100)
class ContactForm2(forms.Form):
sender = forms.EmailField()
class ContactForm3(forms.Form):
message = forms.CharField(widget=forms.Textarea)
I am new to Django I am working with the wizard forms but this wizard form not showing the if statement of the wizard multiform. Please help me to solve the wizard form.
Html Page
{% load i18n %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
{% for field in form %}
{{field.error}}
{% endfor %}
<form action="/contact/" method="post">
{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
{{ wizard.form.management_form }}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>
</form>
Help to find out the problem in wizard multiform
So, i want to get the checked checkboxes items ids as a list and show them on another page. But when i get to that specific page i get the value 'None' instead of the list of ids. What could go wrong? I tried some different versions from another questions already posted on the site, but the result was the same.
Here is the code:
models.py:
from django.db import models
class afirmatii(models.Model):
text = models.CharField(max_length = 250)
def __str__(self):
return self.text
views.py:
def exam(request):
if request.method == 'POST':
checks = request.POST.get('selected[]')
request.session['checks2'] = checks
context = {
'title' : 'Title1',
'aff': afirmatii.objects.order_by('id')
}
return render(request, 'pages/exam.html', context)
def result(request):
checks = request.session.get('checks2')
context = {
'title' : 'Title2',
'checks': checks
}
return render(request, 'pages/result.html', context)
exam.html:
{% extends "./base.html" %}
{% block content %}
<div class="text-break">
<form action="{% url 'result' %}" method="POST">
{% csrf_token %}
{% for q in aff %}
<div class="border mb-3 rounded-sm bg-light p-2">
<div class="custom-control custom-checkbox checkbox-info">
<input type="checkbox" class="custom-control-input" id="{{ q.id }}" name = "selected[]">
<label class="custom-control-label" for="{{ q.id }}" name = 'selected[]'> {{ q.text }} </label>
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-md btn-outline-info">Next</button>
</form>
</div>
{% endblock content %}
result.html:
{% extends "./base.html" %}
{% block content %}
<body>
<div class="text-center">
<p class="pb-5"> {{ checks }} </p><br>
<div class="row">
<div class="col">
Home
</div>
<div class="col">
Learn more
</div>
</div>
</div>
</body>
{% endblock content %}
You can try use FORMSETS A formsets is a layer of abstraction to work with multiple forms on the same page.
You can paint the list of questions according to records in the table and get ids (or other fields) of the marked answers
forms.py
class ExamForm(forms.Form):
checkbox = forms.BooleanField(required=False)
id = forms.CharField(widget=forms.HiddenInput)
text = forms.CharField(widget=forms.HiddenInput)
views.py
from django.shortcuts import render
from django.forms import formset_factory
from .forms import *
def exam(request):
aff = afirmatii.objects.order_by('id')
exam_formset = formset_factory(ExamForm, extra=0)
formset = exam_formset(initial=[{'id': x.id, 'text': x.text} for x in aff])
checks = []
if request.method == 'POST':
formset = exam_formset(request.POST)
if formset.is_valid():
for form in formset.forms:
if form.cleaned_data.get('checkbox', None):
checks.append(form.cleaned_data)
context = {
'formset': formset,
'checks': checks,
}
return render(request, 'pages/exam.html', context)
exam.html
{% if not checks %}
<h1>Exam:</h1>
<form action="{% url 'exam' %}" method="POST">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset.forms %}
<div class="form-group">
{{ form.checkbox }}
{{ form.text.value }}
{{ form.id }}
{{ form.text }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% else %}
<h1>Results:</h1>
{% for check in checks %}
<p>{{ check.id }} {{ check.text }}</p>
{% endfor %}
{% endif %}
This is my forms:
class signup_form(forms.ModelForm):
bio = forms.TextInput()
class Meta:
model = User
fields = ['username',
'password',
'first_name',
'last_name',
'email',
'date_joined']
And This one is my template page:
urlpatterns = [
......
url(r'^profile/(?P<username>[\w\-]+)/$', user_profile, name='user_profile'),
]
And this is signup template page:
{% extends parent_template|default:"tick/base_tick.html" %}
{% block title %}
{{ block.super }} ---> Sign Up HERE!!
{% endblock %}
{% block content %}
<div>
<div>
<form action="{% url 'user_profile' username={{ form.username }} %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Create User</button>
</form>
</div>
</div>
{% endblock %}
As you can see in the 'action' part of the form i want to access to the 'username' field of 'form' but i can't and the Django get me some error.
What Should I do?
Edit: This is the Error
Value of a field is accessed by form.field_name.value. Use can update your code by below code
<form action="{% url 'user_profile' username=from.username.value %}" method="post">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Create User</button>
</form>
If I have a django form, where I want it to provide a bootstrap error input (<input type="text" id="inputError">) to show an error instead of the bullet-list {{ form.title.error }}, how would I go about doing this? Right now I have:
{% if UF.title.errors %}
{{ UF.title }}
{{ UF.title.errors.as_text }}
{% else %}
{{ UF.title }}
{% endif %}
but instead of having UF.title in the first error, I would rather have UF.title but with the ERROR> how would I go about doing this?
You should use django-bootstrap3.
It does exactly what you want.
{% load bootstrap3 %}
{# Display a form #}
<form action="/url/to/submit/" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Submit
</button>
{% endbuttons %}
</form>
Here's what I do for my code:
<div class="form-group {% if form.username.errors %}has-error{% endif %}">
{{ form.username }}
{% if form.username.errors %}
<span class="help-block">{{ form.username.errors.0 }}</span>
{% endif %}
</div>
And my forms.py looks like:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(label='Username', max_length=32, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'form-control'}))