i made a form in django with one field required (imagefield) but when I fill it by selecting an image, once I fill it it considers that the form is not valid and asks to fill it again I don't understand why, here is my code below:
view.py:
def success(request):
return HttpResponse('successfully uploaded')
def contact(request, plage_name):
name = plage_name
plage = Spot.objects.get(name__iexact=name)
if request.method == 'POST':
form = ContactUsForm(request.FILES) # ajout d’un nouveau formulaire ici
if form.is_valid():
print("it's valide")
plage.photo = form.cleaned_data['photo']
plage.save()
return redirect('success')
else:
form = ContactUsForm()
return render(request,
'pages/Testform.html',
{'form': form}) # passe ce formulaire au gabarit
form.py
class ContactUsForm(forms.Form):
photo = forms.ImageField(required=True)
html
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form }}
<input type="submit" value="Envoyer">
</form>
Url.py
urlpatterns = [
path('contact-us/<path:plage_name>', views.contact, name='contact'),
]
in views.py
if request.method == 'POST':
form = ContactUsForm(request.POST,request.FILES)
in HTML
<form action="" method="post" novalidate enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Envoyer">
</form>
I think your error is on the parameters of form init. The first paramters is for POST data, not FILES:
form = ContactUsForm(request.POST, request.FILES)
And after, you have to call form.save(), probably better than make the update yourself...
Related
views.py:
def index(request):
if request.method == 'POST':
data = request.POST['data']
context = {'mydata': data}
return render(request, 'home/index.html', context)
else:
html_template = loader.get_template('home/index.html')
HttpResponse(html_template.render(request))
index.html:
<form method = 'POST' id = 'post-form'>
<select name = 'data' id = 'data'>
<option> 1 </option>
<option> 2 </option>
</select>
<button type="submit" name = 'post-form'> submit </button>
</form>
<h2> {{ mydata}} </h2> // this line print nothing.
When I click the submit button, I can access data from html submit in views.py.
However, I can't access mydata from Django in html.
How can I solve it?
There are minor mistakes in the code:
You need to return HttpResponse so return HttpResponse(html_template.render(request)), but I'd recommend you to directly use return render(request, 'home/index.html').
Also need to place {% csrf_token %} while dealing with POST data inside form, unless you have mentioned #csrf_exempt decorator on view.
So, try this code:
views.py:
def index(request):
if request.method == 'POST':
data = request.POST.get('data')
context = {'mydata': data}
return render(request, 'home/index.html', context)
else:
return render(request, 'home/index.html')
# OR #
# html_template = loader.get_template('home/index.html')
# return HttpResponse(html_template.render({}, request))
index.html:
<form method='POST' id='post-form'>
{% csrf_token %}
<select name='data' id='data'>
<option> 1 </option>
<option> 2 </option>
</select>
<button type="submit" name='post-form'> submit </button>
</form>
<h2> {{mydata}} </h2>
I have a Django form that asks for id number. Hence, when the user clicks on submit, that id number is passed as a parameter to the endpoint.
This URL path('verify/nin/', views.post_nin, name='post_nin') contains the form and asks for the id number while I am submitting the data to this URL to
path('nin/<str:nin>',
views.nin_verification_vw, name="nin_verification")
So I expect to be redirected to http://127.0.0.1:8000/api/nin/15374020766 but instead it is redirecting me to http://127.0.0.1:8000/api/nin/%3Cinput%20type=%22text%22%20name=%22nin%22%20required%20id=%22id_nin%22%3E?nin=15374020766&csrfmiddlewaretoken=u5UmwDW4KRUIvYWXAa64J8g1dTPoJ3yDqtoCuKjboIE2TNxI3tPbjPmCK6FztVwW
How do I avoid the unnecessary parameters?
Here is my forms.py:
class NINPostForm(forms.Form):
"""Form for a user to verify NIN"""
nin = forms.CharField(required=True, help_text='e.g. 123xxxxxxxx')
# check if the nin is a valid one
def clean_nin(self):
nin = self.cleaned_data['nin']
regex = re.compile("^[0-9]{11}$")
if not regex.match(nin):
raise forms.ValidationError("NIN is incorrect.")
return nin
Here is my views.py:
def post_nin(request):
submitted = False
if request.method == 'POST':
form = NINPostForm(request.POST)
if form.is_valid():
cd = form.cleaned_data['nin']
return HttpResponseRedirect('/verify/nin?submitted=True')
else:
form = NINPostForm()
context = {
'form': form,
# 'cd': cd,
}
return render(request, 'ninform.html', context)
And here is my HTML template:
<form action="{% url 'nin_verification' form.nin %}" method="POST">
<table>
{{ form.as_table }}
<tr>
<td><input type="submit" value="Submit"></td>
</tr>
</table>
{% csrf_token %}
</form>
first import redirect : from django.shortcuts import redirect
Change your view to :
<form action="{% url 'post_nin' %}" method="POST">
<table>
{{ form.as_table }}
<tr>
<td><input type="submit" value="Submit"></td>
</tr>
</table>
{% csrf_token %}
</form>
You were passing the whole field instead of a String by using form.nin in your form action you should use your post_nin view to parse the nin field so...
Change your view to :
def post_nin(request):
submitted = False # Don't understand this part
if request.method == 'POST':
form = NINPostForm(request.POST)
if form.is_valid():
nin = form.cleaned_data['nin']
return redirect('nin_verification', nin=nin)
else:
form = NINPostForm()
context = {
'form': form,
}
return render(request, 'ninform.html', context)
`
I am new to django, my question is simple. How can I add two form in the same page? I tried many things as making a class in views or add a second urls path but didn't find how. Thanks you for helping
this is my code:
forms.py
class scrap_info(forms.Form):
url = forms.CharField(label="Urls")
website = forms.ChoiceField(label="Website", choices=ask_website)
class sms_info(forms.Form):
data = forms.ChoiceField(label="Data list", choices=ask_data)
number = forms.CharField(label="Sms number")
views.py
def scrap_app(request):
form1 = scrap_info(request.POST or None)
return render(request, "sms/scrap_app.html", {'form1': form1})
def sms_app(request):
form2 = sms_info(request.POST or None)
return render(request, "sms/sms_app.html", {"form2": form2})
scrap_app.html
<body>
<div>
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-outline-info" type="submit" value="Save">SCRAP</button>
</form>
</div>
</body>
urls.py
urlpatterns = [
path("/scrap_app", views.scrap_app, name="scrap_app"),
]
I have encountered this problem just recently and I solved it by adding a hidden field on every form and getting that hidden value to determine what form was submitted by using an if condition in views
Here's how I did it using CBV.
views.py
class ContactUsView(TemplateView):
template_name = 'yourtemplate.html'
def get(self, request, *args, **kwargs):
inquiry_form = InquiryForm(self.request.GET or None, prefix='inquiry_form')
complaint_form = ComplaintForm(self.request.GET or None, prefix='complaint_form')
context = self.get_context_data(**kwargs)
context['complaint_form'] = complaint_form
context['inquiry_form'] = inquiry_form
return self.render_to_response(context)
def post(self, request):
# instantiate all unique forms (using prefix) as unbound
inquiry_form = InquiryForm(prefix='inquiry_form')
complaint_form = ComplaintForm(prefix='complaint_form')
# determine which form is submitting (based on hidden input called 'action')
action = self.request.POST['action']
# bind to POST and process the correct form
if action == 'inquiry':
inquiry_form = InquiryForm(data=request.POST, prefix='inquiry_form')
if inquiry_form.is_valid():
# Your logic here
return self.render_to_response(
self.get_context_data(
inquiry_form=inquiry_form,
complaint_form=complaint_form,
)
)
messages.error(self.request,
'Inquiry form is invalid.')
elif action == 'complaint':
complaint_form = ComplaintForm(data=request.POST, prefix='complaint_form')
if complaint_form.is_valid():
# Your logic here
return self.render_to_response(
self.get_context_data(
inquiry_form=inquiry_form,
complaint_form=complaint_form,
)
)
messages.error(self.request,
'Complaint form is invalid.')
# prep context
context = {
'inquiry_form': inquiry_form,
'complaint_form': complaint_form,
}
return render(request, self.template_name, context)
yourtemplate.html
<!-- First Form -->
<form action="" method="post" role="form">
{% csrf_token %}
<input type='hidden' name='action' value='inquiry'>
{{ form1 }}
<button type="submit" title="Send Inquiry">Send Inquiry</button>
</form>
<!-- Second Form -->
<form action="" method="post" role="form">
{% csrf_token %}
<input type='hidden' name='action' value='complaint'>
{{ form2 }}
<button type="submit" title="Send Complaint">Send Complaint</button>
</form>
As you can see there's a hidden value in every form named 'action', that will be the one to determine which form was submitted.
my page html :
resrver salle !
<form>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="reserver">
</form>
views .py :
def reserversalle(request , id):
form= ReserverSalle(request.POST or None)
print(form)
if form.is_valid():
print("gooddd")
context= {
'form' : form ,
}
return render(request,'registration/reserversalle.html', context)
forms.py :
class ReserverSalle(forms.Form):
nomsalle = forms.CharField(required=True , widget=forms.TextInput)
motifresa = forms.CharField(required=True , widget=forms.TextInput)
datedebut = forms.DateField( initial="2019-06-21",
widget=forms.SelectDateWidget(years=YEARS))
heuredebut = forms.TimeField( initial='00:00:00')
heurefin = forms.TimeField( initial='00:00:00')
hello i try to submit my form but my form is not valid please i need some help
Try adding form attributes action and method
<form action="." method="post">...</form>
if request.method == 'POST':
form = ReserverSalle(request.POST)
....
else:
form = ReserverSalle()
you need to specify method and action in your form tag in html
<form method="POST" action="<<URL_TO_HANDLE_YOUR_FORM>>">
<> means Url specified in your URL.py which direct it to the views.py function you have written
form.is_valid in views.py always return false. I have used Django forms to create a form and html to implement it.
I will upload this photo to imgur using imgurpython later, but first this should work.
views.py
def upload_view(request):
usr = check_validation(request)
if usr:
if request.method == "GET":
form = PostForm()
return render(request, 'upload.html', {'form': form})
elif request.method == "POST":
form = PostForm(request.POST, request.FILES)
if form.is_valid():
pic = form.cleaned_data.get('image')
title = form.cleaned_data.get('caption')
post = PostForm()
post.user = usr
post.caption = title
post.image = pic
post.save()
return redirect('feed/')
else:
return render(request, 'upload.html', {'error_msg' : "Invalid Inputs"})
else:
return redirect('/login/')
models.py
class Post(models.Model):
user = models.ForeignKey(User)
image = models.FileField(upload_to='user_images')
caption = models.CharField(max_length=240)
image_url = models.CharField(max_length=255)
created_on = models.DateTimeField(auto_now_add=True)
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['user', 'image', 'caption']
template - upload.html
<form method="post" enctype="multipart/form-data" class="loginbox" style="margin-top:200px;">
{% csrf_token %}
<p class="text-16">Upload to aperture.</p>
{{ form }}
<p class="text-16">{{ error_msg }}</p>
<input class="login-btn" type="submit" value="Upload"/>
</form>
Try this,
<form method="post" enctype="multipart/form-data" class="loginbox" style="margin-top:200px;">
{% csrf_token %}
{{ form }}
<input class="login-btn" type="submit" value="Upload"/>
</form>
If this doesn't work, print the request.POST and request.FILES then update the answer with the contents.
Your context has only one variable named form so you have to use that only to make your form work.
<form method="post" enctype="multipart/form-data" class="loginbox" style="margin-top:200px;">
{% csrf_token %}
<p class="text-16">Upload to aperture.</p>
<input type="file" accept="image/*" value="{{ form.image }}" name="image" class="login-btn"/><br/>
<input placeholder="Caption" class="input-default all-curve" rows="3" value="{{ form.caption }}" name="caption" />
<p class="text-16">{{ form.error_msg }}</p>
<input class="login-btn" type="submit" value="Upload"/>
</form>