MultiValueDictKeyError at /savepost/ - django

I know this has been asked before but I'm facing this MultiValueDictKeyError. Basically I'm trying to take an input from the user, the input tag has this name="usercaption" attribute. While I click on submit it pops up the MultiValueDictKeyError. Here's my HTML form:
<div class="post">
<form action="/savepost/" method="GET">
<input type="text" name="usercaption" placeholder="Write Something...">
<div class="attach">
<button class="upload-image"><i class="fal fa-image"></i> Image</button>
<button><i class="fal fa-video"></i> Video</button>
<button><i class="fal fa-smile-beam"></i> Mood</button>
<button type="submit">Upload</button>
</div>
</form>
</div>
Here's my view function:
def savepost(request):
caption = request.GET["usercaption"]
Post = post(caption=caption)
Post.save()
return redirect('usersfeed')
The error is on this line caption = request.GET["usercaption"]

You have to provide a default value for if it doesn't exist, so for example:
caption = request.GET.get["usercaption", ""]
And you have to add the user as well:
user = request.user
Post = post(caption=caption, user=user)

Related

Python(Django) :I want the payment form(code) triggered whenever a user clicks the submit button and only saved into DB if payment is succesful

I am currently using DJANGO
How can I make the payment form(code) triggered when a user clickn submit and also make it saved into DB after successful payment. Please help me out.. i have been trying to solved this days back.
Here is my models.py
from django.db import models
class Promoting(models.Model):
yourname= models.CharField(max_length=60)
fathername= models.CharField(max_length=60)
mothername= models.CharField(max_length=60)
imagefield=models.ImageField(upload_to='postedimages')
def __str__(self):
return self.promoterauthor
Here is my views.py
from django.shortcuts import render
from .models import Promoting
def homepage(request):
if request.method == 'POST':
yourname=request.POST.get('yourname')
fathername=request.POST.get('fathername')
mothername=request.POST.get(' mothername')
imagefield=request.FILES['imagefield']
newdata=Promoting(promoterauthor=promoterauthor,websiteurl=websiteurl,tagline=tagline,imagefield=imagefield)
newone.save()
return render(request, 'success.html', {})
else:
return render(request, 'homepage.html', {})
Here is my form
<form action="{% url 'home' %}" method="POST" role="form" enctype="multipart/form-data class="contactForm">
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6">
<input type="text" name="yourname" id="yourname" class="form-control" placeholder="Youur username" required>
</div>
<div class="form-group col-md-6">
<input type="" class="form-control" name="fathername" id="fathername" placeholder="Your Website" required>
</div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="mothername" id="mothername" placeholder="Add a Tag line" required>
</div>
<div class="form-group">
<input type="file" class="form-control" name="imagefield" id="imagefield" placeholder="Your image" accept="image/*" required>
</div>
<div class="text-center"><button type="submit">Send Message</button></div>
</form>
The form submits successfully into the database and also my payment gateway(Rave by flutterwave.COM is working well)n I ONLY NEED A WAY TO LINK BOTH TOGETHER
Precisely, what I want is the payment form triggered once the submit button is clicked and I only want a the data saved into DB if only payment is successful .. please help out
The code snippet from my payment gateway also works when the pay button is clicked...
Here it the payment code
<form>
<script src="https://api.ravepay.co/flwv3-pug/getpaidx/api/flwpbf-inline.js"></script>
<button type="button" onClick="payWithRave()">Pay Now</button>
</form>
<script>
const API_publicKey = "FLWPUBK-152e7e9e17c0f7e985f9fee5838eafcc-X";
function payWithRave() {
var x = getpaidSetup({
PBFPubKey: API_publicKey,
customer_email: "user#example.com",
amount:5,
customer_phone: "234099940409",
currency: "USD",
txref: "rave-123456",
meta: [{
metaname: "flightID",
metavalue: "AP1234"
}],
onclose: function() {},
callback: function(response) {
var txref = response.tx.txRef; // collect txRef returned and pass to a server page to complete status check.
console.log("This is the response returned after a charge", response);
if (
response.tx.chargeResponseCode == "00" ||
response.tx.chargeResponseCode == "0"
) {
// redirect to a success page
} else {
// redirect to a failure page.
}
x.close(); // use this to close the modal immediately after payment.
}
});
}
</script>
THIS IS WHAT IS GENERATED BY THE PAYMENT CODE WHEN PAY IS CLICKED

