Django web application Taking user input and processing it - django

I am building a web application using django. I need to take a string input from the user and process it using a method I have written myself. How to achieve this in Django? Here are the things I need to do
Get User Input userinput = (string) On start page
Put this string as an argument in my method MyMethod(userinput) and Run it in the backend
Display what MyMethod() returns on another page.

I suggest that you start from django tutorial: https://docs.djangoproject.com/en/1.9/intro/tutorial01/
Basically, what you are going to need is form with one text field, HTML template that will render the form, view that will render HTML template with instance of a form when GET request arrives and call your MyMethod with value from form when POST request arrives and URL rule to call your view function on some URL.
Without additional data or any attempt to solve it and concrete problem you encounter - I can hardly offer more help.

You need to create a model with fields which you want to update by user input, then create a form based on this model. Then import this in a view and render it in a template
simple example:
forms.py:
class InputForm(forms.ModelForm):
class Meta:
model = YourModel
fields = ['fields_from_YourModel']
views.py:
from .forms import InputForm
def user_input(request):
input = CustomUser.objects.get(pk=request.user.pk)
if request.POST:
form = ProfileForm(request.POST, instance=input)
if form.is_valid:
form.save()
else:
form = ProfileForm()
return render(request, 'input.html', {'form':form})
Other steps more easier for beginner, you'll find examples in docs

Related

How to stage forms in Django?

I have form data that I gather in the views. What the user inputs will determine what the next form will be like. Should I create another view? If so, how do I pass on variables from one view to another? And should the separate view render a different html page?
Or is there a way to work in the same view that I gathered the data initially?
The view looks like this:
def admission(request):
if request.method == 'POST':
form = DeterminingForm(request.POST)
if form.is_valid():
selected_season = form.cleaned_data['season']
selected_batch = form.cleaned_data['batch']
form = DeterminingForm()
context = {
'form': form,
}
return render(request, 'admission.html', context)
I have used django-formtools Form wizard in the past for similar use cases. Subclassing out the SessionWizardView allows you to render multiple different forms using the same view and even the same template if you wish, however you can have a different template for each form. The variables for each form submission are stored in server-side sessions and the context can be extracted for each step in the process.
If the sequence of forms is different dependent on the answers in the previous form, you should be able to build up some logic within the process using the WizardView.get_form() method for each form step in the process. Hope this helps as a starter

Sending form to another view django

I am building a website and I want various views that will ask the user to request a quote from our page. I want to keep the code as DRY as possible so I am writing a view quote which will receive the quote requests from various views and, if there is a validation error redirect back to the page that made the request. I managed to solve this using the super bad practice 'global variables'. I need a better solution, I would like redirecting to respective view with the current form so I can iterate through the form.errors. Here is my code:
def send_quote(request):
form = Quote(request.POST)
if form.is_valid():
# do stuff when valid
return redirect('Support:thanks', name=name or None)
quote_for = request.POST['for_what']
global session_form
session_form = form
return redirect('Main:' + quote_for) # Here I would like to send form instead of storing in global variable`
You can use the HttpResponseRedirect function, and pass as argument the page that made the request.
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
All the META data is store on a dictionary, if you want to learn more check the documentation.
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
If you redirect to the referrer, form.errors will be empty, as redirection is always a GET request.
I can think of two solutions to your problem:
Submit forms asynchronously using JavaScript and so populate the errors
Make all the views containing the form support POST - one way to do this would be to create a base class that inherits from FormView
The second option is a typical way of handling forms in Django - you process both POST and GET inside the same view.
After two days of searching I finally found the answer. Instead of saving form in request.session I just save request.POST and then redirect. Here is the code:
def send_quote(request):
form = Quote(request.POST)
if form.is_valid():
# do stuff when valid
return redirect('Support:thanks', name=name or None)
quote_for = request.POST['for_what']
request.session['invalid_form'] = request.POST
return redirect('Main:endview')
def endview(request):
session_form = request.session.pop('invalid_form', False)
if session_form:
form = Quote(session_form)
# render template again with invalid form ;)
Now I can repeat this with all the views I want and just change the what_for input of each form to match the respective view (Like I intended).

