In the Django documentation on Forms, it explains how to pass data to a new form you are creating.
For example
data = {'subject': 'hello',
'message': 'Hi there',
'sender': 'foo#example.com',
'cc_myself': True}
f = ContactForm(data)
But why would you ever want to do this? Isn't the whole point of creating a form to solicit new data? If you are putting in the data, why not just enter it directly into the model?
It's not the idea, the idea is to describe the Form API, generally we instantiate the format without passing data to render an empty form in the GET request, and with user's data after user submit the given form. You will write some code like that:
if request.method == "GET":
form = ContactForm()
elif request.method == "POST":
form = ContactForm(request.POST)
Because, as that same documentation says, the primary purpose of a form is for validation. So you pass the data to be validated, and the form determines the errors.
Related
I am a beginner to Django so I am trying to grasp the basic concepts...what happens
at the formset=OrderFormSet(request.POST,instance=customer)? Does the formset get filled with some request.POST data? Does it get sent to the server? Why is there the request.POST?
def createOrder(request, pk):
OrderFormSet = inlineformset_factory(Customer, Order, fields = ('product','status'), extra=10)
customer=Customer.objects.get(id=pk)
formset=OrderFormSet(queryset=Order.objects.none(),instance=customer)
if request.method=='POST':
formset=OrderFormSet(request.POST,instance=customer)
if formset.is_valid():
formset.save()
return redirect('/')
context={'formset':formset}
return render(request, 'accounts/order_form2.html',context)
Basically in your "formset" variable you begin with an empty queryset so we are in a case where we will append something to a queryset. If you get a POST request, your form is submitted and will be processed. This means the customer fills in the form and submits it via POST. So your "formset" variable will be assigned the submitted data that is contained in request.POST
You will then validate the submitted data using the is_valid() method. This method validates the data introduced in the forms and returns True. If the form is valid
From all the HTML books i've read, I know that POST should be used when changing, adding or removing from the database and when handling sensitive information like passwords. GET should be used when you just want to search through a database without making any changes. With that said, I am reading a book on Django and up until now, to handle forms, we did it like this:
def RegistrationFormView(request):
form = RegistrationForm()
if request.method == "POST": #if the user has clicked the 'submit' button on the form and is sending data
form = RegistrationForm(request.POST)
which makes sense. The book goes on to teach how to create a search page which searches through the database. For this, we use GET, which makes sense. This is the form:
class SearchForm(forms.Form):
query = forms.CharField(
label='Enter a keyword to search for',
widget=forms.TextInput(attrs={'size': 32})
)
But this is the view (and this is what confused me):
def search_page(request):
form = SearchForm()
bookmarks = []
show_results = False #Only show results if the user has searched something
if request.GET.has_key('query'): #check if the user submitted GET data
show_results = True #return results since the user has submitted GET data
query = request.GET['query'].strip()
if query:
form = SearchForm({'query' : query})
I want to clarify four things here.
1) Would it be exactly the same if I just did
if request.method == "GET":
instead of
if request.GET.has_key('query'):
2) in the line
if request.GET.has_key('query'):
according to the Djangobook, it says "has_key Returns True or False, designating whether request.GET or request.POST has the given key." Now, what exactly is a 'key'? Is a key a field in the form, and
if request.GET.has_key('query'):
checks to see if the user has filled out the formField which is called 'query'?
3) Am I allowed to call form.is_valid() when the method is GET? Because what I was thinking was doing
form = SearchForm(request.GET)
if form.is_valid():
query = form.cleaned_data['query']
Is that allowed?
4) why does the book do
if query:
after
query = request.GET['query'].strip()
? Doesn't the line
if request.GET.has_key('query'):
already verify that the 'query' field is filled in?
No. if request.method == "GET": is in no way equivalent to if request.GET.has_key('query'):
request.GET and request.POST are dictionary subclasses and has_key is part of the built-in dictionary interface http://docs.python.org/2/library/stdtypes.html#dict.has_key however it is deprecated in favor of 'query' in request.GET.
Forms do not care about the request method or that there is a request at all. Forms validate dictionaries whatever the source might be.
In the case of ?query= or ?query=%20 the key query would evaluate to '' and ' ' which would both be False after running through strip(). if request.GET.has_key('query'): only checks that the key is present and does not look at the value.
I'm starting to learn django and started watching tutorials on how to create forms and i've seen a lot of places where the form is created like this.
def create(request):
if request.POST:
form = ArticleForm(request.POST)
if form.is_valid:
form.save()
else:
form = ArticleForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('create_article.html', args)
Now, assuming that I created a model called Article and then created an ArticleForm from that model, what exactly is going on here (in the code I provided above)? I understand the if form.is_valid: form.save() part, and according to what I read, request should always be the first parameter, but can someone explain what request as a parameter does and what the first two lines of the function are doing? And what exactly is going on in the else statement and after the else statement (the args part)?
EDIT: Also, suppose the Article model has a field called name = models.CharField(max_length=20), is there a way for me to get / access what the user entered for that particular section of the form? Suppose I want to get the name and see if the name already exists in my database, would there be a way for me to do that?
request.POST among other things (like the CSRF token value) contains all the data the user has entered in the form.
if request.POST
checks if the user actually validated the form, otherwise there is no POST data in the request.
form = ArticleForm(request.POST)
looks strange at first but when the user validates the form, the same page is loaded but the POST data is processed in the django form for data validation (like checking if a required field was left blank, etc…) in order to display errors in the form.
If there is no error (form.is_valid()) then the view program continues.
I hope you are familiar with HTTP methods like GET and POST.
request object represents a single request by any user agent. So it can be a request that's sent from browser from you when you browse a particular page or from a crawler from a search engine. Read more about request here
request.POST is an attribute of this request object, it's a QueryDict (much similar to a normal Python dict). It contains the HTTP POST parameters that are sent to your view.
In short in your example:
def create(request):
if request.POST: # check if the request is POST request and it contains any parameter
form = ArticleForm(request.POST) # then pass all those parameters to the form
if form.is_valid: # process the form to check if it's valid
form.save() # save the data if it's valid
else:
form = ArticleForm() # if not valid data, initialize an new / empty form
args = {} # create a dict to pass to the template
args.update(csrf(request)) # add the CSRF token
args['form'] = form # add the 'form' above to the 'args' dict
return render_to_response('create_article.html', args) # pass that dict to template
Not so sure why you have this example, normally I would do the last part like this:
def create(request):
.... your code ....
else:
form = ArticleForm()
return render(request, 'create_article.html', { form: form })
Hope it helps.
There are some mistakes in the code and it seems it's copy-pasted from a SO question. I would recommend going through the excellent Django documentation, especially the Django tutorial.
Your example should rather look like this example from the Django docs.
Here are some comments:
def create(request):
if request.POST:
form = ArticleForm(request.POST)
if form.is_valid:
form.save()
# after successful POST
# we want to redirect to a different page here
else:
form = ArticleForm()
args = {}
# you really don't need the following necessarily
# just use `{% csrf_token %}` inside the form in your template
args.update(csrf(request))
args['form'] = form
# using just `render` like in the example linked to above is more modern
return render_to_response('create_article.html', args)
I am trying to create a helper function that validates forms. If the form is valid, then I will create an object in the database. The function takes in three arguments, the request, the form, and the model.
def form_validate(request, form, model):
form = form(request.POST)
print form
if form.is_valid():
print "the form is valid"
# create object using valid form
else:
print "the form is not valid"
# send back items
print form.errors.items()
If the form is valid, I want to use the form data to create a new model. How would I do that? I have tried to look at the Django docs(https://docs.djangoproject.com/en/dev/topics/forms/) but I cannot find the answer.
As David Wolever said, using ModelForms is the obvious way.
You could also pass the cleaned_data dictionary to the model constructor (assuming the fields are the same):
def form_validate(request, form, model):
form = form(request.POST)
print form
if form.is_valid():
print "the form is valid"
obj = model(**form.cleaned_data)
obj.save()
else:
# etc
However, ModelForms are really the easiest way of doing this, but you might be interested in reading Django's source to see how they work.
You'll likely want to look at ModelForms: https://docs.djangoproject.com/en/dev/topics/forms/modelforms/
Still new to python and django, though learning ;-)
I have a view that is intended to display a form with contact information. After succesfully processing the form and saving/creating the object, I want to display the same view again (to add another contact) but with a message added saying the previous contact information was successfully saved.
From Django return redirect() with parameters I learned that the way to redirect to a view with a passed parameter is to simply call the view again and display the response.
My view starts as follows:
def addabentry(request, entrytype, messages=[]):
""" Presents form to create a company listing, then enters company into database"""
After postback and successfully saving the data, I call the view again as follows:
messages = ["%s %s has been added." % (entrytype, entry.name)]
response = addabentry(request, entrytype=entrytype, messages=messages)
return HttpResponse(response)
However, the form on the second go-round seems to be bound with the previous data, presumably because the POST parameter is still in the request object I pass to the view.
Is there a way to unbind the form for the second time around? Or, as is more likely, is there a better way of doing what I want? Do I need to use request.sessions as mentioned in the referenced SO question?
Thanks for your help!
W.
You need messages framework.
i think you may be making things a lot more complicated than they need to.
from the basic form example in the docs
def contact(request):
message = ''
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
# instead of redirecting here, create a new blank form, and add a message
form = ContactForm()
message = "contact successfully created"
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
'message': message,
})