Paginate through json data with Flask - python

I am using flask and generate tables that are filled with the JSON data that I retrieve. The problem that I have now is that I need to paginate through all the JSON data, because the maximum per page is set at '50'and I want to show all the products in my table.
So far I can't get this working and I don't really know how to get it working with Flask. I tried using a while loop, but that doesn't work with Jinja2 because that command is not recognized.
This is my Python code:
#app.route('/products',methods = ['POST', 'GET'])
def products():
shopnaam = request.form['shopname']
username = request.form['username']
password = request.form['password']
login = 'https://'+shopnaam+'example.com'
url = 'https://'+shopnaam+'.example.com/admin/products.json'
payload = {
'login[email]': username,
'login[password]': password
}
with requests.Session() as session:
post = session.post(login, data=payload)
r = session.get(url)
parsed = json.loads(r.text)
return render_template('producten.html',parsed = parsed)
This is my Jinja2 code:
<button class="collapsible">Bekijk product Informatie</button>
<div class="content">
<table id = "productentabel">
<tr class = "header">
<th>ID</th>
<th>Titel </th>
<th>Prijs Exclusief BTW</th>
<th>Prijs Inclusief BTW</th>
<th>Datum</th>
{% for product in parsed['products'] %}
<TR>
<TD width="100px" >{{product['id']}}</TD>
<TD width="300px" >{{product['nl']['title']}}</TD>
<TD width="150px">{{product['price_excl']}}</TD>
<TD width="150px">{{product['price_incl']}}</TD>
<TD width="300px">{{product['created_at']}}</TD>
</TR>
</tr>
{% endfor %}
</table>
<input class = "exportknop" value="Exporteer product informatie" type="button" onclick="$('#productentabel').table2CSV({header:['ID','Titel','Prijs Exclusief BTW', 'Prijs Inclusief BTW', 'Datum']})">
</div>
As you can see I am using a for loop, this code works, but the pagination is the issue.
My JSON looks like this:
products: [
{
article_code: "123",
barcode: "456",
brand_id: 2600822,
created_at: "2018-05-31T15:15:34+02:00",
data01: "",
data02: "",
data03: "",
delivery_date_id: null,
has_custom_fields: false,
has_discounts: false,
has_matrix: false,
hits: 0,
hs_code: null,
id: 72660113,
image_id: null,
is_visible: false,
price_excl: 33.0165,
price_incl: 39.95,
price_old_excl: 0,
price_old_incl: 0,
product_set_id: null,
product_type_id: null,
search_context: "123 456 789",
shop_id: 252449,
sku: "789",
supplier_id: 555236,
updated_at: "2018-05-31T15:15:34+02:00",
variants_count: 1,
visibility: "hidden",
weight: 0,
links: {
first: ".json",
last: ".json?page=70",
prev: null,
next: ".json?page=2",
count: 3497,
limit: 50,
pages: 70
}
So links is where the pagination happens, I tried the following in my Python code and with this I get all the values printed in my python terminal. Only I can't send the data to the tables.
while url:
with requests.Session() as session:
post = session.post(login, data=payload)
r = session.get(url)
parsed = json.loads(r.text)
for product in parsed['products']:
print(product['id'], product['nl']['title'])
url = 'https://example/admin/products' + parsed['links']['next']

So a couple things to consider here. First, using a generator to create web content is going to be next to impossible outside of a websocket or async calls. The reason is that WSGI needs all the data to come before it renders. Then it closes the connection. You can yield data, but in a table, this is going to cause problems in raw html.
What to do:
I would use something like datatables (datatables.net) feed your table data into a variable, and let datatables handle the pagination for you.
Example using Bootstrap 4 and DataTables.
<script>
var dataSet = []
var wurl = ""
tablex = $('#tablex').dataTable( {
select: true,
stateSave: true,
colReorder: true,
deferRender: true,
"oLanguage": {"sSearch": "Filter:"},
columns: [
{ title: "Number" },
{ title: "Client Name" },
{ title: "Opened" },
{ title: "Closed" },
{ title: "Worked" }
]
} );
function generate() {
$.get(wurl, function( data ) {
dataSet = data;
tablex.fnDestroy();
tablex = $('#tablex').dataTable( {
data: dataSet,
select: true,
stateSave: true,
colReorder: true,
deferRender: true,
"oLanguage": {"sSearch": "Filter:"},
columns: [
{ title: "Number" },
{ title: "Client Name" },
{ title: "Opened"},
{ title: "Closed"},
{ title: "Worked"}
],
} );
});
};
$(document).ready(function() {
wurl = '/api/getdata';
generate()
} );
</script>
I first establish just a base table, and then I call an API and load that table with data in the background. You could even have this poll and refresh the dataset on an interval if you wanted. The API just delivers the raw data in a column output.
Your table id is "tablex" in this example.
Your API route can be anything, just a return value of your output that is in column and row format.

Related

Django - How to obtain corresponding row values from el-table after performing row-click?

I created a table in Django where upon doing row-click, the records for the corresponding row should be POSTED to the function "medicineRequestSelect" in view_doctor.py. However, it is unable to extract that row of values as shown in Image 1. It returns me None values.
I am relatively new to web development and any help or advice will be greatly appreciated!
<doctor_emr.html>
{% block mainbody%}
{% verbatim %}
<div id="app2" class="container">
<div class="emr-table">
<el-table
ref="multipleTable"
:data="list"
stripe
style="width: 50%"
#row-click="handle"
#selection-change="handleSelectionChange">
<el-table-column
prop="id"
label="Index">
</el-table-column>
<el-table-column
prop="order_id"
label="Order ID">
</el-table-column>
<el-table-column
prop="ward_number"
label="Ward No.">
</el-table-column>
<el-table-column
prop="prop"
label="Scan QR"
width="width">
<template slot-scope="{row$index}">
<el-button #click="onScanQR(row)" type="warning" icon="el-icon-camera" size="mini">Scan</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
{% endverbatim %}
<script>
new Vue({
el: '#app2',
data() {
return {
list: []
}
},
mounted() {
this.getemrList()
},
methods: {
getemrList() {
// Obtain EMR list
axios.post(ToDJ('emrList'), new URLSearchParams()).then(res => {
if (res.data.code === 0) {
console.log(res.data.data)
this.list = res.data.data
} else {
this.NotifyFail(res.data.data)
}
})
},
// Purpose: For the row click
handle(row, event, column) {
console.log(row, event, column)
axios.post(ToDJ('medicineRequestSelect'), new URLSearchParams()).then(res => {
if (res.data.code === 0) {
console.log(res.data.data)
this.list = res.data.data
let index = this.list.findIndex(item => {
return item.id == row.id
})
if (index == -1) {
this.$refs.multipleTable.toggleRowSelection(row, true);
this.list.push(row)
} else {
this.$refs.multipleTable.toggleRowSelection(row, false);
this.list.splice(index, 1)
}
} else {
this.NotifyFail(res.data.data)
}
})
},
onScanQR(row) {
this.dialogFormVisible = true;
this.tmForm={...row}
},
// Success notification
NotifySuc(str) {
this.$message({
message: str,
type: 'success'
})
},
// Error notification
NotifyFail(str) {
this.$message({
message: str,
type: 'warning'
})
}
}
})
</script>
{% endblock %}
<view_doctor.py>
#api_view(['GET',"POST"])
def medicineRequestSelect(request):
id = request.POST.get('id')
order_id = request.POST.get('order_id')
ward_number = request.POST.get('ward_number')
print("Values: ", id, order_id, ward_number)
return Action.success()
Image 1: Output Obtained
Image 2: Table I created
I'm also learning, and I try to progress by trying to help other's problem.
First where are you getting your data's from? From your Models?
So if I understood correctly you should import the model you want your data from and then make queries to it using your model.
model = TheNameOfYourModel.objects.all()
and then you can make your queries using q
PS: I'm still learning, i'm curious to see the answer of someone experienced

How to return JSON from FastAPI (backend) with websocket to Vue (frontend)?

I have an application, in which the frontend is implemented in Vue and the backend uses FastAPI framework. The communication is achieved through websockets.
Currently, the frontend allows the user to enter a term, which is sent to the backend to generate the autocomplete and also perform a search on a URL that returns a JSON object. In which, I save this JSON object in the frontend folder. After that, the backend returns the autocomplete data for the term in question to the frontend. The frontend displays the aucomplete along with the json data.
However, when I studied a little more, I noticed that there is a way to send the JSON returned by the request URL to Vue (frontend), without having to save it locally, avoiding giving an error of not allowing to execute this process more than once.
My current code is as follows. For FastAPI (backend):
#app.websocket("/")
async def predict_question(websocket: WebSocket):
await websocket.accept()
while True:
input_text = await websocket.receive_text()
autocomplete_text = text_gen.generate_text(input_text)
autocomplete_text = re.sub(r"[\([{})\]]", "", autocomplete_text)
autocomplete_text = autocomplete_text.split()
autocomplete_text = autocomplete_text[0:2]
resp = req.get('www.description_url_search_='+input_text+'')
datajson = resp.json()
with open('/home/user/backup/AutoComplete/frontend/src/data.json', 'w', encoding='utf-8') as f:
json.dump(datajson, f, ensure_ascii=False, indent=4)
await websocket.send_text(' '.join(autocomplete_text))
File App.vue (frontend):
<template>
<div class="main-container">
<h1 style="color:#0072c6;">Title</h1>
<p style="text-align:center; color:#0072c6;">
Version 0.1
<br>
</p>
<Autocomplete />
<br>
</div>
<div style="color:#0072c6;">
<JsonArq />
</div>
<div style="text-align:center;">
<img src="./components/logo-1536.png" width=250 height=200 alt="Logo" >
</div>
</template>
<script>
import Autocomplete from './components/Autocomplete.vue'
import JsonArq from './components/EstepeJSON.vue'
export default {
name: 'App',
components: {
Autocomplete,
JsonArq: JsonArq
}
}
</script>
<style>
.main-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
font-family: 'Fredoka', sans-serif;
}
h1 {
font-size: 3rem;
}
#import url('https://fonts.googleapis.com/css2?family=Fredoka&display=swap');
</style>
Autocomplete.vue file in the components directory:
<template>
<div class="pad-container">
<div tabindex="1" #focus="setCaret" class="autocomplete-container">
<span #input="sendText" #keypress="preventInput" ref="editbar" class="editable" contenteditable="true"></span>
<span class="placeholder" contenteditable="false">{{autoComplete}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'Autocomplete',
data: function() {
return {
autoComplete: "",
maxChars: 75,
connection: null
}
},
mounted() {
const url = "ws://localhost:8000/"
this.connection = new WebSocket(url);
this.connection.onopen = () => console.log("connection established");
this.connection.onmessage = this.receiveText;
},
methods: {
setCaret() {
const range= document.createRange()
const sel = window.getSelection();
const parentNode = this.$refs.editbar;
if (parentNode.firstChild == undefined) {
const emptyNode = document.createTextNode("");
parentNode.appendChild(emptyNode);
}
range.setStartAfter(this.$refs.editbar.firstChild);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
},
preventInput(event) {
let prevent = false;
// handles capital letters, numbers, and punctuations input
if (event.key == event.key.toUpperCase()) {
prevent = true;
}
// exempt spacebar input
if (event.code == "Space") {
prevent = false;
}
// handle input overflow
const nChars = this.$refs.editbar.textContent.length;
if (nChars >= this.maxChars) {
prevent = true;
}
if (prevent == true) {
event.preventDefault();
}
},
sendText() {
const inputText = this.$refs.editbar.textContent;
this.connection.send(inputText);
},
receiveText(event) {
this.autoComplete = event.data;
}
}
}
</script>
EstepeJSON.ue file in the components directory:
<template>
<div width="80%" v-for="regList in myJson" :key="regList" class="container">
<table>
<thead>
<tr>
<th>Documento</th>
</tr>
</thead>
<tbody>
<tr v-for="countryList in regList[2]" :key="countryList">
<td style="visibility: visible">{{ countryList}}</td>
</tr>
</tbody>
</table>
</div>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
/>
</template>
<script>
import json from "#/data.json";
export default {
name: "EstepeJson",
data() {
return {
myJson: json,
};
},
};
</script>
Example of the JSON returned by the URL:
[
{
"Title": "SOFT-STARTER",
"Cod": "Produto: 15775931",
"Description": "A soft-starter SSW7000 permite o controle de partida/parada e proteção de motores.",
"Technical_characteristics": ["Corrente nominal", "600 A", "Tensão nominal", "4,16 kV", "Tensão auxiliar", "200-240 V", "Grau de proteção", "IP41", "Certificação", "CE"]
},
{
"Title": "SOFT-STARTER SSW",
"Cod": "Produto: 14223395",
"Description": "A soft-starter SSW7000 permite o controle de partida/parada e proteção de motores de indução trifásicos de média tensão.",
"Technical_characteristics": ["Corrente nominal", "125 A", "Tensão nominal", "6,9 kV", "Tensão auxiliar", "200-240 V", "Grau de proteção", "IP54/NEMA12", "Certificação", "CE"]
}
]
Just convert your data to a json string with json.dumps(mydata)
using #Chris' tips on HTTP and after some research I managed to solve my problem. Below is the resolution.
In my backend FastAPI file I implemented HTTPX async (tip from #Chris). And after returning the JSON, I took the autocomplete term and added it to the first position of the JSON. Thus returning to Vue (frontend) a JSON with autocomplete and HTTPX data.
File FastAPI:
async def predict_question(websocket: WebSocket):
await manager.connect(websocket)
input_text = await websocket.receive_text()
if not input_text:
await manager.send_personal_message(json.dumps([]), websocket)
else:
autocomplete_text = text_gen.generate_text(input_text)
autocomplete_text = re.sub(r"[\([{})\]]", "", autocomplete_text)
autocomplete_text = autocomplete_text.split()
autocomplete_text = autocomplete_text[0:2]
resp = client.build_request("GET", 'www.description_url_search_='+input_text+'')
r = await client.send(resp)
datajson = r.json()
datajson.insert(0, ' '.join(autocomplete_text))
await manager.send_personal_message(json.dumps(datajson), websocket)
In the Autocomplete.vue file I made small changes.
First I merged the EstepeJson.vue file into Autocomplete.vue, especially the json reading part in the html.
Second, in the data: function(){} I added one more object, called myJson: [].
Third, in the receiveText method I changed the way to receive data from the websocket. Since now I have JSON.parse to convert event.data to JSON. Then I use the shift method to take the first position in the json and remove this data from the file. And finally, return the json to the myjson variable.
File Autocomplete.vue:
<template>
<div class="pad-container">
<div tabindex="1" #focus="setCaret" class="autocomplete-container">
<span #input="sendText" #keypress="preventInput" ref="editbar" class="editable" contenteditable="true"></span>
<span class="placeholder" data-ondeleteId="#editx" contenteditable="false">{{autoComplete}}</span>
</div>
</div>
<div v-for="regList in myJson" :key="regList" class="container" >
<table>
<thead>
<tr>
<th>Documento</th>
</tr>
</thead>
<tbody>
<tr v-for="countryList in regList[2]" :key="countryList">
<td style="visibility: visible">{{ countryList}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
...
data: function() {
return {
autoComplete: "",
maxChars: 75,
connection: null,
myJson: []
}
},
.....
...
receiveText(event) {
let result = JSON.parse(event.data)
this.autoComplete = result.shift();
this.myJson = result
}
</script>
First, instead of using Python requests library (which would block the event loop—see this answer for more details), I would strongly recommend using httpx, which offers an async API as well. Have a look at this answer and this answer for more details and working examples.
Second, to send data as JSON, you need to use await websocket.send_json(data), as explained in Starlette documentation. As shown in Starlette's websockets source code, Starlette/FastAPI will use text = json.dumps(data) (to serialise the data you passed) when calling the send_json() function. Hence, you need to pass a Python dict object. Similar to requests, in httpx you can call the .json() method on the response object to get the response data as a dict object, and then pass that dictionary to the send_json() function.
Working Example
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
import httpx
app = FastAPI()
html = """
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
</head>
<body>
<h1>WebSocket Chat</h1>
<form action="" onsubmit="sendMessage(event)">
<input type="text" id="messageText" autocomplete="off"/>
<button>Send</button>
</form>
<ul id='messages'>
</ul>
<script>
var ws = new WebSocket("ws://localhost:8000/ws");
ws.onmessage = function(event) {
var messages = document.getElementById('messages')
var message = document.createElement('li')
var content = document.createTextNode(event.data)
message.appendChild(content)
messages.appendChild(message)
};
function sendMessage(event) {
var input = document.getElementById("messageText")
ws.send(input.value)
input.value = ''
event.preventDefault()
}
</script>
</body>
</html>
"""
#app.on_event("startup")
async def startup_event():
app.state.client = httpx.AsyncClient()
#app.on_event('shutdown')
async def shutdown_event():
await app.state.client.aclose()
#app.get('/')
async def get():
return HTMLResponse(html)
#app.websocket('/ws')
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
# here, use httpx to issue a request, as demonstrated in the linked answers above
r = await app.state.client.get('http://httpbin.org/get')
await websocket.send_json(r.json())

extract a class from beatiful soup

I Have a HTML script that after extraction looks something like this:
class="a-toaster Toaster_toaster__bTabZ">
</div>
</div>
</div>
<script id="__NEXT_DATA__" type="application/json">
{"props":{"pageProps": {"type":"Job","sid":"a84cacbbcb07ec55cdbfd5fbe3d9f252d7f9cdd0","loggedIn":false,"userId":null,"avatar":null,"rating":{"count":"743","value":6.6},"metadata":{"title":"Medior/Senior Tester0"}
I am interested in extracting certain key value pairs of this script into a dataframe. I would for example like a column named "title" with the value "Medior/Senior Tester0" and a column "customer" filled with null.
soup.find('a-toaster Toaster_toaster__bTabZ') results in a nonetype nonetype error. What would be a good way to extract for example the title of this html (medior/senior tester) ?
Try:
import json
from bs4 import BeautifulSoup
html_doc = """\
<div class="a-toaster Toaster_toaster__bTabZ">
</div>
</div>
</div>
<script id="__NEXT_DATA__" type="application/json">
{"props":{"pageProps": {"type":"Job","sid":"a84cacbbcb07ec55cdbfd5fbe3d9f252d7f9cdd0","loggedIn":false,"userId":null,"avatar":null,"rating":{"count":"743","value":6.6},"metadata":{"title":"Medior/Senior Tester0"} } } }
</script>
</div>"""
soup = BeautifulSoup(html_doc, "html.parser")
# locate the script tag:
script = soup.select_one("#__NEXT_DATA__")
# decode the json:
data = json.loads(script.text)
# print all data:
print(data)
Prints:
{
"props": {
"pageProps": {
"type": "Job",
"sid": "a84cacbbcb07ec55cdbfd5fbe3d9f252d7f9cdd0",
"loggedIn": False,
"userId": None,
"avatar": None,
"rating": {"count": "743", "value": 6.6},
"metadata": {"title": "Medior/Senior Tester0"},
}
}
}
To print the title:
print(data["props"]["pageProps"]["metadata"]["title"])
Prints:
Medior/Senior Tester0

Is it possible to pass Ajax response as template context variable in Django?

I sent an Ajax request to server to get some filtered data and here is a sample I receive from server:
(3) [{…}, {…}, {…}]
0: {id: 1, title: "12 Rue Longueil", slug: "12-rue-longueil", latitude: null, longitude: null, …}
1: {id: 2, title: "15 Rue Sherbrooke LM", slug: "15-rue-sherbrooke-lm", latitude: null, longitude: null, …}
2: {id: 3, title: "Cycle Neron", slug: "cycle-neron", latitude: "-73.5987000000000000", longitude: "45.4799000000000000", …}
length: 3
__proto__: Array(0)
above data is logged from console.
I want to display these data in HTMl tags within cards below.
but for that I need to use that received data and create children using JavaScript e.g. document.createElement('DIV'). and then place these data.
$(document).on('submit', "#filterform", function (e) {
e.preventDefault();
$.ajax({
type: 'GET',
url: "{% url 'listing:search' %}",
data: {
listing_for: $('#listing_for').val(),
// cutted
},
success: function (response) {
const listings = eval(response);
const content = document.getElementById('content');
for (let i = 0; i < listings.length; i++) {
const div = document.createElement('div');
div.className = 'listing mgb-1';
div.innerHTML = data[i].title;
content.appendChild(div);
// have to create, add lots of divs and classes
}
}
})
})
I was wondering if there is a way to sent Ajax request data as template variable? Or do I have to hardcode all HTML tags using Javascript?
Edit: Edited content based on first answer creating a separate HTML.
def search(request):
...
lst = list()
for listing in queryset:
ser = ListingSerializer(listing)
lst.append(ser.data)
return render(request, 'listing/newHtmlFile.html', {'listings': json.dumps(lst)})
separate HTML:
{% for list in listings %}
<div class="jumbotron">
<h1>{{ list.title }}</h1>
</div>
{% endfor %}
and ajax request:
success: function (response) {
document.querySelector('#content').insertAdjacentHTML('beforeend', response);
}
Yes, you can. Basically the idea is to make a separate HTML file that's going to be rendered by the view that handles the AJAX request. Then, you can use JavaScript and the insertAdjacentHTML() function to insert it in your original HTML file.
Take a look at this example:
view:
def ajax_handler(request):
# ... logic
return render(request, 'newHtmlFile.html', {'your_context': data})
Original HTML file
<div id='container'>
</div>
newHtmlFile.html
<p>{{ your_context }}</p>
JavaScript part (in this example I use Vanilla, not JQuery)
let ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){
if (this.readyState === 4){
if (this.status === 200){
document.querySelector('#container').insertAdjacentHTML('beforeend', this.responseText);
}
}
}
ajax.open('GET', '/ajax-handler-url', true);
ajax.send();
If you are interested to know how this works, we can break it down as follows:
You have some data (like a queryset, in your case) in your view
You call the render() method and you pass that data as the context data to a template
The render() method what actually does is to (let me be redundant here) render a HTML file (combining the HTML itself with the context data you passed) and return a HTTPResponse object containing a rendered text.
That rendered text (which is a bytestring that represents the content of the rendered HTML) is given as a response to the client. In this case, it's given specifically to the $.ajax() function that made the request.
We use the insertAdjacentHTML() function to append that rendered text to the desired element (in the example above, the #container div).
A quick, and possibly "dirty", way of doing it is to use the backtick strings in javascript:
success: function (r) {
const listings = JSON.parse(r); // with the correct headers from django, this should't be needed.
listings.forEach(e => $('#content').append(`
<div class="listing mgb-1">${e.title}</div>
`));
}
You should return your data from django with the appropriate headers so you automatically get json and don't need to eval(response).

Django - How to Insert Multiple Form Data using JQuery Ajax

I want to perform a similar task like what described in the following video,
https://youtu.be/NoAdMtqtrTA?t=2156
To add multiple rows in the table and then insert it all in a batch to the database.
Any reference or any sample code will be really appreciable. Thank you.
The Javascript code is :
<script>
var data_dict = [];
// function called when Add row button is clicked
function Add_input_row()
{
var input_row ='<tr id="input_row">\
<td><input id="input1"></td>\
<td><input id="input2"></td>\
<td><button onclick="save_row()">save</button></td>\
</tr>';
var table_element = document.getElementById("data_table");
//do nothing if input_row already exists
if(document.getElementById("input_row")) {
alert("input row already exists !");
}
else {
table_element.innerHTML = table_element.innerHTML + input_row;
}
}
// function called when Save button is clicked
function save_row()
{
var field_val1 = document.getElementById("input1").value;
var field_val2 = document.getElementById("input2").value;
//unique id for each added data row needed when reading data directly from table
var data_id = data_dict.length;
//push the data to data dictionary
data_dict.push({
key: data_id,
value: [field_val1,field_val2]
});
var data_row ='<tr>\
<td id="data_field1'+data_id+'">'+field_val1+'</td>\
<td id="data_field2'+data_id+'">'+field_val2+'</td>\
<td></td>\
</tr>';
// remove input row
document.getElementById("input_row").remove();
//append data to table
var table_element = document.getElementById("data_table");
table_element.innerHTML = table_element.innerHTML + data_row;
}
// send data to django views
function update_database() {
var csrf_token = 'your_csrf_token';
$.ajax({
method: 'POST',
url: 'update_database', // name of your djnago view
data: {"datatobeupdated":data_dict,"csrfmiddlewaretoken" : csrf_token},
success: function (response) {
//when executed succesfully empty the data_dict and table
data_dict = [];
var table_element = document.getElementById("data_table");
table_element.innerHTML = "";
},
error: function (response) {
alert("Something Went Wrong");
}
});
}
The Html table is :
<table>
<thead>
<tr><th title="Field #1">Field1</th>
<th title="Field #2">Field2</th>
</tr>
</thead>
<tbody id="data_table">
</tbody>
</table>
<button onclick="Add_input_row()">Add row</button>
<button onclick="Update()">Update</button>
You can access the data in your django view like :
def update_database(request):
if request.is_ajax():
request_data = request.POST
## data dictionary received
datatobeupdated = request_data['datatobeupdated']

Categories