Django Form Fields won't show in my template - python

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]

Related

How to print post data on the same web page?

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.

How to show many-to-many fields from form on on HTML form in Django

I couldn't get my input data to many-to-many field data via the HTML form. How to solve this?
This is my code:
models.py
class SetStaffSchedule(models.Model): # generated work for staffs by admins
schedule = models.ManyToManyField('Staff')
shift = models.DateTimeField("Shift")
detail = models.TextField("Task Detail", max_length=200)
def __str__(self):
return self.shift
def __str__(self):
return self.detail
forms.py
from django import forms
from attendance.models import SetStaffSchedule, Staff
class SetStaffScheduleForm(forms.ModelForm):
class Meta:
model = SetStaffSchedule
fields = ['schedule','shift', 'detail']
views.py
def schedules(request): # getting schedules for staffs' work
all_schedules = SetStaffSchedule.objects.all()
context = {
'all_schedules': all_schedules
}
return render(request, 'getschedule.html', context)
def post(request): # posting schedules for staffs' work
form = SetStaffScheduleForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save();
return redirect ('schedules')
return render(request, 'post_schedules.html', {"form": form})
post_schedules.html
{% csrf_token %}
{{ form.as_p }}
You need to handle the case where the request method is "GET" so that you can render the form without any validation being run. If the user then submits the form as a "POST" you should run the validation/saving
def create_staff_schedule(request): # posting schedules for staffs' work
if request.method == 'GET':
form = SetStaffScheduleForm()
else: #  POST
form = SetStaffScheduleForm(request.POST)
if form.is_valid():
form.save()
return redirect('schedules')
return render(request, 'post_schedules.html', {"form": form})
You need to also wrap the form in a form tag with the method set to "post"
<form method="post">
{% csrf_token %}
{{ form.as_p }}
</form>

Django: ModelForm and show data on the same url

I'm new to django and trying to create my first app and I think I might need some little help :)
I have a ModelForm on a site to submit and want to show the data on the same page. I'm having trouble to set up two functions on the same page, I think i might have to use a class and set it in urls.py but I'm not able to make it work :( the code looks like this:
forms.py:
from django import forms
from .models import Eintrag
class NameForm(forms.ModelForm):
class Meta:
model = Eintrag
fields = ['Anmeldung', 'Essen']
urls.py
from django.urls import path
from . import views
app_name = 'form'
urlpatterns = [
path('', views.get_name, name='form'),
]
views.py
from django.shortcuts import render
from django.utils import timezone
from django.contrib.auth.decorators import login_required
from .forms import NameForm
from .models import Eintrag
#login_required()
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
eintrag = form.save(commit=False)
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
eintrag.Name = request.user # Set the user object here
eintrag.pub_date = timezone.now() # Set the user object here
eintrag.save()
return render(request, 'form/name.html', {'form': form})
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'form/name.html', {'form': form})
def post_list(request):
posts = Eintrag.objects.all()
return render('form/post_list.html', {'posts': posts})
name.html
...
{% include "form/post_list.html" %}
<form action="/form/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
...
post_list.html
{% for post in posts %}
{{ post }}
{% endfor %}
So the problem is in urls.py only get_name is handled and I'm clueless how I should include post_list. I rather not want to use different url's, do I have to?
Thanks for any help and advice!
You don't need a separate URL or view for the list. Just include the queryset in the context of your get_name view.
posts = Eintrag.objects.all()
return render(request, 'form/name.html', {'form': form, 'posts': posts})
with [Class Based View] it would be better.
But with your view, you can send multiple data via context.
#login_required()
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
''' codes '''
eintrag.save()
return HttpResponseRedirect(request.path) # generate an empty form
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
posts = Eintrag.objects.all() # the queryset is here, and sent via context
return render(request, 'form/name.html', {'form': form,'posts':posts})
I your html remain the same, but keep your form action='' empty
{% include "form/post_list.html" %}
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>

Django form isn't rendering at all

I'm trying to make a non model form that just gets input text for a chat like interface.
views.py
def get_input(request):
if request.method == 'POST':
form = inputForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = inputForm()
return render(request, 'index.html', {'form': form})
def shelley_test(request):
form = inputForm()
return render(request, 'shelley_test.html')
form.py
from django import forms
class inputForm(forms.Form):
input = forms.CharField(label='input field')
shelley_test.html
<form action="/get_input/" method="get">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
please please help. I'm new at django and stumped :(
You're not sending the form to the context in your shelley_test method - see the difference in the render line compared with get_input.
Note though you don't need shelley_test at all: just go straight to /get_input/ to see the empty form.

How to save a data after user logs in DJANGO

After user logs in, user is able to submit a form. On click of submit button, data is being stored in DB, but how should I connect this information to the submitting user.
I would need the code as well as the structure of the new db
Kind of starting out in django.
Any help would be appreciated!!!
I have included user as foreign key in the CustomizeRequest model, but now how do i fill in this information?
Exact Scenario: After user log in, once he comes to contactUs.html, he submits a form which tells the number of travellers. This number is being stored in the DB. But now how do I connect each of these numbers to the submitted user?
models.py
class CustomizeRequest(models.Model):
user = models.ForeignKey(User)
travellers = models.CharField(max_length=2)
def __str__(self):
return self.travellers
contactUs.html
<form method="POST" class="form-horizontal">
{% csrf_token %}
<div class="btn-group" data-toggle="buttons">
{% for radio in crform.travellers %}
<label class="btn btn-default {% if radio.choice_label = '1' %}active{% endif %}" for="{{ radio.id_for_label }}">
{{ radio.choice_label }}
{{ radio.tag }}
</label>
{% endfor %}
</div>
<button type="submit" class="btn btn-default btn-block btn-warning">SUBMIT</button>
</form>
views.py
def contactUs(request):
if request.method=="POST":
form = CustomizeRequestForm(request.POST)
form.save()
else:
form = CustomizeRequestForm()
context_dict = {'form': form}
return render(request, 'tour/contactUs.html', context_dict)
Based on catavaran answer (with a check to see if the form is valid):
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
#login_required
def contactUs(request):
form = CustomizeRequestForm(data=request.POST or None)
if request.method == "POST":
if form.is_valid():
customize_request = form.save(commit=False)
customize_request.user = request.user
customize_request.save()
return redirect('.')
else:
pass # could add a notification here
context_dict = {'form': form}
return render(request, 'tour/contactUs.html', context_dict)
Logged user is available as request.user property. You can get the unsaved model instance using form.save(commit=False) trick, set the user field and then save the instance to database:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
#login_required
def contactUs(request):
if request.method == "POST":
form = CustomizeRequestForm(request.POST)
if form.is_valid():
customize_request = form.save(commit=False)
customize_request.user = request.user
customize_request.save()
return redirect('.')
else:
form = CustomizeRequestForm()
context_dict = {'form': form}
return render(request, 'tour/contactUs.html', context_dict)

Categories