Proper way to handle PUT requests Django with forms

I have a web app that allows users to edit previously submitted data.
I'm currently processing PUT requests by manually updating the data.
I would like to use my forms to validate input but I run into the issue of the other required fields.
For instance, if a user updates a date field and I validate it with my form, it errors out as I'm missing other required fields like name, location, etc since the form was designed to be filled out all at once.
What is the best way to use my forms to validate input but conditionally allow required fields if the request is a PUT or POST with model Forms.
If you're getting errors for missing fields you're not using the modelform correctly, sounds like you are not passing it the existing instance to work on.
You need to use a pattern like this:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
def my_view(request, obj_id):
my_object = get_object_or_404(MyModel, pk=obj_id)
update_form = MyModelForm(instance=my_object, data=request.PUT or None)
if update_form.is_valid():
return HttpResponse(status=204) # empty success response
else:
return render(...) # render update_form.errors somehow
And be sure to include the object id in the url that you send your PUT requests to

changing CreateView behavior to preview data before save in django

I have gotten Creatview() class based function to work. When the submit succeeds, it has already the data and shows the 'success' page.
I'd like to change this behavior this way: When the CreateView() succeeds, I'd like the data to get validated, but not saved. Instead of going to the success page, I'd like to use the DetailView() class to display the newly created instance, so the user can see how it is going to look like when the data is eventually saved..
Once the user is happy with the data displayed, the user can click "save" in which case the data is saved and the CreateView() is completed or the user can click "re-edit", and go back to the form to change the data and then be shown the newly created instance using DetailView() (and repeat until the user is satisfied). What is the best way to do this using class based views elegantly?
from django.views.generic.edit import CreateView
from restaurant.models import Restaurant
from restaurant.forms import RestaurantForm
import uuid
class RestaurantCreate(CreateView):
form_class = RestaurantForm
template_name = 'restaurant_form.html'
model = Restaurant
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.life_id = str(uuid.uuid1())
return super(RestaurantCreate, self).form_valid(form)
Also, I do know about Form wizard, but I do not have multiple page forms. Even if I ignore that, Form wizard's does not give the opportunity to preview data before the final save.
Edit: Related discussion on google groups, but no solutions
Here's what I should do:
Overwrite the form_valid method of the RestaurantCreate class and let the save the form in a session. From there you can redirect to another view , your RestaurentDetail view, there you would overwrite the get_object method by reading out the form out of the session and displaying what you need.
There I would also place a form with all fields hidden, except the submit/save button. The form will be populated by whatever was in your session. So when the user presses save a POST is done to another view RestaurantFinalCreate view for example. There you can just implement the CreateView as normal.
If you're uncertain which method to overwrite and how, take a look at: http://ccbv.co.uk/ it has been really helpful to me.
Also don't use super in the form_valid method of the RestaurantCreate view since that would trigger a save in the parent class ModelFormMixin.

Django: Form in base template

Hi Stackoverflow people,
In my Django project I created a form to register users. This forms can be called through a specific url -> view method. Once the user has filled in the form, presses submit, the same view method will be called and if form.is_valid() is true, then ... simply a standard form, nothing special.
Now, I would like to integrate this little form on every page, and therefore I would like to add it to the base template. I have read that I could populate the form variable through a context_processor, but could I define the process after the submission of the form?
I have created the context_processor.py (as below), added the context_processor to the TEMPLATE_CONTEXT_PROCESSOR dir in the settings (as described here):
from app.forms import Form
def registration_form(request):
return {
registration_form : Form()
}
First of all, the form variable won't be displayed.
And secondly, how do I manipulate the form submission?
I think I misunderstanding the context_processor of Django and would be more than happy about comments on the overall process.
Thank you!
how are you trying to access to form in your template? you probably don't want to use a function name as your dictionary key, maybe you want
return {
'registration_form': Form(),
}
not sure what you mean by manipulate the form submission, but i guess you'd need all the form processing logic in your context processor
if request.POST:
form = Form(request.POST)
# validate etc
instead of creating context processor, create template tag for the purpose and place the tag in base.html
for form submission and displaying errors use ajax, and front-end validations.