post form in django, get blank screen, broken or bug? - python

I've created a form in django which works fine on desktop browsers, but on mobile browsers when the form submits it just displays a blank screen (doesn't even load the title or an error), am I missing something?
If there's no way to make it work using post, how could I submit a form to locations/<zip code> or use get locations/?zip_code=<zip code>? (I'm a django noob, sorry)
here's the relevant code:
template:
<form action="" method="post">
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
form.py:
class ZipForm(forms.Form):
zip_code = forms.CharField(max_length=10)
views.py:
def zip(request):
if request.method == "POST":
form = ZipForm(request.POST)
if form.is_valid():
zip_code = form.cleaned_data['zip_code']
## get result
return render_to_response("zip.html",{
'title':'Closest Locations',
'results' : results,
'form' : form,
})
else:
form = ZipForm()
return render_to_response("zip.html", {
'form' : form,
'title' : 'Find Locations',
})
url.py:
url(r'^locations/$', 'app.views.zip'),
I wish there was a decent debugger for developing on mobile phones, ugh.

If the form is valid then you do all this fancy stuff... but you forgot to handle the case where the form isn't valid.

Related

Avoiding page refresh when a form is used in Django

I have a very basic Django view:
def myview(request):
if request.method == 'POST':
if 'button1' in request.POST:
form1 = form = myForm(request.POST)
# check whether it's valid:
if form.is_valid():
profile = form.save()
profile.user = request.user
profile.save()
messages.success(request, f"Success")
return HttpResponseRedirect(request.path_info)
else:
form = myForm()
return render(request,
"main/mytemplate.html",
context={"form":form})
And its template:
<form method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form %}
<button name="button1" type="submit" class="btn btn-primary">SUBMIT</button>
</form>
Everything works here, when this form is used, some data is saved on my DB. What i would like to change, though, is the page reload after the form is used.
When the Submit button is hit, the page will be refreshed. Since it makes the navigation way slower, i would like to have the view not refreshing the page each time the form is used.
Is it possible to accomplish this in Django? For example, instead of refreshing the page, i would like to only load part of it, or to have a 'Reload' icon while the view is doing its work.
I'm pretty new to Ajax, so i don't know how to get started on this.

Django Form request not saving data to db

I am using a django form in atemplate to save data entered to database.
In my view after the request is made, the response is redirected correctly but the data is not saved to db.
I might be missing something. but am unable to find it even after a lot of debugging.
here is what has been done so far:
views.py:
from .models import testmodel
def testview(request):
if request.method== 'POST':
form=MapForm(request.POST)
if form.is_valid():
test1=request.POST.get('t1')
print meaningid1
test2=request.POST.get('t2')
print meaningid2
pobj=testmodel(test1=test1,test2=test2)
pobj.save()
return HttpResponse('Successful')
after this the response message "Successful" is seen
from template:
<form action="/testview/" method="post"> {% csrf_token %}
{{form.as_p}}
<input type="text" name="t1" value='' id='t1'/> <br><br><br>
<input type="text" name="t2" value='' id='t2'/><br>
<input type="submit" value="Submit" />
</form>
from forms.py:
from .models import testmodel
class MapForm(forms.ModelForm):
class Meta:
model = testmodel
fields = ['test1','test2']
after the data is entered in form it is going to page /testview and showing message on page. but from backend data is not been saved to db.
Can some one suggest what could be done
Thanks
In python, indentation matters.
def testview(request):
if request.method== 'POST':
form=MapForm(request.POST)
if form.is_valid():
test1=request.POST.get('t1')
print meaningid1
test2=request.POST.get('t2')
print meaningid2
pobj=testmodel(test1=test1,test2=test2)
pobj.save()
return HttpResponse('Successful')
In the above code 'Successful' will be displayed regardless of whether the form is actually successful or not. You need to push your return statement four spaces to the right, and you also need to add an else clause which handles the situation where the form is not valid. Typically that is just to display the form again (with form errors which wil be displayed for you automatically is you use form.as_p or form.as_table)

Django: View Tests Passing but Form Not Working in Page?

