Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
i want the form to be prepopulated with data when i am editing the form
views.py
def edit_task(request, post_id):
post = Post.objects.get(id=post_id)
form = TaskForm(request.POST, instance=post)
if request.method == 'POST':
print(request.POST)
form = TaskForm(request.POST, instance=post)
if form.is_valid():
form.save()
return redirect('task')
context = {'form': form}
return render(request, 'List/add_task.html', context)
add_task.html
{% extends "List/Home.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
{% endblock content %}
Think carefully about how you instantiate forms. At the moment, you are using the same code TaskForm(request.POST, instance=post) for GET and POST requests:
def edit_task(request, post_id):
post = Post.objects.get(id=post_id)
form = TaskForm(request.POST, instance=post)
if request.method == 'POST':
print(request.POST)
form = TaskForm(request.POST, instance=post)
...
But request.POST is empty for GET requests, so you'll get an empty form with errors when you load the form with a GET request.
You can fix it by removing request.POST for GET requests
def edit_task(request, post_id):
post = Post.objects.get(id=post_id)
# Instantiate form without any data
form = TaskForm(instance=post)
if request.method == 'POST':
print(request.POST)
# replace the form for POST requests
form = TaskForm(request.POST, instance=post)
...
It might be clearer to use if...else instead of replacing the form:
def edit_task(request, post_id):
post = Post.objects.get(id=post_id)
if request.method == 'POST':
print(request.POST)
# instantiate form for POST requests
form = TaskForm(request.POST, instance=post)
...
else:
# instantiate the form for GET requests
form = TaskForm(instance=post)
context = {'form': form}
return render(request, 'List/add_task.html', context)
you can populate this form with data, providing initial
def edit_task(request, post_id):
post = Post.objects.get(id=post_id)
form = TaskForm(request.POST if request.POST else None, instance=post, initial={
'initial_field_name_1': 'initial_field_value_1',
...
'initial_field_name_n': 'initial_field_value_n',
})
if request.method == 'POST':
print(request.POST)
if form.is_valid():
form.save()
return redirect('task')
context = {'form': form}
return render(request, 'List/add_task.html', context)
Related
I'm a Django beginner and i have a little problem. I made a form for create the model FantaSquadra, and this works. Then I made a form to edit the model and when I press the submit button it doesn't do anything.
Can someone help me?
urls.py:
path('add/fantasquadra/', views.addFantaSquadra, name='creazione_fanta'),
path('edit/fantasquadra/<int:fantasquadra_id>/', views.editFantaSquadra, name='edit_fanta'),
views.py:
def addFantaSquadra(request):
elenco_fantasquadre = FantaSquadra.objects.all()
if request.method == "POST":
form = NewFantaSquadraForm(request.POST)
if form.is_valid():
fanta_item=form.save(commit=False)
fanta_item.save()
else:
form = NewFantaSquadraForm()
return render(request, 'sondaggio/fantasquadre.html', {'form': form})
def editFantaSquadra(request, fantasquadra_id):
item = get_object_or_404(FantaSquadra, pk=fantasquadra_id)
form = NewFantaSquadraForm(request.POST or None, instance=item)
elenco_fantasquadre = FantaSquadra.objects.all()
if form.is_valid():
form.save()
return render(request, 'sondaggio/fantasquadre.html', {'form': form})
forms.py:
class NewFantaSquadraForm(forms.ModelForm):
class Meta:
model = FantaSquadra
fields = ['nome_fantasquadra','proprietario']
fantasquadre.html
<html>
<h1>Scrivi il nome della tua fantasquadra</h1>
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Submit</button>
</form>
</html>
You have a link inside your button, for some reason. The link is taking priority over the button submission, so the data is never actually posted to the view.
Remove that <a> element.
I have a problem with AuthenticationForm(), when login and passwords are correct everything works correct, but when I want to cause an error with wrong password or login instead getting 'incorrect login or password' error, I get the following error page:
My views.py code:
def login_view(request):
if request.method == 'POST':
form =AuthenticationForm(data=request.POST)
if form.is_valid():
#log in the user
return redirect('Product_list')
else:
form = AuthenticationForm()
return render(request, 'account/login.html', {'form': form})
My template code:
{%block content%}
<form class="login-form" method="POST">
{%csrf_token%}
{{ form.as_p }}
<input type="submit" value="Logowanie">
</form>
<div id="signup">
<a href="http://127.0.0.1:8000/account/signup/">
Jeżeli nie masz jeszcze konta zarejestruj się: <input type="submit" value="Rejestracja">
</a>
</div>
{%endblock%}
In your view if the form is valid you return return redirect('Product_list') but is not valid you're not returning anything.
Try to change your code to:
def login_view(request):
if request.method == 'POST':
form =AuthenticationForm(data=request.POST)
if form.is_valid():
#log in the user
return redirect('Product_list')
return render(request, 'account/login.html', {'form': form})
else:
form = AuthenticationForm()
return render(request, 'account/login.html', {'form': form})
or even better
def login_view(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
#log in the user
return redirect('Product_list')
return render(request, 'account/login.html', {'form': form})
I am creating a contact form in django to send an email but the form is not displaying on the webpage. I think the issue may be because the form object may have never been passed to the context correctly, but I have no idea where it is going wrong. The code below is what I have so far.
from .forms import *
My Views
def email(request):
form = ContactForm()
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
email = form.cleaned_data['email']
first_name = form.cleaned_data['first_name']
message = form.cleaned_data['message']
try:
send_mail(first_name + ": " + subject, message, email,
['flavioandersites#gmail.com'])
except BadHeaderError:
return HttpResponse("Invalid Header.")
return redirect('thankyou')
return render(request, 'Index-App/contact.html', {'form': form})
My Form Class
class ContactForm(forms.Form):
subject = forms.CharField(required=True)
from_email = forms.EmailField(required=True)
first_name = forms.CharField(max_length=200, required=True)
message = forms.CharField(widget=forms.Textarea)
Urls
url(r'^contact/$', views.email, name='contact'),
My Template
{% block contact %}
<form method="POST" action="{% url 'Index-App:contact' %}">
{% csrf_token %}
{{ form }}
<input type="submit" class="btn-success" value="Send"/>
</form>
{% endblock %}
Because you are not instantiating your form when method is GET. Also, you need to change self param to request
Try the following:
def email(request): # pass request for your view param, not self
form = ContactForm() # You should instantiate your form for GET method
if request.method == 'POST':
form = ContactForm(request.POST)
# ...
return render(request, 'Index-App/contact.html', {'form': form})
The view that **renders** is
def codequestion(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/codequestion.html', {'question': question})
the view that is called on submission is
def codequestion_evaluate(request, question_id):
form = CodeForm()
print request.method
if request.method == 'POST':
form = CodeForm(request.POST)
if form.is_valid():
data = form.cleaned_data
return HttpResponse("Your code is %s" % data['solution'])
else:
return HttpResponse("not valid")
else:
return HttpResponse("Error")
class
from django import forms
class CodeForm(forms.Form):
solution = forms.CharField(widget=forms.Textarea)
template
<form action="{% url 'codequestion_evaluate' question.id %}" method="post">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Submit" />
</form>
I do not get the form field display in the HTML page, I can only see the submit button.
The view that is suppose to show the unfilled form doesn't create the form object at all. It should create a form object and pass it to the template, like this:
def codequestion(request, question_id):
question = Question.objects.get(pk=question_id)
form = CodeForm()
return render(request, 'polls/codequestion.html', {'question': question, 'form': form})
But better yet you should follow the pattern described in Django documentation. To do this you should:
Delete the codequestion. All actions (displaying the unfilled form, displaying a submitted form with errors, processing a correctly submitted form) will be handled by a single view.
Configure your url routing so codequestion_evaluate view handles the page showing the unfilled form.
Change codequestion_evaluate so it follows the pattern:
def codequestion_evaluate(request, question_id):
if request.method == 'POST':
form = CodeForm(request.POST)
if form.is_valid():
# The form has been submitted and is valid
# process the data and redirect to a "thank you" page
data = form.cleaned_data
return HttpResponseRedirect('/thanks/')
else:
# just display an empty form
form = CodeForm()
# you can optionally add 'question' if you need it in your template
question = Question.objects.get(pk=question_id)
return render(request, 'polls/codequestion.html', {'form': form, 'question': question})
form refers to a variable in your context data, since you haven't included it in the context data, it can't find it so there isn't anything to render, you need to include it.
def codequestion(request, question_id):
question = Question.objects.get(pk=question_id)
return render(request, 'polls/codequestion.html',
{'question': question, 'form': CodeForm()})
Try changing
class CodeForm(forms.Form):
to
class CodeForm(forms.ModelForm):
I faced same problem but it got resolved from this.
The recent distributions of django don't have widgets included. So:
pip install django-widgets
should do the trick.
Sorry the inconvenient, but I am extremely newbie on Django. I imagined that Django would create the forms for me if I use forms.py, I would not need to create an input tag on template, so I created a test template only, since I created the forms.py. However, running my code I was told that my view didn't return an HttpResponse object, and I suspect it was due to my template having only text on it. Could you help me creating a template to have my forms working ? We can use the example posted above. I will paste it bellow:
def create_post(request):
if request.method == 'POST':
form = CreatePostForm(request.POST)
if form.is_valid():
my_model = form.save()
return redirect('/posts/')
else:
form = CreatePostForm()
c = {'form' : form}
return render(request,'create_post.html',c)
You should return render() instead of HttpResponse:
from django.shortcuts import render
def create_a_my_model(request):
...
return render(request, 'template.html', c)
template.html can be very primitive:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button>Save</button>
</form>
Also note that the good practice is to redirect to some page after the post request. This will prevent the double submit. So the whole code of your view will be:
from django.shortcuts import redirect, render
def create_a_my_model(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
my_model = form.save()
return redirect(my_model) # if the model has `get_absolute_url()`
else:
form = MyModelForm()
return render(request, 'template.html', {'form': form})
If you model doesn't have the get_absolute_url() method the you can redirect to any other url: return redirect('/success/page/')