DJANGO SENDING ORDERS TO THE DATABASE WITHOUT ANY PAYMENT GATEWAY - django

How do i send my order to my database in django
i'm beginner in django, and i'm trying to build an ecoomerce sute . although i'm not using the same payment gateway so its difficult for me to fllow up.
i want the order details to be saved in the database.
help
my orders view
from django.shortcuts import render
from django.http.response import JsonResponse
from django.shortcuts import render
from cart.cart import Cart
from .models import Order, OrderItem
Create your views here.
def add(request):
cart = Cart(request)
if request.POST.get('action') == 'post':
user_id = request.user.id
carttotal = cart.get_total_price()
# Check if order exists
if Order.objects.filter(order_key=order_key).exists():
pass
else:
order = Order.objects.create(user_id=user_id, full_name='name', address1='add1',
address2='add2', total_paid=carttotal, order_key=order_key)
order_id = order.pk
for item in cart:
OrderItem.objects.create(order_id=order_id, product=item['product'], price=item['price'], quantity=item['qty'])
response = JsonResponse({'success': 'Return something'})
return response
def payment_confirmation(data):
Order.objects.filter(order_key=data).update(billing_status=True)
def user_orders(request):
user_id = request.user.id
orders = Order.objects.filter(user_id=user_id).filter(billing_status=True)
return orders
{% extends "../store/base.html" %}
{% load static %}
{% block title %}Order{% endblock %}
{% block content %}
<style>
.account-form input,
{
border: 2px solid #ccc;
height: calc(2em + .75rem + 2px);
}
.form-control {
border: 2px solid #ccc;
}
.account-form input:focus {
border-color: #1497ff;
box-shadow: inset 0 0px 0px rgba(0, 0, 0, 0.075), 0 0 0px rgba(255, 0, 0, 0.6);
}
</style>
<div class="container-fluid">
<div class="row no-gutter">
<div class="col-md-12">
<div class="login d-flex align-items-center py-5">
<div class="container">
<div class="row">
<div id="payment-form" class="col-12 col-lg-6 mx-auto">
<h3 class="mb-3">Billing address</h3>
<!-- Error messages in this element -->
<div id="card-errors" class="a" role="alert"></div>
<form>
<div class="row g-3">
<div class="col-sm-7">
<label for="firstName" class="form-label">Customer Name</label>
<input type="text" name="name" class="form-control" id="custName" placeholder="" required>
<div class="invalid-feedback">
Valid first name is required.
</div>
</div>
<div class="col-12">
<label for="email" class="form-label">Email <span class="text-muted">(Optional)</span></label>
<input type="email" name="email" class="form-control" id="email" placeholder="you#example.com">
</div>
<div class="col-12">
<label for="address" class="form-label">Address</label>
<input type="text" name="address" class="form-control" id="custAdd" placeholder="1234 Main St" required>
<div class="invalid-feedback">
Please enter your address.
</div>
</div>
<div class="col-md-5">
<label for="country" name="country" class="form-label">Country</label>
<select class="form-select" id="country" required>
<option value="">Choose...</option>
<option>Zambia</option>
</select>
<div class="invalid-feedback">
Please select a valid country.
</div>
</div>
<div class="col-md-4">
<label for="state" name="state" class="form-label">State</label>
<select class="form-select" id="state" required>
<option value="">Choose...</option>
<option>Lusaka (Evelyne Hone College)</option>
</select>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div>
</div>
</div>
<hr class="my-4">
<h4 class="mb-3">Orders</h4>
<label for="card-element">Credit or debit card</label>
<div id="card-element" class="form-control form-control-payment">
<!-- Payment elements will appear here -->
</div>
<hr class="my-4">
<button id="submit" id="make-payment" class="btn btn-primary w-100 fw-bold">Order Now</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var total={{'basket.get_subtotal_price'}}
document.getElementById("make-payment").addEventListener('click',function(e){
submitFormData()
})
function submitFormData(){
console.log("payment button clicked")
var userFormData={
'name':null,
'email':null,
'total':total
'address':null,
'state':null,
'country':null,
}
if (user=='AnonymousUser'){
userFormData.name=form.name.value
userFormData.name=form.email.value
userFormData.name=form.address.value
userFormData.name=form.state.value
userFormData.name=form.country.value
}
var url='/order_placed/'
fetch=(url,{
method:'post'
headers:{
'content-type':'application/json',
'x-CSRF_Token':csrf_token
},
body:JSON.stringify({'form':userFormData})
} )
</script>
{% endblock %}

Related

How to read additional data posted by form in django forms.py

I'm trying to write kind off bussiness mail management.
In simple world, it'll have bunch of mail templates that will use un mailmerge operation
There will be 2 kind of user:
those who create mail templates, let's call them 'tc' (template creator)
thoise who will issueing mails by term of triggering a mail merge.
In this post I will only ask about the tc part.
The work sequnce will :
TC make a MS docx,
upload to this web app
web app will get all variable names from docx ( I use docxtpl library), and save it on MailTemplate model class.
here is my MailTemplate model class
class MailTemplate(models.Model):
name = models.CharField(max_length=20)
tfile = models.FileField(upload_to='uploads/mailtemplate', null=True, blank=True)
schema = models.CharField(max_length=256, blank=True, null=True, editable=False)
# conto: ['{"name": "kepada", "label": "Kepada", "type": 2, "format": ""}']
def __str__(self) -> str:
return self.name
all variables gathered by docxtpl, is combined in the form as list-of-dicts and saved in MailTemplate.schema
example:
[{"name": "date", "label": null, "type": 2, "format": ""}, {"name": "invoiceNumber", "label": null, "type": 2, "format": ""}, {"name": "company", "label": null, "type": 2, "format": ""}, {"name": "total", "label": null, "type": 2, "format": ""}]
When TC first update new template, MailTemplate.schema is still empty.
I make ModelAdmin to use custom change_view template.
class MailTemplateAdmin(admin.ModelAdmin):
change_form_template = 'mailtemplate_form.html'
form = MailTemplateForm
and here is the mailtemplate_form.html
{% extends "admin/change_form.html" %}
{% block after_field_sets %}
<!--- add htmx -->
<script src="https://unpkg.com/htmx.org#1.6.0"></script>
<style>
/* DivTable.com */
.divTable{
display: table;
width: 100%;
}
.divTableRow {
display: table-row;
}
.divTableCell, .divTableHead {
border: 1px solid #999999;
display: table-cell;
padding: 3px 10px;
}
.divTableHeading {
display: table-header-group;
font-weight: bold;
}
.divTableFoot {
background-color: #EEE;
display: table-footer-group;
font-weight: bold;
}
.divTableBody {
display: table-row-group;
}
</style>
<style>
.button.bino_btn {
background:none; border:none;
}
</style>
{% if not add %}
<div id="schema_head" hx-get="{% url 'get_schema' object_id %}" hx-trigger="load" hx-target="#alldata" hx-swap="innerHTML">
<b>Schema </b>
<button class="button.bino_btn" hx-get="{% url 'get_schema' object_id %}" hx-trigger="click" hx-target="#alldata" hx-swap="innerHTML">Refresh</button>
</div>
<div id="table_for_schema" class="divTable">
<div class="divTableHeading">
<div class="divTableRow">
<div class="divTableHead">Nama Variabel</div>
<div class="divTableHead">Label</div>
<div class="divTableHead">Tipe</div>
<div class="divTableHead">Format</div>
</div>
</div>
<div id="alldata" class="divTableBody">
</div>
</div>
{% endif %}
{% endblock %}
when that template called in 'change' mode, it will call a views function that will read respective MailTemplate.schema, deserialized it and add additional fields inside form.
Here is resulted HTML form (copied from 'inspector') :
<html dir="ltr" lang="en-us"><head>
<title>docx01 | Change mail template | Django site admin</title>
<link rel="stylesheet" href="/static/admin/css/base.css">
<link rel="stylesheet" href="/static/admin/css/dark_mode.css">
<link rel="stylesheet" href="/static/admin/css/nav_sidebar.css">
<script src="/static/admin/js/nav_sidebar.js" defer=""></script>
<link rel="stylesheet" href="/static/admin/css/forms.css">
<script src="/admin/jsi18n/"></script>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="/static/admin/js/core.js"></script>
<script src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
<script src="/static/admin/js/actions.js"></script>
<script src="/static/admin/js/urlify.js"></script>
<script src="/static/admin/js/prepopulate.js"></script>
<script src="/static/admin/js/vendor/xregexp/xregexp.js"></script>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="/static/admin/css/responsive.css">
<meta name="robots" content="NONE,NOARCHIVE">
<style> .htmx-indicator{opacity:0;transition: opacity 200ms ease-in;} .htmx-request .htmx-indicator{opacity:1} .htmx-request.htmx-indicator{opacity:1} </style></head>
<body class=" app-myapp model-mailtemplate change-form" data-admin-utc-offset="0">
<!-- Container -->
<div id="container">
<!-- Header -->
<div id="header">
<div id="branding">
<h1 id="site-name">Django administration</h1>
</div>
<div id="user-tools">
Welcome,
<strong>admin</strong>.
View site /
Change password /
<form id="logout-form" method="post" action="/admin/logout/">
<input type="hidden" name="csrfmiddlewaretoken" value="ZBziDfqR44MaX5oT5fyG9cRUkO1uqi70JZjLQB1gzdHWHaL2l7gNYJH0HnLaMWtp">
<button type="submit">Log out</button>
</form>
</div>
</div>
<!-- END Header -->
<div class="breadcrumbs">
Home
› Myapp
› Mail templates
› docx01
</div>
<div class="main shifted" id="main">
<button class="sticky toggle-nav-sidebar" id="toggle-nav-sidebar" aria-label="Toggle navigation"></button>
<nav class="sticky" id="nav-sidebar">
<input type="search" id="nav-filter" placeholder="Start typing to filter…" aria-label="Filter navigation items">
<div class="app-auth module">
<table>
<caption>
Authentication and Authorization
</caption>
<tbody><tr class="model-group">
<th scope="row">Groups</th>
<td>Add</td>
</tr>
<tr class="model-user">
<th scope="row">Users</th>
<td>Add</td>
</tr>
</tbody></table>
</div>
<div class="app-myapp module current-app">
<table>
<caption>
Myapp
</caption>
<tbody><tr class="model-mailtemplate current-model">
<th scope="row">Mail templates</th>
<td>Add</td>
</tr>
</tbody></table>
</div>
</nav>
<div class="content">
<!-- Content -->
<div id="content" class="colM">
<h1>Change mail template</h1>
<h2>docx01</h2>
<div id="content-main">
<ul class="object-tools">
<li>
History
</li>
</ul>
<form enctype="multipart/form-data" method="post" id="mailtemplate_form" novalidate=""><input type="hidden" name="csrfmiddlewaretoken" value="ZBziDfqR44MaX5oT5fyG9cRUkO1uqi70JZjLQB1gzdHWHaL2l7gNYJH0HnLaMWtp">
<div>
<fieldset class="module aligned ">
<div class="form-row field-name">
<div>
<label class="required" for="id_name">Name:</label>
<input type="text" name="name" value="docx01" class="vTextField" maxlength="20" required="" id="id_name">
</div>
</div>
<div class="form-row field-tfile">
<div>
<label for="id_tfile">Tfile:</label>
<p class="file-upload">Currently: uploads/mailtemplate/invoice-template_BCpUuSw.docx
<span class="clearable-file-input">
<input type="checkbox" name="tfile-clear" id="tfile-clear_id">
<label for="tfile-clear_id">Clear</label></span><br>
Change:
<input type="file" name="tfile" id="id_tfile"></p>
</div>
</div>
</fieldset>
<!--- add htmx -->
<script src="https://unpkg.com/htmx.org#1.6.0"></script>
<style>
/* DivTable.com */
.divTable{
display: table;
width: 100%;
}
.divTableRow {
display: table-row;
}
.divTableCell, .divTableHead {
border: 1px solid #999999;
display: table-cell;
padding: 3px 10px;
}
.divTableHeading {
display: table-header-group;
font-weight: bold;
}
.divTableFoot {
background-color: #EEE;
display: table-footer-group;
font-weight: bold;
}
.divTableBody {
display: table-row-group;
}
</style>
<style>
.button.bino_btn {
background:none; border:none;
}
</style>
<div id="schema_head" hx-get="/mst/htmx/get_schema/7" hx-trigger="load" hx-target="#alldata" hx-swap="innerHTML" class="">
<b>Schema </b>
<button class="button.bino_btn" hx-get="/mst/htmx/get_schema/7" hx-trigger="click" hx-target="#alldata" hx-swap="innerHTML">Refresh</button>
</div>
<div id="table_for_schema" class="divTable">
<div class="divTableHeading">
<div class="divTableRow">
<div class="divTableHead">Nama Variabel</div>
<div class="divTableHead">Label</div>
<div class="divTableHead">Tipe</div>
<div class="divTableHead">Format</div>
</div>
</div>
<div id="alldata" class="divTableBody"><div id="31d6fa45-e660-4983-bfcb-f5217fd26e16" class="divTableRow">
<div class="divTableCell">
<input type="hidden" name="varname_31d6fa45-e660-4983-bfcb-f5217fd26e16" value="date">
date
</div>
<div class="divTableCell">
<input type="text" name="varlabel_31d6fa45-e660-4983-bfcb-f5217fd26e16" value="None" class="vTextField" maxlength="20">
</div>
<div class="divTableCell">
<select name="vartype_31d6fa45-e660-4983-bfcb-f5217fd26e16">
<option value="1">
Integer</option>
<option value="2" selected="">
String</option>
<option value="3">
Date</option>
</select>
</div>
<div class="divTableCell">
<input type="text" name="varformat_31d6fa45-e660-4983-bfcb-f5217fd26e16" class="vTextField" maxlength="20">
</div>
</div>
<div id="0bffd751-79a3-4561-b62f-dc254e2bbaac" class="divTableRow">
<div class="divTableCell">
<input type="hidden" name="varname_0bffd751-79a3-4561-b62f-dc254e2bbaac" value="invoiceNumber">
invoiceNumber
</div>
<div class="divTableCell">
<input type="text" name="varlabel_0bffd751-79a3-4561-b62f-dc254e2bbaac" value="None" class="vTextField" maxlength="20">
</div>
<div class="divTableCell">
<select name="vartype_0bffd751-79a3-4561-b62f-dc254e2bbaac">
<option value="1">
Integer</option>
<option value="2" selected="">
String</option>
<option value="3">
Date</option>
</select>
</div>
<div class="divTableCell">
<input type="text" name="varformat_0bffd751-79a3-4561-b62f-dc254e2bbaac" class="vTextField" maxlength="20">
</div>
</div>
<div id="cc528860-3855-4645-bd3f-948e297bda76" class="divTableRow">
<div class="divTableCell">
<input type="hidden" name="varname_cc528860-3855-4645-bd3f-948e297bda76" value="company">
company
</div>
<div class="divTableCell">
<input type="text" name="varlabel_cc528860-3855-4645-bd3f-948e297bda76" value="None" class="vTextField" maxlength="20">
</div>
<div class="divTableCell">
<select name="vartype_cc528860-3855-4645-bd3f-948e297bda76">
<option value="1">
Integer</option>
<option value="2" selected="">
String</option>
<option value="3">
Date</option>
</select>
</div>
<div class="divTableCell">
<input type="text" name="varformat_cc528860-3855-4645-bd3f-948e297bda76" class="vTextField" maxlength="20">
</div>
</div>
<div id="66971274-8d70-4766-8254-996bda8991b0" class="divTableRow">
<div class="divTableCell">
<input type="hidden" name="varname_66971274-8d70-4766-8254-996bda8991b0" value="total">
total
</div>
<div class="divTableCell">
<input type="text" name="varlabel_66971274-8d70-4766-8254-996bda8991b0" value="None" class="vTextField" maxlength="20">
</div>
<div class="divTableCell">
<select name="vartype_66971274-8d70-4766-8254-996bda8991b0">
<option value="1">
Integer</option>
<option value="2" selected="">
String</option>
<option value="3">
Date</option>
</select>
</div>
<div class="divTableCell">
<input type="text" name="varformat_66971274-8d70-4766-8254-996bda8991b0" class="vTextField" maxlength="20">
</div>
</div>
<div id="01ed7377-b526-4acf-a556-b87a1012091f" class="divTableRow">
<div class="divTableCell">
<input type="hidden" name="varname_01ed7377-b526-4acf-a556-b87a1012091f" value="items">
items
</div>
<div class="divTableCell">
<input type="text" name="varlabel_01ed7377-b526-4acf-a556-b87a1012091f" value="None" class="vTextField" maxlength="20">
</div>
<div class="divTableCell">
<select name="vartype_01ed7377-b526-4acf-a556-b87a1012091f">
<option value="1">
Integer</option>
<option value="2" selected="">
String</option>
<option value="3">
Date</option>
</select>
</div>
<div class="divTableCell">
<input type="text" name="varformat_01ed7377-b526-4acf-a556-b87a1012091f" class="vTextField" maxlength="20">
</div>
</div>
</div>
<!--div id="alldata" hx-get="/mst/htmx/get_schema/7" hx-trigger="load" hx-swap="beforeend" class="divTableBody">
</div-->
</div>
<div class="submit-row">
<input type="submit" value="Save" class="default" name="_save">
<p class="deletelink-box">Delete</p>
<input type="submit" value="Save and add another" name="_addanother">
<input type="submit" value="Save and continue editing" name="_continue">
</div>
<script id="django-admin-form-add-constants" src="/static/admin/js/change_form.js" async="">
</script>
<script id="django-admin-prepopulated-fields-constants" src="/static/admin/js/prepopulate_init.js" data-prepopulated-fields="[]">
</script>
</div>
</form></div>
<br class="clear">
</div>
<!-- END Content -->
<div id="footer"></div>
</div>
</div>
</div>
<!-- END Container -->
</body></html>
it's clear that all additional field is between form tags.
And here is my MailTemplateForm class
class MailTemplateForm(forms.ModelForm):
def clean(self):
cleaned_data = super().clean()
print(f'Cleaned Data:\n{cleaned_data}\n-------')
class Meta:
model = MailTemplate
fields = '__all__'
see that currently for all additional fields I only want to debug print it .
When I edit one of additional field and do save, I only got
Cleaned Data:
{'name': 'docx01', 'tfile': <FieldFile: uploads/mailtemplate/invoice-template_BCpUuSw.docx>}
-------
[16/Jan/2023 05:11:35] "POST /admin/myapp/mailtemplate/7/change/ HTTP/1.1" 302 0
[16/Jan/2023 05:11:35] "GET /admin/myapp/mailtemplate/ HTTP/1.1" 200 6823
[16/Jan/2023 05:11:35] "GET /admin/jsi18n/ HTTP/1.1" 200 3141
So, my question is:
How to read all the additional data in forms.py?
Kindly please give me any clue.
Sincerely
bino

How is it possible to get data from one form that has multiple textareas in Django

I'd like to get data from one form that has multiple textareas inside , In my views: 'compare_ingredients' I've tried requesting data from my form id 'compareform' also the textarea id 'ingredients', but when I enter something into one texture and click on submit it comes back as 'None' when I print. Here is my html and views:
html :
<div class="container-fluid">
<h4>Please enter in your ingredients:</h4>
<h6>(Seperate each item by comma)</h6>
<br>
<button class="add_item">Add Item</button>
<br>
<div class="row row-cols-1 row-cols-md-2 mx-auto">
<form action="{% url 'compare_ingredients' %}" method="POST" name="compareform" id="compare">
{% csrf_token %}
<br>
<button type="submit" class="btn btn-info sub_btn">Submit</button>
<button type="submit" class="btn btn-secondary back_button">
Back
</button>
<br>
<br>
<div class="row form_row">
<div class="col mb-4">
<h5>Item 1</h5>
<div class="card form_card">
<div class="card-body compare_cardbody">
<textarea name="ingredients1" id="ingredients" cols="30" rows="10" form="compareform"></textarea>
</div>
</div>
</div>
<div class="col mb-4">
<h5>Item 2</h5>
<div class="card form_card">
<div class="card-body compare_cardbody">
<textarea name="ingredients2" id="ingredients" cols="30" rows="10" form="compareform"></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
views.py:
def compare_ingredients(request):
if request.method == "POST":
ingredients = request.POST.get('compareform')
print(ingredients)
return render(request, 'result/compare.html')
ok, I figured it out , the problem was in the html textarea I had the name of the form as 'compareform' when it should have been 'compare' :
<textarea name="ingredients2" id="ingredients" cols="30" rows="10" form="compare"></textarea>
then in my views I did:
ingredients1 = request.POST.get('ingredients1')

Django Model Form not saving to database

I have the following ModelForm which when I use as below it is not saving to the database. I have tried other posts and answers on here but cannot get this to save.
If I use the same Class Base View (CreateView) and use the input of {{form}} in the HTML I can get this working and it saves to the database, but I need to have the form fields added separately in the HTML page as below that has been created for me with separate inputs.
The output of the post prints in the terminal ok, but then as mentioned not to the database.
Hope this all makes sense and thanks in advance for any help I can get on this.
models.py
class ASPBookings(models.Model):
program_types = (
('Athlete Speaker & Expert Program', 'Athlete Speaker & Expert Program'),
('Be Fit. Be Well', 'Be Fit. Be Well')
)
presentation_form_options = (
('Face to Face', 'Face to Face'),
('Virtual', 'Virtual'),
)
organisation_types = (
('Goverment School', 'Goverment School'),
('Community Organisation', 'Community Organisation'),
('Non-Goverment School', 'Non-Goverment School'),
('Other', 'Other')
)
contact_name = models.CharField(max_length=80)
program_type = models.CharField(max_length=120,choices=program_types)
booking_date = models.DateField()
booking_time = models.DateTimeField(default=datetime.now())
duration = models.CharField(max_length=10, default="1")
email = models.EmailField()
phone_number = models.CharField(max_length=120)
speaker_brief = models.TextField()
presentation_form = models.CharField(max_length=120, choices=presentation_form_options)
audience_number = models.CharField(max_length=10)
street = models.CharField(max_length=120)
suburb = models.CharField(max_length=120)
region = models.CharField(max_length=50, default="1")
post_code = models.CharField(max_length=40)
organisation_type = models.CharField(max_length=120,choices=organisation_types)
athlete = models.ForeignKey(Athlete, default="13", on_delete=models.CASCADE)
def __str__(self):
return self.contact_name
forms.py
class ASPBookingsForm(forms.ModelForm):
class Meta():
model = ASPBookings
fields = ('__all__')
views.py
class ASPBookingsCreateView(CreateView):
form_class = ASPBookingsForm
model = ASPBookings
template_name = "vistours/bookings_asp.html"
def post(self, request):
if request.method == 'POST':
form = self.form_class(request.POST)
print(request.POST)
if form.is_valid():
program_type = form.cleaned_data['prev_program']
booking_date = form.cleaned_data['prev_date']
booking_time = form.cleaned_data['prev_time']
duration = form.cleaned_data['prev_duration']
street = form.cleaned_data['street']
suburb = form.cleaned_data['suburb']
post_code = form.cleaned_data['postcode']
region = form.cleaned_data['region']
organisation_type = form.cleaned_data['org_type']
audience_number = form.cleaned_data['audience']
presentation_form = form.cleaned_data['presentation_form']
contact_name = form.cleaned_data['contact_name']
email = form.cleaned_data['email']
phone_number = form.cleaned_data['phone']
speaker_brief = form.cleaned_data['comments']
athlete = form.cleaned_data['athlete']
form.save()
return render(request, self.template_name)
HTML
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">
<title>Athlete Speaker Program</title>
<!-- VIS Branding -->
<link rel="stylesheet" type="text/css" href="{% static 'vistours/css/vis.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'vistours/css/number-input.css' %}">
<!-- JQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Bootstrap -->
<link href="{% static 'vistours/css/bootstrap.min.css' %}" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/js/bootstrap.min.js" integrity="sha384-nsg8ua9HAw1y0W1btsyWgBklPnCUAFLuTMS2G72MMONqmOymq585AcH49TLBQObG" crossorigin="anonymous"></script>
</head>
<body>
<form method="post" class="needs-validation" novalidate enctype="multipart/form-data">
{% csrf_token %}
<div class="container-fluid pt-3">
<!-- Nav Bar -->
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8"><img alt="VIS Logo" src="https://www.vis.org.au/theme/vis/img/logo.svg" style="height: 50px;" class="img-fluid"></div>
<div class="col-md-2"></div>
</div>
<!-- END Nav Bar -->
<div id="duration_container" class="row py-5">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="card">
<h5 class="card-header">Address & Organisation Type</h5>
<div class="card-body">
<h5 class="card-title">Please fill out the address fields</h5>
<p class="card-text">Uncheck the box below if you've already booked a session with us in an earlier date.</p>
<div class="form-floating mb-3">
<input type="text" required class="form-control" id="street" name="street" placeholder="Flinders Street" value={{street}} >
<label for="street">Street</label>
<div class="invalid-feedback">
Please enter a valid street name
</div>
</div>
<div class="form-floating mb-3">
<input type="text" required class="form-control" id="suburb" name="suburb" placeholder="Albert Park" value={{suburb}}>
<label for="suburb">Suburb</label>
<div class="invalid-feedback">
Please enter a valid suburb name
</div>
</div>
<div class="form-floating mb-3">
<input required oninput="this.value =
!!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null; if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
" type="number" min="0" max="9999" class="form-control" id="postcode" name="postcode" placeholder="3000" value={{post_code}}>
<label for="postcode">Post Code</label>
<div class="invalid-feedback">
Please enter a valid post code
</div>
</div>
<div class="form-floating mb-3">
<select class="form-select" id="region" name="region" aria-label="Region" value={{region}}>
<option value="1">Metro</option>
<option value="2" selected>Suburb</option>
</select>
<label for="region">Region</label>
</div>
<div class="form-floating mb-3">
<select class="form-select" id="org_type" name="org_type" aria-label="Organisation Type" value={{form.organisation_type}}>
<option value="1">Community organisation</option>
<option value="2">Corporation</option>
<option value="3" selected>Government school</option>
<option value="4">Non-Government school</option>
<option value="5">Other</option>
</select>
<label for="org_type">Organisation Type</label>
</div>
</div>
</div>
</div>
<div class="col-md-2">
</div>
</div>
<!-- Next Button DIV -->
<div class="row">
<div class="col-2">
</div>
<div class="col-8">
Next
</div>
<div class="col-2"></div>
</div>
<!-- END Next Button DIV -->
<div class="col-xs-12" style="height:350px;"></div>
<!--Time Container Blank Space-->
<div id="time_container" class="row py-5">
<div class="col-md-2"></div>
<div class="col-md-8">
</div>
<div class="col-md-2"></div>
</div>
<!--END Time Container Blank Space-->
<!-- Time Slots -->
<div class="row pb-5">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="card">
<h5 class="card-header">Audience</h5>
<div class="card-body">
<h5 class="card-title">Audience Number</h5>
<p class="card-text">How many people will be attending this conference</p>
<div class="form-floating mb-3">
<input required oninput="this.value =
!!this.value && Math.abs(this.value) >= 0 ? Math.abs(this.value) : null;if(this.value<0){this.value= this.value =0} else if(this.value>9999){this.value= this.value =9999}
" type="number" min="0" max="9999" class="form-control" id="audience" name="audience" placeholder="0 - 9999" value={{audience_number}}>
<label for="audience">Audience Number</label>
<div class="invalid-feedback">
Please enter a valid audience number
</div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
</div>
</div>
<!-- Next Button DIV -->
<div class="row">
<div class="col-2">
</div>
<div class="col-8">
Next
</div>
<div class="col-2"></div>
</div>
<!-- END Next Button DIV -->
<div class="col-xs-12" style="height:350px;"></div>
<!--END Time Slots-->
<!--Date Container Blank Space-->
<div id="date_container" class="row py-5">
<div class="col-md-2"></div>
<div class="col-md-8">
</div>
<div class="col-md-2"></div>
</div>
<!--END Date Container Blank Space-->
<div class="row pb-5">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="card">
<h5 class="card-header">Contact Information</h5>
<div class="card-body">
<h5 class="card-title">Contact info and speaker brief</h5>
<p class="card-text">
Please fill out the contact form and explain what function/class the speaker will be presenting to, what topics you would like the speaker to cover and if you have any requests for type of speaker (male/female/sport/para athlete, etc.) under <em>Speaker Brief</em> section.</p>
<div class="form-floating mb-3">
<select class="form-select" id="presentation_form" name="presentation_form" aria-label="Presentation Form" value={{presentation_form}}>
<option value="1" selected>Face-to-Face</option>
<option value="2">Virtual</option>
</select>
<label for="presentation_form">Preferred Presentation Form</label>
</div>
<div class="form-floating mb-3">
<input required type="text" class="form-control" id="contact_name" name="contact_name" placeholder="John Doe" value={{contact_name}}>
<label for="contact_name">Contact Name</label>
<div class="invalid-feedback">
Please enter a valid contact name
</div>
</div>
<div class="form-floating mb-3">
<input required type="text" class="form-control" id="athlete" name="athlete" placeholder="Athlete Name" value={{athlete}}>
<label for="contact_name">Athlete Name</label>
<div class="invalid-feedback">
Please enter a valid contact name
</div>
</div>
<div class="form-floating mb-3">
<input required type="email" class="form-control" id="email" name="email" placeholder="name#example.com" value={{email}}>
<label for="email">Email</label>
<div class="invalid-feedback">
Please enter a valid email address
</div>
</div>
<div class="form-floating mb-3">
<input required pattern="^((\+61\s?)?(\((0|02|03|04|07|08)\))?)?\s?\d{1,4}\s?\d{1,4}\s?\d{0,4}$" type="text" class="form-control" id="phone" name="phone" placeholder="0400 000 000" value={{phone_number}}>
<label for="phone">Phone</label>
<div class="invalid-feedback">
Please enter a valid phone number
</div>
</div>
<div class="form-floating">
<textarea required class="form-control" placeholder="Leave a comment here" id="comments" name="comments" maxlength="500" value={{speaker_brief}}></textarea>
<label for="comments">Speaker Brief (Max 500 Characters)</label>
<div class="invalid-feedback">
Please explain the topics you want the speaker to present
</div>
</div>
</div>
</div>
</div>
<div class="col-md-2">
</div>
</div>
<!-- Form Validation Alert Box -->
<div class="row py-3" id="alert_box" style="visibility: hidden;">
<div class="col-2">
</div>
<div class="col-8">
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong>Oops!</strong> Some of the fields above need to be reviewed.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</div>
<div class="col-2">
</div>
</div>
<!-- END Form Validation Alert Box -->
<!-- Submit Button DIV -->
<div class="row">
<div class="col-2">
</div>
<div class="col-8 d-flex flex-row-reverse">
<input type="submit" name="submit" class="btn btn-primary" value="Submit">
</div>
<div class="col-2">
</div>
</div>
<!-- END Submit Button DIV -->
<div class="col-xs-12" style="height:200px;"></div>
</div>
<!-- hidden inputs -->
<div style="display: none; visibility: hidden;">
<input type="text" name="prev_time" id="prev_time">
<input type="text" name="prev_date" id="prev_date">
<input type="text" name="prev_duration" id="prev_duration">
<input type="text" name="prev_program" id="prev_program">
</div>
</form>
<script src="{% static 'vistours/js/form-validation.js' %}"></script>
<script>
document.getElementById("prev_time").value = sessionStorage.getItem('time');
document.getElementById("prev_date").value = sessionStorage.getItem('date');
document.getElementById("prev_duration").value = sessionStorage.getItem('duration');
document.getElementById("prev_program").value = sessionStorage.getItem('program');
</script>
</body>
</html>
I think your form might be invalid. Try to print form.errors in the else statement corresponding to your if form.is_valid() statement.
One other suggestion is to use Django form to generate the html instead of generating everything by yourself (which is prone to errors and hard to manage). You can still keep the form fields separated. Check out the URL below:
https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html#accessing-the-form-fields-individually

'stripeToken' error when attempting to submit payment form

I'm following an outdate django e-commerce course using django and stripe. The course is about 4 years old so a lot has changed with django and stripe, which has allowed me to do a ton of research on both. I'm at the end of the tutorial and have run into an issue while creating the checkout page and more importantly using stripe to 'Create Charge'. I am receiving the following error message:
django.utils.datastructures.MultiValueDictKeyError
django.utils.datastructures.MultiValueDictKeyError: 'stripeToken'
I read in the documentation for Creating Charge which states
token = request.POST['stripeToken'] # Using Flask
is for Flask (I think), however when i remove ['stripeToken'], I receive this error message:
stripe.error.InvalidRequestError stripe.error.InvalidRequestError:
Request req_kikB88HKbEkq9W: Could not find payment information
I need a way to pass Stripe the payment information when the form is submitted. Also, I came across this post but the publisher was receiving error message do to multiple forms
view.py
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
# Create your views here.
#login_required
def checkout(request):
publish_key = settings.STRIPE_PUBLISHABLE_KEY
if request.method == 'POST':
token = request.POST['stripeToken']
stripe.Charge.create(
amount=999,
currency='usd',
description='Example charge',
source=token,
statement_descriptor='Custom descriptor',
)
context = {'publish_key': publish_key}
template = 'checkout.html'
return render(request, template, context)
checkout.html
{% extends 'base.html' %}
{% block content %}
<div class="col-sm-6 offset-md-3">
<h4 class="mb-3">Billing address</h4>
<form id="payment-form" action="" method="post">{% csrf_token %}
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName">First name</label>
<input type="text" class="form-control" id="firstName" required style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHklEQVQ4EaVTO26DQBD1ohQWaS2lg9JybZ+AK7hNwx2oIoVf4UPQ0Lj1FdKktevIpel8AKNUkDcWMxpgSaIEaTVv3sx7uztiTdu2s/98DywOw3Dued4Who/M2aIx5lZV1aEsy0+qiwHELyi+Ytl0PQ69SxAxkWIA4RMRTdNsKE59juMcuZd6xIAFeZ6fGCdJ8kY4y7KAuTRNGd7jyEBXsdOPE3a0QGPsniOnnYMO67LgSQN9T41F2QGrQRRFCwyzoIF2qyBuKKbcOgPXdVeY9rMWgNsjf9ccYesJhk3f5dYT1HX9gR0LLQR30TnjkUEcx2uIuS4RnI+aj6sJR0AM8AaumPaM/rRehyWhXqbFAA9kh3/8/NvHxAYGAsZ/il8IalkCLBfNVAAAAABJRU5ErkJggg=="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;" required/>
<div class="invalid-feedback">
Valid first name is required.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastName">Last name</label>
<input type="text" class="form-control" id="lastName" required />
<div class="invalid-feedback">
Valid last name is required.
</div>
</div>
</div>
<div class="mb-3">
<label for="email">Email <span class="text-muted"></span></label>
<input type="email" class="form-control" id="email" placeholder="you#example.com" required />
<div class="invalid-feedback">
Please enter a valid email address for shipping updates.
</div>
</div>
<div class="mb-3">
<label for="address">Address</label>
<input type="text" class="form-control" id="address" placeholder="1234 Main St" required />
<div class="invalid-feedback">
Please enter your shipping address.
</div>
</div>
<div class="mb-3">
<label for="address2">Address 2 <span class="text-muted"></span></label>
<input type="text" class="form-control" id="address2" placeholder="Apartment or suite" />
</div>
<div class="row">
<div class="col-md-5 mb-3">
<label for="city">City</label>
<input type="text" class="form-control" id="city" required />
<div class="invalid-feedback">
Zip code required.
</div>
</div>
<div class="col-md-4 mb-3">
<label for="state">State</label>
<select class="custom-select d-block w-100" id="state" required>
<option value="">Choose...</option>
<option>California</option>
</select>
<div class="invalid-feedback">
Please provide a valid state.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="zip">Zip</label>
<input type="text" class="form-control" id="zip" required />
<div class="invalid-feedback">
Zip code required.
</div>
</div>
</div>
<hr class="mb-4">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="same-address">
<label class="custom-control-label" for="same-address">Shipping address is the same as my billing address</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="save-info">
<label class="custom-control-label" for="save-info">Save this information for next time</label>
</div>
<hr class="mb-4">
<h4 class="mb-3">Payment</h4>
<div class="d-block my-3">
<label for="card-element">Credit or debit card</label>
<div id="card-element" class="form-control" style='height: 2.4em; padding-top: .7em;'>
<!-- A Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<hr class="mb-4">
<button class="btn btn-outline-success btn-lg btn-block" type="submit">Continue to checkout</button>
</form>
</div>
{% endblock %}
app.js
// Create a Stripe client.
const stripe = Stripe('{{ publish_key }}');
// Create an instance of Elements.
const elements = stripe.elements();
// Create an instance of the card Element.
const card = elements.create('card', {});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', ({error}) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
// Create a token or display an error when the form is submitted.
const form = document.getElementById('payment-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const {token, error} = await stripe.createToken(card);
if (error) {
// Inform the customer that there was an error.
const errorElement = document.getElementById('card-errors');
errorElement.textContent = error.message;
} else {
// Send the token to your server.
stripeTokenHandler(token);
}
});
// Submit the form with the token ID.
const stripeTokenHandler = (token) => {
// Insert the token ID into the form so it gets submitted to the server
const form = document.getElementById('payment-form'),
hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}