I have a page with two forms: a SearchForm and a QuickAddForm. Processing two forms on the same page in Django is not easy, and I'm spent the past two or three days trying to get it to work. I have several unittests that I've been using: a test for each form to make sure it's displaying on the page, a test that a submission of a valid search to the searchform returns the correct results, and three tests for the quickadd form testing that 1) a submission of valid fields results in a new Entry saving to the database; 2) that after an entry is saved, the form redirects to the same page; and 3) that the success message is displayed on that page. For example:
def test_quick_add_form_saves_entry(self):
self.client.post('/editor/', {'quickadd_pre-hw' : 'كلمة'}, follow=True)
self.assertEqual(Entry.objects.count(), 1)
After a lot of work (and helped greatly by the answers and comments on this page: [Proper way to handle multiple forms on one page in Django). I finally got the form working, so that the submitted entry was successfully saved in the database and was redirecting after post. Yay!
Except ... When I open up the page in a browser and try to enter a new Entry, it's clear that it's doing no such thing. You fill out the forms and hit "Save" and ... nothing happens. The page doesn't reload, and the entry isn't added to the database. But the tests (like the one above) testing those very features are passing. (It was at this point that I added the test for the success message, which, at least, has the decency to be failing.) The searchform is working.
I don't know what could possibly be preventing the quickadd form from functioning. Also, I don't understand how the tests could be passing, when the form is not working. What's going on???
Here's the code (Python3, Django1.8 - slightly simplified for clarity):
editor.html
<form id="id_searchform" role="form" method="POST" action="/editor/">
{% csrf_token %}
{{ searchform.as_p }}
<button type="submit" class="btn btn-primary btn-lg"
name="{{searchform.prefix}}">Search</button>
</form>
...
<h1>New entry</h1>
<form id="id_quick_add_form" method="POST" action='/editor/' class="post-form">
{% csrf_token %}
{{ quickaddform.as_p }}
<button type="submit" class="save btn btn-primary"
name='{{quickaddform.prefix}}'>Save</button>
</form>
views.py
def _get_form(request, formcls, prefix):
data = request.POST if prefix in next(iter(request.POST.keys())) else None
return formcls(data, prefix=prefix)
def editor_home_page(request):
if request.method == 'POST':
searchform = _get_form(request, SearchForm, 'searchform_pre')
quickaddform = _get_form(request, QuickAddForm, 'quickadd_pre')
if searchform.is_bound and searchform.is_valid():
query = searchform.cleaned_data['searchterm']
results = Entry.objects.filter(bare_hw__icontains=query)
return render(request, 'dict/editor.html', {
'query' : query,
'results' : results,
'searchform' : searchform,
'quickaddform' : quickaddform,
})
elif quickaddform.is_bound and quickaddform.is_valid():
hw = quickaddform.cleaned_data['hw']
e = Entry.objects.create(hw=hw)
messages.success(request, "Entry %s successfully created." % e.hw)
return redirect('/editor/', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre'),
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
else:
return render(request, 'dict/editor.html', {
'searchform': SearchForm(prefix='searchform_pre'),
'quickaddform': QuickAddForm(prefix='quickadd_pre')
})
forms.py
class SearchForm(Form):
searchterm = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'English | العربية',
'class' : 'form-control input-lg',
}),
required=True)
class QuickAddForm(Form):
hw = forms.CharField(
max_length=100,
widget=forms.TextInput(attrs={
'placeholder': 'ex: مَضْروب',
'class' : 'form-control',
}),
required=True)

How to post to a view in django from a django template?

Heres the scenario:
I have a email subscriber/un-subscriber app. I am stuck up in the un-subscribing a user part. The user is given a link, which if he/she follows will be able to un-subscribe. The link is typically a view, in the following format:
r^'/unsub_view/(?P<user_id>\w+)/$'
So, when the user follows this links he/she is doing a GET request on the view unsub_view with a parameter user_id. So I have coded up my view as:
def unsub_view(request, user_id):
if request.method == 'GET':
### Do some DB lookup to determine if it is a valid user or not
if user_is_valid:
return direct_to_template(request, '/app/unsub.html', {'user': user})
Now when a valid user is doing the GET, a confirmation dialogue is shown, along with a button. If he/she clicks on the button, I want the template to post the 'user' to the same view, thus the unsub_view also has this piece of code:
if request.method == 'POST':
if user_is_subscribed:
#Unsubscribe the user.
else:
#Show error meessage.
My question is how can I have the button in my template to post to this view ? I have looked around but I got POST-ing to a .php or .asp
Please help.
Note: If there is a better workflow idea, I am also open to that, so please do suggest if there is one.
In the template unsub.html rendering the form with the button, you should pass the url of your view using the reverse method
from django.code.urlresolvers import reverse
def unsub_view(request, viewid):
if request.method == 'POST':
if user_is_subscribed:
#Unsubscribe the user.
submit_url = reverse('unsub_view', viewid)
return direct_to_template(request, '/app/unsub.html', {'user': user, 'submit_url'})
else:
#Show error meessage.
in your template you can then render the form like follows :
...
<form method='post' action='{{ submit_url }}'>
{% csrf_token %}
<input type="hidden" value="{{ user_id }}" name="user_id" />
<input type="submit" value="unsubscribe"/>
</form>
...
Django also has a full framework dedicated to form modeling and rendering. You could take advantage of that to generate the form.

Edit/Add objects using the same django form

I already used the answer to this question, but for some reason I'm not getting a good result.
I'm trying to use the same template for my edit form and my add form. Here's my urls.py:
url(r'^app/student/new/$', 'edit_student', {}, 'student_new'),
url(r'^app/student/edit/(?P<id>\d+)/$', 'edit_student', {}, 'student_edit'),
And my views.py:
def edit_student(request, id=None, template_name='student_edit_template.html'):
if id:
t = "Edit"
student = get_object_or_404(Student, pk=id)
if student.teacher != request.user:
raise HttpResponseForbidden()
else:
t = "Add"
student = Student(teacher=request.user)
if request.POST:
form = StudentForm(request.POST, instance=student)
if form.is_valid():
form.save()
# If the save was successful, redirect to another page
redirect_url = reverse(student_save_success)
return HttpResponseRedirect(redirect_url)
else:
form = StudentForm(instance=student)
return render_to_response(template_name, {
'form': form,
't': t,
}, context_instance=RequestContext(request))
And my forms.py:
class StudentForm(ModelForm):
class Meta:
model = Student
exclude = ('teacher',)
And finally my template student_edit_template.html:
<h1>{{ t }} Student</h1>
<form action="/app/student/edit/{{ student.id }}" method="post"> {% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
For some reason, this is throwing a 404:
Page not found (404)
Request Method: POST
Request URL: http://192.168.1.3:5678/app/student/edit/
I'm probably missing something easy here, but at this point I need another set of eyes on it at the very least.
Thanks in advance!
You're getting the 404 because /student/edit/ requires an id at the tail end otherwise there's no route, and when you're coming from /student/new/ you don't have an id yet. Create a route and view for /student/edit/ and put logic in there to handle the case for when you're creating a record on POST.

Categories

Resources