I have a dynamically generatyed HTML file that displays quizzes for a class that was gathered from an API request. Within this page, I have a scan button that will scan the selected quiz and kick off a python script on the backend. When the scan button is clicked, I need that specific class data sent back to my views file so I can kick off an API request on the back end for the scan.
The issue I am having is that when the scan button is pressed, only the last element in the list (of the dynamically generated html page) is sent back to my views.py file.
How do I set up my POST reuquest on button click to handle the dynamic data so the data that gets sent back is correct as.
Images below will show what is happening.
Dynamic HTML page code
<div class="container">
<form method="post">
{% csrf_token %}
{% for quiz in assignment_data %}
<div class="assignment hide-content">
<div class="row assignment-header">
<div class="col">{{quiz.title}}</div>
<div class="col">published: {{quiz.published}}</div>
<div class="col">Questions: {{quiz.question_count}}</div>
<div class="col-sm toggle-col">
<i class="toggle-drop-icon drop-icon-down fa-sharp fa-solid fa-caret-down"></i>
<i class="toggle-drop-icon drop-icon-up fa-sharp fa-solid fa-caret-up"></i>
</div>
</div>
<div class="row assignment-content">
<div class="col">
<button class="button" type="submit" id="scan-quiz" name="run_webscrape" onclick="this.classList.toggle('button--loading')">
<span class="button-text">Scan</span>
<input type="hidden" name="quiz_id" value="{{quiz.id}}">
<input type="hidden" name="quiz_name" value="{{quiz.title}}">
</button>
</div>
<div class="col">
Cheatability
<br>
<span class="grey">0/{{quiz.question_count}}</span>
</div>
<div class="col">
Last Scan
<br>
<span class="grey">Not Scanned</span>
</div>
<div class="col">
<a href="#" disabled>View Results</a>
</div>
</div>
</div>
{% endfor %}
</form>
</div>
Post request in views.py
def post(self, request, class_id):
if request.method == 'POST' and 'run_webscrape' in request.POST:
# get user profile form
# base information for authentication to canvas
# grab canvas token out of database for canvas auth
user_token = Profile.objects.filter(user=request.user).values_list('canvas_api_token', flat=True)
api_token = str(user_token[0])
user_quiz_data = Profile.objects.filter(user=request.user).values_list('teacher_data', flat=True)
teacher_data_string = user_quiz_data[0]
if not teacher_data_string:
print("No data yet for this teacher")
teacher_data = list(teacher_data_string)
else:
teacher_data_string_edit = [teacher_data_string]
teacher_data_list = [json.loads(idx.replace("'", '"'), strict=False) for idx in teacher_data_string_edit]
teacher_data = teacher_data_list[0]
# set the quiz id of the selected quiz to scan
# THIS DATA RIGHT HERE NEEDS TO BE DYNAMIC
********************************************************************************
quiz_id = int(request.POST['quiz_id'])
quiz_name = request.POST['quiz_name']
#*******************************************************************************
# Create data block entry to save quiz information into database
# vars for Canvas authentication
canvas_api_url = "https://canvas.instructure.com/api/v1"
header = {
"Authorization": f"Bearer {api_token}"
}
webscrape(canvas_api_url, header, quiz_id, class_id, quiz_name, teacher_data, request)
return redirect(to="home-view")
Terminal data that gets printed out to double check I am getting the correct data
**
5640376
13368555
Test Science Quiz 2 Multiple Variations
**
For reference, I clicked the scan button for Science Test Quiz 1 but got data for Test Science Quiz 2 Multiple Variations. This also happens for every class page. It only ever sends back the last interation within the for loop on the HTML page (for loop in shown within HTML page code)
2
Answers
submit button always send all data in form, use ‘id"{{quiz.id}}"’ and give dynamic id and dynamic name to your submit button and then in BackEnd check wich submit button clicked then do some action
or
you should create button from anything other than ‘type="submit" ‘ and use JS to send data to API or backend
for dynamic submit button
this code is simple
I suggest using Javascript & Ajax to submit the values instead of an HTML form.
This also comes with the added benefit of not having to reload the page on every button click!
This is generally what I would do:
View
Template
Generally you would throw the javascript into an external file and source it in the html, but for simplicity I decided not to do that
I included the
status
andmsg
response, as I find it very robust. It allows you to handle two types of errors in a consistent manner