Django image upload with js plugin issue

I am using js plugin to upload image, first time when i select image from the plugin the form gets submitted. The issue is that i select the image first time but then i don't want that image and i click on it again to upload another image, the form does not get validated and fails to submit.
views.py
class SelectObituaryView(LoginRequiredMixin, TemplateView):
template_name = "website/obituary_select.html"
def get_context_data(self, **kwargs):
context = super(SelectObituaryView, self).get_context_data(**kwargs)
church_id = self.request.session.get('church_id', None)
if church_id:
samples = ObituarySample.objects.filter(organization__id=church_id)
context['obituary_samples'] = samples
context['church_cover'] = self.request.session.get('church_cover', None)
return context
#transaction.atomic
def post(self, request):
print("Entered function")
try:
data = request.POST.copy()
data['organization'] = request.session.get('church_id', None)
data['slug'] = data['name'].replace(' ', '-')
data['funeral_time'] = data['funeral_time'].replace(" ", "")
data['viewing_time'] = data['viewing_time'].replace(" ", "")
if len(request.FILES.getlist('gallery')) > 10:
messages.error(request, "Max gallery images limit exceeded.")
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
obituary_form = ObituaryForm(data=data, files=request.FILES)
# print("obituary form data",data)
print("before is valid")
if obituary_form.is_valid():
print("Inside is_valid")
obituary_instance = obituary_form.save(commit=False)
obituary_instance.image = obituary_instance.obituary_sample.background
obituary_instance.user = request.user
obituary_instance.save()
obituary_instance.update_slug_with_id()
#override profile_image
#imageName = os.path.basename(obituary_instance.profile_image.path)
imgArr = os.path.split(obituary_instance.profile_image.path)
image_data = request.POST['profile_image1']
b = json.loads(image_data)
head, data = b["output"]["image"].split(',')
binary_data = a2b_base64(data)
print(binary_data)
with open(obituary_instance.profile_image.path, 'wb+') as fh:
myfile = File(fh)
myfile.write(binary_data)
imprinted_image_path = apps.obituary.utils.imprint(obituary_instance, obituary_instance.obituary_sample)
# Save imprinted image in db
with open(imprinted_image_path, 'rb') as f:
data = f.read()
file_postfix = datetime.now().strftime("%Y%m%d-%H%M%S")
obituary_instance.image.save("%s%s.jpg" % ('obituary', file_postfix), ContentFile(data))
for gallery_image in request.FILES.getlist('gallery'):
GalleryImage.objects.create(obituary=obituary_instance, image=gallery_image)
return HttpResponseRedirect(reverse('obituary:preview', kwargs={'obituary_id': obituary_instance.id}))
else:
print("else")
messages.error(request, constants.OPERATION_UNSUCCESSFUL)
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
except Exception as e:
print(e)
print("except")
messages.error(request, "Unable to create, Please try again.")
return HttpResponseRedirect(
reverse('obituary:create', kwargs={'sample_obituary_id': request.POST.get('obituary_sample')}))
html
{% extends "website/base.html" %}
{% load static %}
{% block javascript %}
<script>
// Submit post on submit
{# $('#create_obit').on('submit', function(event){#}
{# event.preventDefault();#}
{# alert("Aamixsh");#}
{# });#}
$("#create_obit").submit(function(evt){
//evt.preventDefault();
if($(this).find('input[name="profile_image"]').val() != "") {
$(this).find('input[name="profile_image"]').attr('name','profile_image1');
$(this).find(".slim").find('input[type="file"]').attr('name','profile_image');
return true;
}
});
$(document).ready(function(){
$('input[type="text"]').attr( 'autocomplete', 'off' );
$('.dateReadonly').attr( 'readonly', 'true' );
});
</script>
{% endblock %}
{% block body_block %}
<!-- Banner Area Start -->
<div class="banner-area">
<div class="overlay"></div>
<div class="img-holder">
<div class="holder"><img src="{{ church_cover }}" alt=""></div>
</div>
<div class="caption">
<div class="holder">
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="banner">
<h2>Fill in Loved Ones Details</h2>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section-space">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="row">
<h3 class="heading-title">Create an Obituary</h3>
<form class="setting-form" id="create_obit" action="{% url 'obituary:select' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<fieldset>
<div class="col-xs-12">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Name: <input type="text" maxlength="50" name="name" placeholder="Name*" class="form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Funeral Address: <input type="text" maxlength="50" name="address" placeholder="Funeral Address*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Date of Birth: <input type="text" id="datepicker1" name="date_of_birth" placeholder="Date of Birth*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Date of Death: <input type="text" id="datepicker2" name="date_of_death" placeholder="Date of Death*" class="dateReadonly form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Funeral Date: <input type="text" name="funeral_date" id="datepicker3" placeholder="Funeral Date*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Funeral Time: <input type="text" name="funeral_time" id="timepicker" placeholder="Funeral Time*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Surviving Family: <input type="text" maxlength="100" name="family_info" placeholder="spouse Mary Louise, and sons Joe, Ed, and Tim, etc. (Max Limit: 100 Characters)" class="form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Ways To Contribute: <input type="text" maxlength="40" name="memorial_donation_info" placeholder="e.g. Donation url or other Information* (Max Limit: 40 Characters)" class="form-control input-field" >
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Viewing Date: <input type="text" name="viewing_date" id="datepicker4" placeholder="Viewing Date*" class="dateReadonly form-control input-field" required>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
Viewing Time: <input type="text" name="viewing_time" id="timepicker2" placeholder="Viewing Time*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
Viewing Address: <input type="text" maxlength="50" name="viewing_address" placeholder="Viewing Address*" class="form-control input-field" required>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
Message: <textarea maxlength="500" name="message" id="" cols="30" rows="10" class="form-control input-field" placeholder="Message* (Max Limit: 500 Characters)" required></textarea>
</div>
</div>
</div>
<input type="hidden" name="obituary_sample" value="{{ obituary_form.obituary_sample.value }}" />
</div>
<div class="col-sm-12">
<h3>Upload Obituary Photo</h3>
<div class = "form-group">
Maximum image size is 8 MB. You can rotate and crop the uploaded image by using the control buttons at the bottom of the image.
<!-- original <input type="file" name="profile_image" placeholder="Obituary Image*" class="form-control input-field" required> -->
<input type="file" name="profile_image" placeholder="Obituary Image*" class="slim" required>
</div>
</div>
<div class="col-xs-12">
<h3>Upload Gallery Photos</h3>
<div class="dropzone" id="my-awesome-dropzone">
<div class="fallback">
(Maximum image size should be 8 MB)
<input type="file" name="gallery" multiple class="form-control input-field"/>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<input type="checkbox" onchange="document.getElementById('create').disabled = !this.checked;" /> I understand, that the obituary cannot be edited once paid for!
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<button type="submit" id="create" class="btn send-btn" disabled>Create</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}