Django: How to use modal as a form to update an object

I'm trying to use modal as a edit form but I don't know good way.
Currently my views.py is like this.
def edit_entry(request, entry_pk):
entry = get_object_or_404(Entry, pk=entry_pk)
if request.method != 'POST':
form = EntryForm(instance=entry, user=request.user)
else:
form = EntryForm(instance=entry, data=request.POST, user=request.user)
if form.is_valid():
form.save()
and I have a template for this view.
What I want to do is
from the page that lists a bunch of entry objects, the edit form for the object is shown when I click edit button.
{% for entry in entries %}
...
<button class="btn btn-outline-primary" data-toggle="modal" data-target="#editEntryModal">Edit</button>
<!-- modal for the object -->
Anyone who could give me tips?
You need to send back your form as html and stick it in the modal before you show it. so on click, you would first do you ajax request, and this will send back your form as html. For example,
def edit_entry(request, entry_pk):
....
entry = get_object_or_404(Entry, pk=entry_pk)
if request.method != 'POST':
form = EntryForm(instance=entry, user=request.user)
return HttpResponse(form.as_p()) # This will return the plain html of a form
....
Hope this helps!
I had a similar task and first created an ajax request from the template to load the data:
<script>
$(document).ready(function(){
$("#myBtn").click(function(){
var pk = $(this).data('pid')
$("#myModal").modal("show");
});
$("#myModal").on('show.bs.modal', function(event){
var modal = $(this)
var pk = $(this).data('pid')
$.ajax({
data: {'pk': pk},
url: "{% url 'search:load_paper' %}",
context: document.body,
error: function(response, error) {
alert(error);
}
}).done(function(response) {
modal.html(response);
});
});
});
</script>
The load_paper function looks like the following:
def load_paper(request):
pk = request.GET.get('pk')
object = get_object_or_404(Paper, pk = pk)
form = PaperForm(instance=object)
return render(request, 'edit_paper_modal.html', {
'object': object,
'pk': pk,
'form': form,
})
The data is rendered in the 'edit_paper_modal.html', which looks like this:
<div class="modal-dialog modal-lg" role="document">
<form action="{% url 'search:edit_paper' pk=object.pk %}" method="post" class="form" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title">Edit Paper</h4>
</div>
<div class="modal-body">
{% csrf_token %}
{{form|crispy}}
{{ form.media }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Save changes" />
</div>
</div><!-- /.modal-content -->
</form>
</div>
The key thing here is that I am passing the pk of the paper back to the edit_paper function in views.py which actually saves the form.
Hope this is useful!
what you are trying to possible only with django template.
you need js or jquery or any frontend framework .
when you click edit button A edit from will appeared in current dom and you need to make ajax call to get initial data for edit from. the edit the data and submit the data vai ajax and in backend update the object. django rest framework is more suitable for this kind of task.

Django How do i pass the url parameter with the form button?

Hi i am Newbie in django i read django documentation but i had made a url with parameteres i want to book a car . for booking i need car id and driver id . after redirect to my booking page . my book now button is not sending the driver id and car id . please help me.
for example.
i am having a John as a Driver , and he click on Audi To book . after getting his url i want to save it to my booking database . after click on button in my html "book now" it doesnt render to next page book a car and dont get the car id and driver id.
please help me.
Sorry for my english . if didnt understand please let me know in comments ill more explain to you and share more content . i am just beginner in field so just learning .
Views
#csrf_protect
def rentacar_car(request, car_id,driver_id):
try:
args['car'] = Car.objects.get(id__exact=car_id)
args['driver_id'] = driver_id
except:
args['car'] = None
args['driver_id'] = None
if args['car'] is not None:
template = Template.objects.get(template_default__exact=1)
return render(request, template_page, args)
else:
return HttpResponseRedirect('/rentacar/list/')
def rentacar_booking(request):
template = Template.objects.get(template_default__exact=1)
template_page = template.template_alias + str("/rentacar/rentacar_booking_form.html")
menu_config_list = MenuItemRentacarList.objects.all()[0]
menu_config = MenuItemRentacarList.objects.get(id=menu_config_list.id)
args['main_menu'] = MenuMenu.objects.get(id__exact=template.template_main_menu_id)
args['menu_items'] = MenuItem.objects.filter(
menu_item_menu=args['main_menu'],
menu_item_published=1,
)
args['current_menu_item'] = menu_config.menu_item_rentacar_list_menu_item
all_modules = Module.objects.filter(
module_show_option__exact='all',
module_published=1
)
selected_modules = Module.objects.filter(
module_show_option__exact='selected',
module_published=1,
module_menu_item=args['current_menu_item']
)
excluded_modules = Module.objects.filter(
module_show_option__exact='except',
module_published=1,
).exclude(
module_menu_item=args['current_menu_item']
)
args['modules'] = list(chain(all_modules, selected_modules, excluded_modules))
try:
args['car'] = Car.objects.get(id__exact=request.POST.get('car_id'))
args['driver'] = Driver.objects.get(id__exact=request.POST.get('driver_id'))
except:
args['car'] = None
args['driver'] = None
if args['car'] is not None:
return render(request, template_page, args)
else:
return HttpResponseRedirect('/rentacar/list/')
else:
return HttpResponseRedirect('/')
Templates
rentacar_book_form
<div class="row">
<div class="medium-6 small-12 columns">
<label>
Book Start Date <br>
<input type="date" name="book_booking_start_date" required>
</label>
</div>
<div class="medium-6 small-12 columns">
<label>
Book End Date <br>
<input type="date" name="book_booking_end_date" required>
</label>
</div>
</div>
<hr>
<input type="submit" class='button large primary' value="Book {{ car.car_brand.brand_name }} {{ car.car_name }}">
</div>
</div>
<input type="text" name="book_booking_car_car" value="{{ car.id }}" class="hidden">
<input type="text" name="book_booking_driver_driver" value="{{ driver.id }}" class="hidden">
rentacar_car_car
<form action="/rentacar/book-a-car/" method="post">
{% csrf_token %}
<input name="car_id" type="text" value="{{ car.id }}" class="hidden" required>
<input name="driver_id" type = 'text' value="{{ driver.id }}" class = 'hidden' required>
<button type="submit" class="button primary uppercase centered full-width">
Book now!
</button>
</form>
urls.py
url(r'^rentacar/book-a-car/$', extension_views.rentacar_booking),
url(r'^rentacar/list/(\d+)/$', extension_views.rentacar_list),
url(r'^rentacar/car/(\d+)/driver/(\d+)/$', extension_views.rentacar_car),
If you just want to get the values from hidden inputs just do this.
In method rentacar_car type:
car_id = request.GET.get('car_id')
driver_id = request.GET.get('driver_id')
print(car_id)
print(driver_id)
And since you are getting the values from those inputs you have to change method of form to GET.

pass parameter to form from template in Django 2

in Django I make a form which get an email address and save it in database and this my form.py:
class NewsletterUserSignUpForm(forms.ModelForm):
class Meta:
model = NewsletterUsers
fields = ['email']
def clean_email(self):
email = self.cleaned_data.get('email')
return email
and this is my views.py :
def newsletter_signup(request):
form = NewsletterUserSignUpForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
if NewsletterUsers.objects.filter(email=instance.email).exists():
messages.warning(request, 'Your Email Already Exist In Our DataBase.',
'alert alert-warning alert-dismissible')
else:
instance.save()
messages.success(request, 'Your Has Been Submitted To Our DataBase.',
'alert alert-success alert-dismissible')
context = {
'form': form,
}
return render(request, 'newsletter/subscribe.html', context)
the problem is here that this form has it own input which the input must put inside it but I want to design my own template and get input in my template then pass it to this form and my question is how do I can pass inputs in my .html template file to my form?
this is my html file and don't know to put what in href for input tag :
<form method="post" class="login100-form validate-form">
{% csrf_token %}
<span class="login100-form-title p-b-43">
Subscribe
</span>
<div>
<inputtype="email" name="Email">
<span class="label">Email</span>
</div>
<button type="submit" href="">
Subscribe
</button>
</div>
and what should I put in my href and how pass input to form from here?
In addition, I'm sorry for writing mistakes in my question.
From what I understand, you want to create your own custom input box and when that box is filled, you want the form input box to also get filled.
Hide the form input box using display:none.
Create your own custom input box, use javascript to fill the form input box when custom input box is filled.
Ex :
<script>
form_input_box = document.getElementById('id_of_form_input_box')
custom_input_box = documen.getElementById('id_of_custom_input_box')
$("id_of_custom_input_box").change(function(){
form_input_box.value = custom_input_box.value
});
</script>
the problem it was for my html code, I Should add an id and name attribute to my input tag and use this id and name for getting input from html and pass it to my form, and for href attribute I write the url that redirect to my form.
fixed html code:
<form method="post" class="login100-form validate-form">
{% csrf_token %}
<span class="login100-form-title p-b-43">
Subscribe
</span>
<div class="wrap-input100 container-login100-form-btn rs1 rs2 validate-input padding-50"
data-validate="Username is required">
<input id="email" maxlength="100" class="input100" type="email" name="email">
<span class="label-input100">Email</span>
</div>
<div class="container-login100-form-btn">
<button type="submit" href="{% url 'newsletter_subscribe' %}" class="login100-form-btn">
Subscribe
</button>
</div>
<div class="text-center w-full p-t-23">
<a style="font-size: 15px" href="{% url 'newsletter_unsubscribe' %}" class="txt1">
Click Here To Unsubscribe.
</a>
</div>
</form>

django the way to access data from input form

My symptom is when I click the modify button and then I write down the information on new window that is implemented by bootstrap div part. However, my database doesn't change at all. Please ignore ... in codes, I delete attributes that looks messy. Codes can have typo, because I wrote it down manually to find a bug, but I didn't find.
I tried in view.py, address_modify makes return Httpresponse(street), but It returned None.
view.py
def address_modify(request, adid):
cat = get_object_or_404(Address, adid=adid)
if request.method == "POST":
old_adid = adid
email = request.user.email
street = request.POST.get("street", None)
city = request.POST.get("city", None)
...
Address.objects.filter(adid=adid).update(..., street=street, city=city, state=state, ...)
return redirect('/address/')
return redirect('/address/')
template ( I name it address.html)
<button class="btn btn-success" data-toggle="modal" data-target="#modify">MODIFY</button>
<div class ="model fade" id="modify" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<from action="" method="POST">{% csrf_token %}
</div>
<div class="modal-body">
<input type="text" name="street">
<input type="text" name="city">
...
...
<input type="text" name="zipcode">
</div>
<div class="modal-footer">
<a href="{% url 'address_modify' i.adid %}">{% csrf_token %}
<button type="button" class="btn btn-primary">Save Change</button></a>
<div></form>
urls.py
url(r'^address_modify/(?P<adid>[0-9]+)/$', MyAppView.address_modify, name='address_modify'),
In django the best practice is to create a forms.py file to handle forms, its really easy you can read the doumentation on it, basically the form will ensure that all your data are read.
That is not how you implement form and form submit. Your link is not submitting anything, it's just opening a link. This is the standard form syntax:
<form method="POST">
{% csrf_token %}
... your form input fields here ...
<input type="submit" value="Save changes">
</form>
You must submit the form. Note type="submit" there.
Next to that, Django has forms feature. Use it. Create forms.py as #Saumel-Omole suggested. Form for model Address would look like this:
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = '__all__'
Then you modify your view to use the form like:
def address_modify(request, adid):
cat = get_object_or_404(Address, adid=adid)
form = AddressForm(instance=cat)
if request.method == 'POST':
form = AddressForm(request.POST, instance=cat)
if form.is_valid():
form.save()
return redirect('/address/')
else:
print(form.errors) # change to logging
return render(request, 'address.html', {'form': form})
Go over the official Django tutorial. These basics are all there. Maybe it is going to take you a day or two to get through it, but long-term that's going to be far less than guessing and googling around for days for basic stuff.