I'm using class-based views (FormView) and I would like to keep a search keyword after form is submitted (POST request). I tried this in form_valid
method:
def form_valid(self, form):
self.initial['search'] = form.data['search']
...
but this will show it for all users. This is quite common solution on many web search forms (not to mention Google search) so I wonder how this can be done in Django.
Update: Mon 19 Jun 13:18:42 UTC 2017
Based on some answers below I'll have to rephrase my question.
I have a simple form with a few input fields, after a form is submitted it will query other sites to get the results based on a search term. I would like to store some results into database, mainly to produce stats, re-display the form with selected fields and show results.
Currently data resides on a class object and it's passed from POST to GET. This is not a good solution for obvious security reasons:
class SearchView(FormView):
...
data = dict()
def form_valid(self, form):
....
self.data['results'] = results
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['data'] = self.data.pop('results', None)
return context
Question:
What would be the best way to display form (with selected fields) and results on the same page, preferably without sessions or storing them in database between POST and GET.
Points that I already considered:
Don't redirect the user (render the template with the current context right away, while we still have the response object) - I don't like the fact that page refresh will re-submit the form.
Save the response into some key-value store like Redis and redirect the user to something like results/{result_id}, where we can retrieve the response from database to pre-fill the form with data and show the results - this sounds reasonable but I'll have to add another component just to pass the results from POST to GET.
Use GET for this type of form - my understanding was that we should use POST for data modification
Google and other similar searches use GET
params to pass query string
Exmaple:
test
https://www.google.ru/?q=test
So basically you need to use same approach and pass you search string as GET
param.
Here is general Idea
class SearchView(View):
success_url = reverse('result-view')
def get_success_url(self):
success_url = super().get_success_url()
return '{0}?search={1}'.format(success_url, self.form.cleaned_data['search'])
...
class ResultView(View):
def get(self, request, *args, **kwargs):
search_string = request.GET.get('search', '')
From your update: I think this is the process you are looking for:
You basically need to prevent the redirection when form is valid:
class SearchPageView(FormView):
def form_valid(self, form):
# do your things (3) here
context = self.get_context_data(form=form)
context['results'] = ['lorem', 'ipsum']
return self.render_to_response(context)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With