I am trying to print the POST data from django form on my webpage, right under my form. I am able to print it by HttpResponse on a different page, but I want it on the same page when the user presses submit button.
Views.py
from django.views.generic import TemplateView
from django.shortcuts import render
from django import forms
from django.http import HttpResponseRedirect, HttpResponse
from home.forms import HomeForm
def home(request):
def get(request):
form = HomeForm()
return render(request, 'home/home.html', {'form':form})
if request.method=='GET':
response=get(request)
return response
elif request.method == 'POST':
form = HomeForm(request.POST)
if form.is_valid():
text = HomeForm('post')
return HttpResponse('post')
else:
form = HomeForm()
return render(request, 'home/home.html', {'form':form})
Forms.py
from django import forms
class HomeForm(forms.Form):
post = forms.CharField( widget= forms.TextInput() )
Html template
<div class="container">
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit" class="btn btn-danger">
</form>
<h2>{{ text }}</h2>
</div>
I want the post field input to be displayed in the 'text' mentioned in the h2 tag of the webpage as soon as the user presses the submit button, and not on a separate page like HttpResponse does.
You have three options to get this thing done :
First is, you redirect the form on submit to the same page and pass the request.POST.DATA in context and then you can easily display it.
Like :
def home(request):
def get(request):
form = HomeForm()
return render(request, 'home/home.html', {'form':form})
if request.method=='GET':
response=get(request)
return response
elif request.method == 'POST':
form = HomeForm(request.POST)
if form.is_valid():
text = HomeForm('post')
# return HttpResponse('post')
context = {'text' : text, 'form' : form,}
return render(request, 'home/home.html', context)
else:
form = HomeForm()
return render(request, 'home/home.html', {'form':form})
Second Option is To display itself in the form the initial values from the Model :
form = HomeForm(initial = {'text' : modelsFile.Model.object}) # models.ModelName.text
Third Option is to use JavaScript and JQuery for realtime display of data.
That would be complex but good to do, you can search for how to display form data realtime in JS on google.
Thank you.
Related
my views.py file i just try to update form data form dashboard so i'm not getting what's going wrong to the code can someone please help me to solve
def addpost(request):
if request.user.is_authenticated:
if request.method == 'POST':
forms = addpostForm(request.POST)
if is_valid():
forms.save()
forms = addpostForm()
else:
forms = addpostForm()
return render(request, 'addpost.html', {'form': forms})
else:
return HttpResponseRedirect('login')
addpost.html file
<form action ='' method='POST'>
{% csrf_token %}
{{form.as_p}}
<input type='submit' class='btn btn-success btn-sm' value ='Add' >
<input type='submit' class='btn btn-danger btn-sm' value ='Cancel' >
</form>
my forms.py
class addpostForm(forms.ModelForm):
class Meta:
model = post
fields = ['title','desc']
labels ={'title':'Title','desc':'Description'}
widgets = {'title':forms.TextInput(attrs={"class":'form-control'}),'desc':forms.Textarea(attrs={"class":'form-control'}),}
Your method did not return a HTTP response in case of a GET request. You should unindent the else and thus construct a new form in case of a GET request and render the page.
For a successful POST request, you normally redirect to a view (that can be the same view), to implement the Post/Redirect/Get architectural pattern [wiki].
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
#login_required
def addpost(request):
if request.method == 'POST':
forms = addpostForm(request.POST, request.FILES)
if is_valid():
forms.save()
return redirect('name-of-some-view')
else:
forms = addpostForm()
return render(request, 'addpost.html', {'form':forms})
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
I am rendering a dropdown which displays a list of integers. This is the only field in the form/view. Once that form is submitted, the integer selected should be passed to the URL of the next view which is rendered on submission of the previous form.
I am getting a 404 when I attempt this.
Here is what I am currently trying:
forms.py
#this is the dropdown field
class ManifestDropDown(forms.Form):
reference = forms.ModelChoiceField(queryset=Orders.objects.values_list('reference', flat=True).distinct(),
empty_label=None)
views.py
#this is the view where the dropdown is submitted
def manifest_references(request):
if request.method == 'POST':
form = ManifestDropDown(request.POST)
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return render('manifest', reference_id=reference_id)
query_results = Orders.objects.all()
reference_list = ManifestDropDown()
context = {
'query_results': query_results,
'reference_list': reference_list,
}
return render(request, 'manifest_references.html', context)
#this is the view where the value should be displayed in the url
def manifest(request, reference_id):
form = CreateManifestForm(request.POST)
if request.method == "POST":
....
data = Manifests.objects.all().filter(reference__reference=reference_id)
form = CreateManifestForm(initial={
'reference': Orders.objects.get(reference=reference_id),
})
total_cases = Manifests.objects.filter(reference__reference=reference_id).aggregate(Sum('cases'))
context = {
'reference_id': reference_id,
'form': form,
'data': data,
'total_cases': total_cases['cases__sum'],
}
return render(request, 'manifest_readonly.html', context)
urls.py
#url which displays the manifest view above
url(r'^manifest/(?P<reference_id>\d+)/$', manifest, name='manifest'),
url(r'^references_manifests', manifest_references, name='references_manifests'),
manifest_references.html
<div class="container">
<br>
<br>
<br>
<form method="POST" action="references_manifests">
{% csrf_token %}
{{ reference_list }}
<button type="submit" class="btn btn-primary" name="button">Create Proforma</button>
</form>
</div>
To dynamically change the URL that you're actually submitting to, you would need to use JavaScript.
But an alternative is to submit back to the manifest_references view, then redirect from there to manifest. (Note, you should always be redirecting, not rendering, after a successful submission anyway. And no need to call form.save(), this isn't a modelform so there is nothing to save.)
def manifest_references(request):
if request.method == 'POST':
form = ManifestDropDown(request.POST)
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
return redirect('manifest', reference_id=reference_id)
You can do two things:
Call the manifest view directly.
Redirect the user to the manifest page.
The first one should be done like this:
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return manifest(request, reference_id)
The second one can be done like this:
if form.is_valid():
reference_id = form.cleaned_data.get('reference')
form.save()
return HttpResponseRedirect(reverse('manifest', reference_id = reference_id))
It doesn't really matter which one you do, although I would recomment redirecting the user to the correct page, because then a refresh will not resend the form the user has entered.
The form field won't show up in the browser. There is only the submit button showing up.
views.py code:
def vote(request, pk):
# check if request is post
if request.method == 'POST':
# create a form and populate it with data from request
form = forms.Vote(request.POST)
if form.is_valid():
fact = Fact.objects.get(pk=pk)
fact.votes += int(form.cleaned_data['vote'])
fact.save()
return HttpResponseRedirect(reverse(
'facts:detail',
args=(pk,)
))
else:
form = forms.Vote()
return render(request, 'facts/fact_detail.html', {'form': form})
template(fact_detail.html) code:
<form method='POST'>
{% csrf_token %}
{{ form }}
<input type="submit" value="vote" />
</form>
Form class(forms.py) code:
VOTE_CHOICES = [
(1, 'upvote'),
(0, 'downvote')
]
class Vote(forms.Form):
vote = forms.ChoiceField(choices=VOTE_CHOICES, widget=forms.RadioSelect())
In views.py for the vote method initialize the form variable locally, before passing it as a parameter.
def vote(request, pk):
form=""
//rest of the code//
return render(request, 'facts/fact_detail.html', {'form': form})
I recommend check generic editing views from django documentation I think it has the solution
[ https://docs.djangoproject.com/en/1.11/ref/class-based-views/generic-editing/#createview][1]
I have two views and I want to render those views to a single HTML page. I know how to render a single view to an HTML page but don't know how to render two views to a single HTML page.
views.py file
from django.shortcuts import render
from django.http import HttpResponse
from app.models import *
# Create your views here.
def collegeview(request):
if request.method == 'POST':
form = collegeform(requst.POST)
if form.is_valid():
form.save()
return HttpResponse('its done here')
else:
form = collegeform()
return render(request, 'about.html', {'form':form})
def schoolview(request):
if request.method == 'POST':
f = schoolform(requst.POST)
if f.is_valid():
f.save()
return HttpResponse('its done here')
else:
f = schoolform()
return render(request, 'about.html', {'f':f})
about.html
<html>
<body>
<h1>its working </h1>
first view <br>
<form action ='' method = 'POST'> {% csrf_token %}
{{form.as_p}}
<input type='submit' name='submit'>
</form>
2nd view<br>
<form action='' method='POST'> {% csrf_token %}
{{f.as_p}}
<input type='submit' name='submit'>
</form>
</body
</html>
single view working corresponding to the URL.
Not possible to render two different views to the same template, but you can add both the logics in a single view and then render both forms in that:
from django.shortcuts import render
from django.http import HttpResponse
from app.models import *
def institute_view(request):
f = schoolform(requst.POST or None)
form = collegeform(requst.POST or None)
if request.method == 'POST':
if form.is_valid():
form.save()
return HttpResponse('its done here')
elif f.is_valid():
f.save()
return HttpResponse('its done here')
else:
f = schoolform()
form = collegeform()
return render(request, 'about.html', {'f':f,'form':form})
By this method, both of your forms can be handled and whenever anyone of them gets posted the values will be saved accordingly.
at the moment, I try to make a search form for a small database.
This is a part of my models.py file:
from django.db import models
from django import forms
#...
class searchForm(forms.Form):
searchField = forms.CharField(max_length = 100)
#...
This is a part of my views.py file:
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
#...
def index(request):
template = loader.get_template('index.html')
context = Context({})
return HttpResponse(template.render(context))
def search(request):
if request.method == 'POST': # If the form has been submitted...
form = searchForm(request.POST)# A form bound to the POST data
if form.is_valid():
searchData = form.cleaned_data['searchField']
return HttpResponseRedirect('search.html') # Redirect after POST #???
else:
searchData = searchForm() # an unbound form
return render(request, 'search.html', {'form': form,}) #???
#...
This is a part of my index.html, where I want to implement that form:
<label for="Search">Search:</label>
<form action = "/search/" method = "post">
{% csrf_token %} {{ form.as_p }}
<input type = "submit" value = "Go" />
</form>
What I'm trying to do:
When I submit the form I would like to redirect to the result file called search.html, where for the beginning, is the input from the search textfield showing up. The link struktur should be something like that:
Landing-Page is: http://127.0.0.1:8000/
after a submitted form: http://127.0.0.1:8000/search.html
I think there might be an error in the search method, where I marked the lines with the '???'. The next problem is, that my search textfield isn't showing up.
Would be great, if someone could give me some advice.
thanks,
eljobso
First: The form isn't showing up because as you say, you want it to appear in index.html but the index view isn't passing any form to the template. Is in search view where you pass the form the template.
If you want the behavior described you should reorganize the code like this:
from django.shortcuts import render
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.template.context import RequestContext
#...
def index(request):
# this will only render the template with the form
searchData = searchForm() # an unbound form
return render_to_response(
'index.html',
context_instance=RequestContext(
request,{'form':searchData,}
)
)
def search(request):
if request.method == 'POST': # If the form has been submitted...
form = searchForm(request.POST)# A form bound to the POST data
if form.is_valid():
searchData = form.cleaned_data['searchField']
# do whatever you want to process the search with
# searchada, maybe populate some variable
return render_to_response(
'search.html',
context_instance=RequestContext(
request,{'form':searchData,} # maybe add here the populated variable with the search
)
)
else:
# request.GET, just show the unbound form
searchData = searchForm() # an unbound form
return render_to_response(
'search.html',
context_instance=RequestContext(
request,{'form':searchData,}
)
)
Then your templates should be:
index.html
<!-- is not good to have a label outside form -->
<label for="Search">Search:</label>
<form action = "/search/" method = "post">
{% csrf_token %} {{ form.as_p }}
<input type = "submit" value = "Go" />
</form>
And also that text included inside search.html template because there you render the form as well.
I hope this may bring some light!
With django FormView you can do that:
class Index(FormView):
form_class = SearchForm
template_name = 'index.html'
success_template = 'search.html' # I've added this attr
def form_valid(self, form): #That return a your form, validated
# Here you can do something with you VALID form.
searchData = form.cleaned_data['searchField']
context = dict(
searchData=searchData,
)
return render_to_response(self.success_template, {}, RequestContext(self.request, context))