Using two submit buttons to save django inlineformset as draft - django

I have an inlineformset that works. I have attempted to add a second submit button, that when clicked will check that a particular field in each inline form has been filled out i.e. this field becomes a required filed only when the second submit button is clicked.
The problem is that when I click this second submit button the validation errors don't appear and the form just seems to submit anyway. I think the issue is within my view, within form_valid. I'm not sure what I need to return when if form.is_valid() fails.
I'm teaching myself to code, so any help or direction is much appreciated.
Forms.py
class response_form_draft(forms.ModelForm):
class Meta:
name = response
exclude = ['id_question','order']
def __init__(self, *args, **kwargs):
super(response_form_draft, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_show_labels = False
class response_form_final(forms.ModelForm):
class Meta:
name = response
exclude = ['id_question','order']
def __init__(self, *args, **kwargs):
super(response_form_final, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_show_labels = False
def clean(self):
data = self.cleaned_data
resp = data['response']
if resp == "":
raise forms.ValidationError(('must not be blank'))
checklist_formset_draft = inlineformset_factory(checklist, response,
form = response_form_draft,
extra=0, can_delete=False,
widgets={'comments': forms.Textarea(attrs={'cols': 7, 'rows': 3,
'style':'resize:none'})
})
checklist_formset_final = inlineformset_factory(checklist, response,
form = response_form_final,
extra=0, can_delete=False,
widgets={'comments': forms.Textarea(attrs={'cols': 7, 'rows': 3,
'style':'resize:none'}),
'response': forms.TextInput(attrs={'required':True})
})
Views.py
class ChecklistUpdateView(LoginRequiredMixin, UpdateView):
login_url = '/user/login'
model = checklist
form_class = checklist_form
success_url = reverse_lazy('checklist:checklist_list')
def get_context_data(self, **kwargs):
data = super(ChecklistUpdateView, self).get_context_data(**kwargs)
if self.request.POST:
if 'complete' in self.request.POST:
print("complete")
data['question'] = checklist_formset_final(self.request.POST, instance=self.object)
else:
print("draft")
data['question'] = checklist_formset_draft(self.request.POST, instance=self.object)
else:
data['question'] = checklist_formset_draft(instance=self.object)
return data
def form_valid(self, form):
context = self.get_context_data()
question = context['question']
with transaction.atomic():
self.object = form.save(commit=False)
self.object.last_edit_by = str(self.request.user)
self.object.last_edit_date = timezone.now()
if question.is_valid():
question.instance = self.object
question.save()
return super(ChecklistUpdateView, self).form_valid(form)
HTML template
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
<form method="post">
{% csrf_token %}
<h1>{{ object.id_template.title }}</h1>
{{ form.errors }}
{{ form.entity|as_crispy_field }}
{{ form.date_created.as_hidden }}
{{ form.created_by.as_hidden }}
{{ form.id_template.as_hidden }}
{{ form.status.as_hidden }}
<div class="card">
<table id="table_id" class="table">
<tbody>
{{ question.management_form }}
{% for form in question.forms %}
{{ formset.errors }}
{{ form.non_field_errors }}
{% if forloop.first %}
<thead class="thead-dark">
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
<th></th>
</tr>
</thead>
{% endif %}
<tr class="{% cycle row1 row2 %} formset_row">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{% if field.label == "Question" %}
<p>{{ form.question.value }}</p>
{{ field.as_hidden }}
{% elif field.label == "Response" %}
{{ field.as_hidden }}
<button id="Yes.{{ forloop.parentloop.counter0 }}" row="{{ forloop.parentloop.counter0 }}" class="ans {{ forloop.parentloop.counter0 }} btn btn-dark right">Yes</button>
<button id="No.{{ forloop.parentloop.counter0 }}" row="{{ forloop.parentloop.counter0 }}" class="ans {{ forloop.parentloop.counter0 }} btn btn-dark right">No</button>
<button id="N/a.{{ forloop.parentloop.counter0 }}" row="{{ forloop.parentloop.counter0 }}" class="ans {{ forloop.parentloop.counter0 }} btn btn-dark right">N/a</button>
{% else %}
{{ field|as_crispy_field }}
{% endif %}
</td>
{% endfor %}
<td> </td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{{ form.comments|as_crispy_field }}
{{ form.audit|as_crispy_field }}
<div class="form-submit-row" id="submit-row">
<input class="btn btn-dark right" name="draft "type="submit" value="Save draft">
<input class="btn btn-dark right" name="complete" type="submit" value="Complete">
Delete
</div>
</form>
<br><br>
</div>

form_valid is activated when your form is valid. In your classview django automatically check validation for your checklist_form without validating formset. you can add custom validation in your form_valid and form_invalid, but i would go another way. i would put formset inside your base form (checklist_form)
something like that:
class checklist_form(forms.ModelForm):
def __init__(*args, **kwargs):
self.question= kwargs.pop("question")
super()__.init__(*args, **kwargs)
def clean(self):
cleaned_data = super().clean()
if not self.question.is_valid():
self.add_error(None, "Have some formset errors")
return cleaned_data
now form will be valid only if formset is also valid. And then in your ChecklistUpdateView i would put creation of formset into get_form_kwargs
def get_form_kwargs(self):
data = super().get_form_kwargs()
if self.request.POST:
if 'complete' in self.request.POST:
data['question'] = checklist_formset_final(self.request.POST, instance=self.object)
else:
data['question'] = checklist_formset_draft(self.request.POST, instance=self.object)
else:
data['question'] = checklist_formset_draft(instance=self.object)
return data
After that in your html template you will need to use form.question instead of question

Related

multiple forms in one step, Django Wizard form

I am trying to create 2 Model Forms in on Step, one of them is Modelformset, does someone did this before, it will be very helpful.
I am using Django 2 in my project.
Thank you.
class Post(models.Model):
main_image = models.ImageField('main_image', upload_to='main_images/', blank=True, null=True)
def __str__(self):
return str(self.pk)
class PostImages(models.Model):
image = models.ImageField('Foto', upload_to='post_images/', blank=True, null=True)
post = models.ForeignKey(Post,related_name='myposts',on_delete=models.CASCADE, null=True)
def __str__(self):
return str(self.pk)
my Forms.py
Here I am Trying to create two forms, first one is main_image and the other is formsetfield in one step. that works but i can not get the instance of my formset so i can not save it.
class step3Form(forms.ModelForm):
main_image = forms.FileField(widget=forms.FileInput(attrs={'class': 'custom-control'}), required=True, label=_('Hauptbild:'))
formsetfield = modelformset_factory(PostImages, ImageForm, can_delete=True)
class Meta:
model = Post
fields = ('main_image',)
def __init__(self, *args, **kwargs):
super(step3Form, self).__init__(*args, **kwargs)
views.py
what schuld I do here to get the instance of my Formset? in order to save it!
class PostCreateView(LoginRequiredMixin, SessionWizardView):
instance = None
form_list = [PostForm, PostFormSecondStep, step3Form, step4Form]
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'media'))
def get_template_names(self):
return [TEMPLATES[self.steps.current]]
def get_form_instance(self, step):
if self.instance is None:
self.instance = Post()
return self.instance
def done(self, form_list, form_dict, **kwargs):
form_data_dict = self.get_all_cleaned_data()
result = {}
self.instance.author = self.request.user.profile
form_list[2].save()
self.instance.save()
form_data = [form.cleaned_data for form in form_list]
return redirect('post_app:post_create_page')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
html
<form method="post" id="msform" enctype="multipart/form-data">
{% csrf_token %}
{{ wizard.management_form }}
{% if wizard.form.forms %}
{% for form in wizard.form.forms %}
{{ form }}
{% endfor %}
{% else %}
{% if wizard.form.non_field_errors %}
<ul>
{% for error in wizard.form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{{ wizard.form.main_image.label_tag }}
{{ wizard.form.main_image }}
{{ wizard.form.main_image.errors }}
{{ wizard.form.formsetfield.errors }}
<div id="formset" data-formset-prefix="{{ wizard.form.formsetfield.prefix }}">
{{ wizard.form.formsetfield.management_form }}
<div data-formset-body>
{% for form in wizard.form.formsetfield %}
{{ form.non_field_errors }}
{{ form.errors }}
<div data-formset-form>
{{ form }}
<span class="p-2"><a class="cursor-pointer" data-formset-delete-button><i class="far fa-trash-alt"></i></a></span>
</div>
{% endfor %}
</div>
<input type="button" class="btn btn-outline-dark" value="Hinzufügen" data-formset-add>
</div>
{% endif %}
<button type="submit" id="submit_btn" class="action-button" name="button">Weiter</button>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" class="action-button" type="submit" value="{{ wizard.steps.first }}">Erster Schritt</button>
<button name="wizard_goto_step" id="back_btn" class="action-button" type="submit" value="{{ wizard.steps.prev }}">Zurück</button>
{% endif %}
</form>
try this in function based:
Forms.py
class step3Form(forms.ModelForm):
class Meta:
model = Post
fields = ('main_image',)
view.py
from django.forms import modelformset_factory
def create(request):
formset = modelformset_factory(
Post,
form=step3Form,
fields=('main_image'),
extra=1,
can_delete=True
)
if request.method == 'POST':
form = formset(request.POST, prefix='post')
if form.is_valid()
post = form.save(commit=False)
for row in post:
row.userID = request.user
row.save()
form.save()
context['form']=formset(queryset=Post.objects.none(), prefix='post')
return render(request, 'post/form.html',context=context)

How to update a post using form wizard in Django

I have created a multipage form using the form wizard from the form tools package and it works. I am trying to create and update view so that I can be able to update the created post.
I have tried using generic update view, this only display the page without the form. Then, I tried using the same code for the create view by using a get method but this seems not to work also.
I will appreciate it if someone can point me in the right direction. Thanks.
views.url
class FormWizardView(SessionWizardView):
template_name = "new_rental.html"
form_list = [NewRentalPropertyForm, NewContractForm]
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'images'))
def done(self, form_list, **kwargs):
rentalproperty_instance = RentalProperty()
contract_instance = Contract()
for form in form_list:
rentalproperty_instance = construct_instance(form, rentalproperty_instance)
contract_instance = construct_instance(form, contract_instance)
rentalproperty_instance.save()
contract_instance.rentalproperty = rentalproperty_instance
contract_instance.save()
return redirect('mini_rental:property_list')
class UpdateWizardView(SessionWizardView):
template_name = "update.html"
form_list = [NewRentalPropertyForm, NewContractForm]
file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'images'))
def done(self,pk, form_list, **kwargs):
rentalproperty_instance = RentalProperty.objects.get(pk=pk)
contract_instance = Contract()
for form in form_list:
rentalproperty_instance = construct_instance(form, rentalproperty_instance)
contract_instance = construct_instance(form, contract_instance)
rentalproperty_instance.save()
contract_instance.rentalproperty = rentalproperty_instance
contract_instance.save()
return redirect('mini_rental:property_list')
form. html
Update rental listing
{% load i18n %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form 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>
{% endblock body %}
urls.py
path('property_update/<int:pk>', UpdateWizardView.as_view(forms), name='property_update'),
path('new_rental/', FormWizardView.as_view(forms), name='new_rental'),

Validation errors not showing up

So I'm stuck on why validation errors aren't showing for this particular form. They are showing up fine on all my other forms, but not this one.
I can empirically see the validation at work because when office_street_address is none, the form is not saving. But the form.non_field_error doesn't seem to have any errors.
forms
class PremiumAgentForm(forms.ModelForm):
class Meta:
model = Agent
exclude = ['field1', 'field2', ...]
def __init__(self, *args, **kwargs):
super(PremiumAgentForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
visible.field.widget.attrs['class'] = 'form-control'
def clean(self):
cd = super(PremiumAgentForm, self).clean()
a = cd.get('office_street_address')
if a == None:
raise forms.ValidationError("Error")
return cd
html
<form class="row justify-content-center" enctype="multipart/form-data" method="post">
{% csrf_token %}
{% for error in form.non_field_errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
{% if form.non_field_errors %}
<p style="color: red">there are errors</p>
{% else %}
<p>no errors</p> # This is always displayed.
{% endif %}
<div class="col-sm-4">
{% for field in form %}
<div class="form-group pb-3">
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text|safe }}</small>
{% endif %}
</div>
{% endfor %}
<button class="button2"><span>Submit</span></button>
</div>
</form>
views.py
def edit_profile(request):
if request.method == 'POST':
form = PremiumAgentForm(request.POST, request.FILES, instance=agent)
if form.is_valid():
form.save()
return HttpResponseRedirect(request.META['HTTP_REFERER'])
else:
agent = get_object_or_404(Agent, pk=request.user.agent.pk)
form = PremiumAgentForm(instance=agent)
return render(request, 'edit_profile.html', {'form': form})
In your case, you keep the form if it is valid, and after that you do a redirect, even if the form is not valid. This should help:
if not form.is_valid():
return render(request, 'edit_profile.html', {'form': form})
form.save()

Django all-auth Form errors not displaying

I am using django-allauth and whenever I input a wrong password in login form,the page just reloads and doesn't show any error.This is my html code:
<form class="login" method="POST" action="{% url 'account_login' %}">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<span><b> {{error}} </b><span>
</div>
{% endfor %}
{% endfor %}
{% endif %}
{% csrf_token %}
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{ form.login }}
<label class="mdl-textfield__label" for="id_login">Username/Email:</label>
</div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{ form.password }}
<label class="mdl-textfield__label" for="id_password">Password</label>
</div>
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="id_remember">
{{form.remember}}<span class='mdl-checkbox__label 'align='left'>Remember me</span>
</label></br>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a><br/></br>
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--raised mdl-button--colored" type="submit">{% trans "Sign In" %}</button>
<br/>
<br/>
</form>
The form displays properly normally and submits normally,if the info input are correct.For sign-up form,the error messages show but it gives a weird one like '%(model_name)s with this %(field_label)s already exists.' if i try to input an email that already exists but for username it gives a normal A user with that username already exists.
This is the signup.html
<form class="signup" id="signup_form" method="post" action="{% url 'account_signup' %}">
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<span><b> {{error}} </b><span>
</div>
{% endfor %}
{% endfor %}
{% endif %}
{% csrf_token %}
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{ form.username }}
<label class="mdl-textfield__label" for="id_username">Username</label>
</div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{form.email}}
<label class="mdl-textfield__label" for="id_email">Email</label>
</div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{form.password1}}
<label class="mdl-textfield__label" for="id_password1">Password</label>
</div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
{{form.password2}}
<label class="mdl-textfield__label" for="id_password2">Password(again)</label>
</div>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}<br/>
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--raised mdl-button--colored" type="submit">{% trans "Sign Up" %}</button>
</form>
Signup View
class SignupView(RedirectAuthenticatedUserMixin, CloseableSignupMixin,
AjaxCapableProcessFormViewMixin, FormView):
template_name = "account/signup." + app_settings.TEMPLATE_EXTENSION
form_class = SignupForm
redirect_field_name = "next"
success_url = None
#sensitive_post_parameters_m
def dispatch(self, request, *args, **kwargs):
return super(SignupView, self).dispatch(request, *args, **kwargs)
def get_form_class(self):
return get_form_class(app_settings.FORMS, 'signup', self.form_class)
def get_success_url(self):
# Explicitly passed ?next= URL takes precedence
ret = (
get_next_redirect_url(
self.request,
self.redirect_field_name) or self.success_url)
return ret
def form_valid(self, form):
# By assigning the User to a property on the view, we allow subclasses
# of SignupView to access the newly created User instance
self.user = form.save(self.request)
return complete_signup(self.request, self.user,
app_settings.EMAIL_VERIFICATION,
self.get_success_url())
def get_context_data(self, **kwargs):
ret = super(SignupView, self).get_context_data(**kwargs)
form = ret['form']
email = self.request.session.get('account_verified_email')
if app_settings.SIGNUP_EMAIL_ENTER_TWICE:
email_keys = ['email1', 'email2']
else:
email_keys = ['email']
for email_key in email_keys:
form.fields[email_key].initial = email
login_url = passthrough_next_redirect_url(self.request,
reverse("account_login"),
self.redirect_field_name)
redirect_field_name = self.redirect_field_name
redirect_field_value = get_request_param(self.request,
redirect_field_name)
ret.update({"login_url": login_url,
"redirect_field_name": redirect_field_name,
"redirect_field_value": redirect_field_value})
return ret
signup = SignupView.as_view()
Login View
class LoginView(RedirectAuthenticatedUserMixin,
AjaxCapableProcessFormViewMixin,
FormView):
form_class = LoginForm
template_name = "account/login." + app_settings.TEMPLATE_EXTENSION
success_url = None
redirect_field_name = "next"
#sensitive_post_parameters_m
def dispatch(self, request, *args, **kwargs):
return super(LoginView, self).dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super(LoginView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_form_class(self):
return get_form_class(app_settings.FORMS, 'login', self.form_class)
def form_valid(self, form):
success_url = self.get_success_url()
try:
return form.login(self.request, redirect_url=success_url)
except ImmediateHttpResponse as e:
return e.response
def get_success_url(self):
# Explicitly passed ?next= URL takes precedence
ret = (get_next_redirect_url(
self.request,
self.redirect_field_name) or self.success_url)
return ret
def get_context_data(self, **kwargs):
ret = super(LoginView, self).get_context_data(**kwargs)
signup_url = passthrough_next_redirect_url(self.request,
reverse("account_signup"),
self.redirect_field_name)
redirect_field_value = get_request_param(self.request,
self.redirect_field_name)
site = get_current_site(self.request)
ret.update({"signup_url": signup_url,
"site": site,
"redirect_field_name": self.redirect_field_name,
"redirect_field_value": redirect_field_value})
return ret
login = LoginView.as_view()
if any one still having problem then you can use this one
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-error">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
Make sure to check for {{form.non_field_errors}} in addition to errors attached to specific fields.

haystack on existing template

How to implement working SearchView in existing views.py?
I already have CBV, and added in urls.py as /moderate and want to apply search form in it. but always got "Results No results found."
This is my /moderate page with 3 forms, using SearchView and piece of code from tutorial in template.
And this from /search page, with urls(r'^search/$', include('haystack.urls'))
urls.py
urlpatterns= [
url(r'^search/', include('haystack.urls')),
url(r'^moderate/', Moderate.as_view(), name='moderate'),
]
views.py
class Moderate(SearchView):
#method_decorator(staff_member_required)
def dispatch(self, *args, **kwargs):
return super(Moderate, self).dispatch(*args, **kwargs)
#model = Ad
template_name = 'adapp/ad_moderate.html'
#template_name = 'search/search.html'
paginator_class = DiggPaginator
paginate_by = 10
ad_type = None
ad_sub_type = None
def get_queryset(self):
qs = super(Moderate, self).get_queryset().filter(ad_type__isnull=False,
ad_sub_type__isnull=False)
return qs
def get_context_data(self, **kwargs):
context = super(Moderate, self).get_context_data(**kwargs)
context['filter'] = ModerateFilter(self.request.GET)
return context
# define method to recieve fields from form, and change data accordings
def post(self, request, *args, **kwargs):
selected = request.POST['selected']
record = Ad.objects.get(pk=int(selected))
form = ModerateForm(request.POST, instance=record)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('')
template/ad_moderate.html
{% extends 'base.html' %}
{% load i18n url_tags %}
{% block content %}
<div id="casing">
<div id="content">
{# filter form, to show only models with moderated=True #}
<form action="" method="get">
{{ filter.form.as_p }}
<input type="submit">
</form>
<h2>Search</h2>
{# search form right from tutorial #}
<form method="get" action="">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table>
{% if query %}
<h3>Results</h3>
{% for result in page.object_list %}
<p>
{{ result.object.title }}
</p>
{% empty %}
<p>No results found.</p>
{% endfor %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>
{% for object in filter %}
{# a lot of template tags and third form to change value of model #}
<form action="" method="POST">
{% csrf_token %}
<input type="radio" name="moderated" value="True">Accept
<br>
<input type="radio" name="moderated" value="False">Decline
<input type="hidden" value="{{ object.id }}"
name="selected">
<input class="btn" type="submit" value="moderate">
</form>
search_indexes.py
from .models import Ad
class AdIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
def get_model(self):
# my model, with one search should be
return Ad
templates/search/indexes/app/ad_text.txt
{{ object.title }}
{{ object.short_desc }}
{{ object.description }}
{{ object.experience }}
{{ object.skills }}
{{ object.name }}
{{ object.city }}
get_context_data():
context['search'] = SearchForm(self.request.GET).search()
Would solve a problem.
That means, I should create form and send return from .save() method, rather that django-like form instance.