Passing value and ID from Request.POST - python

I am trying to have a website with multiple input type ="text" fields which as a default have values from database in them.
Goal is to have X input types where X=number of entries in database and one extra input type box to add a new entry.
The problem is that if user edits a textfield and hits submit, Request.POST['event'] returns only the new value, not the id of the box that has been edited,
This is my current code:
<form method="post">
{% csrf_token %}
{% for choice in event %}
<form method ='POST'> {% csrf_token%}
<input type="text" name = "event" id="event{{ forloop.counter }}" value="{{choice.txt}}"><br>
<input type = 'submit' value = 'Zapisz'/>
</form>
{% endfor %}
<form method ='POST'> {% csrf_token%}
{{form.as_p}}<br>
<input type = 'submit' value = 'Zapisz'/>
</form>
and views.py:
def rpg_create(request):
try:
event = get_list_or_404(Event)
except:
event = ""
if request.method == 'POST':
try:
Adjusted_event = request.POST['event']
print (Adjusted_event)
except:
pass
form = RpgForm(request.POST or None)
if form.is_valid():
print(form)
form.save()
context = {
'form': form,
'event': event
}
return redirect('/rpgmaker', context)
else:
form = RpgForm()
context = {
'form': form,
'event': event
}
return render(request,"rpgmaker/rpg.html",context)

Related

Updating multiple checkboxes forms with Django

in my django website I'm trying to building a page in which there are multiple forms (In particular 3: the first is simply a checkbox, as the second one. The third one requires the entering of two text fields). I've already managed the presence of multiple forms and I've no problem when the user performs the first assignment. The problem is instead during the updating of the answers that the user gave the first time: there are no problems when adding new instances of the text fields of the third form, while instead if I've selected one checkbox of the first two forms and I want to change them unchecking them it seems like django doesn't save the new values. Any idea of why it's happening?
Here's the view associated:
def new_4e2(request, pk, var=None):
if Specifiche.objects.filter(ID_rich = pk).exists():
specs = Specifiche.objects.filter(ID_rich = pk)
choicesp =[]
lista =[]
for spec in specs:
choicesp+=[(spec.id, str(spec.rif))]
lista+=[spec.id]
att = MAIN.objects.get(id=pk)
unform = FormUn(instance=att)
data = {'ID_rich': pk}
form = UnicitaForm(initial=data)
form.fields['rifext'].choices = choicesp
if Unicita.objects.filter(rifext__in = lista).exists():
uns=Unicita.objects.filter(rifext__in = lista)
context={
'att': att,
'uns': uns,
'var':var,
'specs': specs
}
else:
context = {
'att': att,
'var':var,
'specs': specs,
}
form = UnicitaForm(initial = data)
form.fields['rifext'].choices = choicesp
similiform = SimiliForm(instance=att)
if request.method=='POST':
if 'Aggiungi' in request.POST:
form = UnicitaForm(request.POST, initial=data)
form.fields['rifext'].choices = choicesp
if form.is_valid():
form.save()
return redirect(f'/new_4e2/{pk}/{var}//')
if 'Simili' in request.POST:
similiform = SimiliForm(request.POST, instance=att)
if similiform.is_valid():
similiform.save()
return redirect(f'/new_4e2/{pk}/{var}//')
if 'Unicita' in request.POST:
unform = FormUn(request.POST, instance=att)
if unform.is_valid():
unform.save()
return redirect(f'/new_4e2/{pk}/{var}//')
context = context | {'form': form, 'unform':unform, 'similiform': similiform}
return render(request, 'new_4e2.html', context)
The two forms for which I have this problems are: 'unform' and 'similiform'
And here is my template.html
<form method="POST">
{% csrf_token %} 4.1 | {{unform}}
<input type="submit" name="Unicita">
</form>
{% if not att.Unicita %}
<div style="position:relative; left:50 px; height: 10 px; width:500 px;">
<form method="POST">
{% csrf_token %} {{similiform}}
<input type="submit" name="Simili">
</form>
<form action ="" method="POST">
{% csrf_token %}
<h4>Insert Unicita</h4>
{{form}}
<input type="submit" name="Aggiungi">
</form>
...

[DJANGO]: How to pass a Django form field value to a template form action?

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)
`

Django, How to add two form in one page?

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.

How to update choices for forms.ChoiceField in Django?

I have field in forms.py:
main_choices = ((1,'option 1'),(2,'option 2'),(3,'option 3'))
sub_choices = ((1,'PlaceHolder'))
class MainForm(forms.Form):
type = forms.ChoiceField(choices=main_choices)
sub_type = forms.ChoiceField(choices=sub_choices)
HTML:
<form action="{% url 'app:get_files' %}" method="POST">
{% csrf_token %}
{{ form.type }}
{{ form.sub_type }}
<button type="submit" class="app">GET</button>
</form>
view.py
def get_files(request):
//Some action with complete form
return FileResponse(zip_file, as_attachment=True)
def get_ajax(request):
if request.is_ajax():
data = request.POST.copy()
if 'type' in data:
type = int(data['type'])
if type == 2:
sub_choices = getChoices(type)
elif type ==3:
sub_choices = getChoices(type)
return HttpResponse()
Currently, server catches ajax post data from the type field.
I don't know how to put sub_choices from get_ajax action to sub_type field in forms.
Can anyone explain how to do that?

form.as_hidden doesn't pass values to POST

My form has initial values in it. I use form.as_hidden to hide the values and pass those values through a POST request. However, the hidden values are not passing through. Is there a way through this?
views.py
def car_detail_view(request, id):
if request.method == "POST":
form = CarForm(request.POST)
print(form.is_valid())
if form.is_valid():
car_save = form.instance
get_car = Car.objects.get(number_plate=car_save.number_plate)
get_car.available = False
get_car.save()
return redirect('/')
else:
print(form.errors)
else:
car = Car.objects.get(id=id)
form = CarForm(initial={'brand':car.brand, 'number_plate':car.number_plate, 'price':car.price,
'available':car.available})
args = {
'car':car,
'form':form
}
return render(request, 'map/confirmation.html', args)
confirmation.html
<h1>Confirmation of Booking</h1>
{% block content %}
<p>Brand: {{ car.brand }}</p>
<p>Number Plate: {{ car.number_plate }}</p>
<p>Price: {{ car.price }}</p>
<p> Are you sure you want to book? <p>
<form class="" method="post">
{% csrf_token %}
{{ form.as_hidden }}
<input type="submit" value="Book {{ car.brand }}">
</form>
{% endblock %}
Error
<ul class="errorlist"><li>brand<ul class="errorlist"><li>This field is required.</li></ul></li><li>number_plate<ul class="errorlist"><li>This field is required.</li></ul></li><li>price<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
Django doesn't have a form.as_hidden method. Therefore {{ form.as_hidden }} will render as the empty string '' in your template.
You can use the as_hidden method for individual form fields.
{{ form.number_plate.as_hidden }}
If you use values from hidden fields, you might need to add code to prevent the user altering the field values (e.g. with their browser's developer tools). However, in your case you don't need to get the values from the form, you can fetch them from the database.
def car_detail_view(request, id):
if request.method == "POST":
car = Car.objects.get(id=id)
car.available = False
car.save()
return redirect('/')
else:
car = Car.objects.get(id=id)
args = {
'car':car,
}
return render(request, 'map/confirmation.html', args)
Once you've got this working, you might want to think about what happens if two users try to book the same car at once.

Categories