Get the name of hyperlink clicked from previous page-FLASK - python

I am creating a project on examination.
In my first html page I have a set of hyperlinks which represent the name of question papers. The question papers are stored in the form of tables in MySQL.
What I want is,to return the name of the hyperlink clicked by the user in my python code.
All the links should lead to the same webpage,but the contents in each link is different.
This is my python code for the webpage which should open after one of the links is clicked:
#app.route('/qsetdisplay/exam',methods=['GET','POST'])
def exam():
if request.method == 'POST':
if 'answer' in request.form:
cursor5 = db3.cursor(pymysql.cursors.DictCursor)
tablename = request.args.get('type')
print(tablename)
cursor5.execute("select questions from {}".format(tablename))
cursor5.execute("select answers from {}".format(tablename))
cursor5.execute("select marks from {}".format(tablename))
print("ques:", ques)
print("ans:", ans)
print("marks:",marks)
return render_template('exam.html',ques=ques,marks=marks,ans=ans)
tablename returns as none in the above code.
This is my html code for the webpage which would open after oneof the links is clicked:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>EXAMINATION</title>
</head>
<body>
<div>
<form name="ex" id="ex" action="{{url_for('exam')}}" method=POST>
<h1 align="centre">ALL THE BEST!!!</h1>
{% for que in ques %}
<h6>{{que}}</h6>
<textarea name="answer" id="answer" placeholder="enter answer" rows="10" cols="100"></textarea><br><br>
{% endfor %}
<input name="sub" id="sub" type="submit" value="submit">
</form>
</div>
</body>
</html>
And this is the html code for the previous page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>STUDENT PROFILE</title>
</head>
<body>
<div>
<form action="/">
<h1>"WELCOME STUDENT"</h1>
</form>
</div>
<div>
<form name="QD" action="{{url_for('qset_display')}}" method="get">
<input name="QD" value="CLICK TO VIEW QUES PAPERS" type="submit"><br><br><br><br>
<h1>THESE ARE THE AVAILABLE PAPERS:</h1>
{% for name in names %}
{{name}}<br><br>
{% endfor %}
</form>
</div>
</body>
</html>
How can I correct my code?

Related

Why does request.POST always contains name of the button? How to avoid it?

This is my HTML code:
<!DOCTYPE html> <html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load static %}
<script src="{% static 'jquery-3.6.2.min.js' %}" ></script>
<script src="{% static 'jquery.js' %}" ></script>
</head>
<body>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<button name="button1">button1</button>
<button name="button2">button2</button>
<input type="text" name="textbox">
</form>
</body>
</html>
Every time I type some text in the textbox, let's say I type: "hi" and hit enter, the request.POST returns:
<QueryDict: {'csrfmiddlewaretoken': ['FX1qFNzbQUX3fYzAwW27cOu83omLzifnlLU5X0WXXVdOiyNretM5b3VgsGy1OogA'], 'button1': [''], 'textbox': ['hi']}>
Why does request.POST contain 'button1': [''] even though I haven't clicked on it?
Is there a way to avoid request.POST to have 'button1': ['']?
Remove a name attribute from your <button> tag if you don't need to know which buttons is pressed by a user:
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<button>button1</button>
<button>button2</button>
</form>
As the button is an input as well and can contain name and value.
Alternatively you may use the feature to implement the following approach if you wish to vary your backend logic dependant of which button is pressed:
In a template file:
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<button name="action" value="button1_pressed">button1</button>
<button name="action" value="button2_pressed">button2</button>
</form>
In your views.py:
if request.method == "POST":
back = reverse('index')
action = request.POST.get("action")
if action == "button1_pressed":
# do something
messages.success(request, "Successed!")
return redirect(back)
if action == "button2_pressed":
# do something else
messages.success(request, "Successed!")
return redirect(back)
you may Try
<!--base.html-->
{% load static %}
<!DOCTYPE html> <html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{% static 'jquery-3.6.2.min.js' %}" ></script>
<script src="{% static 'jquery.js' %}" ></script>
</head>
<body>
{% block content %}
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<input type="text" name="textbox">
<button name="button1">button1</button>
<button name="button2">button2</button>
</form>
{% endblock %}
</body>
</html>

Making with a POST request with checkboxes

I am trying to pass in a list of classes into a checkbox (this works), and when the Submit button is clicked, I want to make a Post Request to send all the selected boxes to the backend and then also go to the next page (Does not work).
Here is my HTML page right:
<!doctype html>
<html lang="en">
<head>
<style>
h1 {color: rgb(240, 112, 38);}
</style>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
function myFunction() {
window.location.href="./classinfo";
}
function sendPOST() {
let formData = { user_classes: $("#user_classes").val() };
$.post("/class", formData)
};
</script>
</head>
<body style="background-color:powderblue;">
<div class="container">
<br>
<h1>What Classes Have You Taken</h1>
<div class="form-group row">
<label class="col-lg-12">
<form method="POST" action='/class'>
<label class="col-xs-6" style="font-family:verdana;">
{% for c in cs_req %}
<input type="checkbox" style="text-align:left;" name = 'user_classes' option value = "{{c}}" SELECTED> {{c}}<br></option>
{% endfor %}
</label>
<br>
<input class="btn btn-secondary" style="font-family:verdana;" type="Submit" onclick="sendPOST();MyFunction()">
</form>
</label>
</div>
<div id="content">
</div>
</div>
<script>
$(document).ready(function(){
$('.selectpicker').selectpicker();
})
</script>
</body>
</html>
and my backend function is this:
#app.route('/class', methods=["POST"])
def store_classes():
"'Based on checkboxes selected from checkboxes(), store the classes in txt'"
user_classes = request.form.getlist('class') #--> returns nothing
return render_template("class.html")
My onclick is not sending the post request or going to the next page. I'm not sure how to solve this so any advice is appreciated.

django- how to render template for formset properly

I would like to create template with inline_formset. My parent element is customer and children elements are attachments which was sent by them. So I have to models: Customer, Attachment and inline_formset_factory
For the time being I've got template as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Adding new doc</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{ form.as_table }}
<br/><br/><br/>
{{ formset }}
<button type="submit">Submit</button>
</form>
</body>
</html>
And it looks like sh... I'm new in django and would like to give users better output.
How can I render form and formset with table where labels and fields will be in separarte rows?

How to retrieve the data from the list in django templates through request

I'm newly learning django. I'm trying to learn django by making todo app. I've created a view having template in which I'm showing a list of items to the user using for loop. I've also created a link for each item.Now I want to access the item that user clicked and I should display all details related to that item, for that I've created another view.But the problem is I'm not getting how to access that. Here's my code.
views.py
def display_user_tasks(request):
name = request.user
task_list = Task.objects.filter(user=User.objects.get(username=request.user.username))
context = {
'name': name,
'task_list': task_list,
}
return render(request, 'todo/task_list.html', context)
def about_tasks(request):
name = request.user
task = request.task
context = {
'task': task,
'name': name,
}
return render(request, 'todo/about_tasks.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Task List</title>
</head>
<body>
<div>
{% if task_list %}
<p> Hello {{ name }} Here are your tasks</p>
{% for task in task_list %}
{{ forloop.counter }}
{{ task }} <br>
{% endfor %}
{% else %}
<p> No tasks yet </p>
{% endif %}
<br>
<button onclick="window.location.href='task-form'">Add task</button>
</div>
</body>
</html>
I've just tried to display whether the task which user clicked is displaying or not.
about_task.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About tasks</title>
</head>
<body>
{{ name }}<br>
{{ task }}
<p> You will see about your tasks here</p>
</body>
</html>
Finally, I got the answer for my problem. I can send the clicked item as parameter in urls. So, I did it and this parameter takes the value when I use the name the respective url.

I cannot show a file-upload button

I cannot show a file-upload button.
I wrote in profile.html like
{% extends "registration/accounts/base.html" %}
{% block content %}
user.username: {{ user.username }}<hr>
user.is_staff: {{ user.is_staff }}<hr>
user.is_active: {{ user.is_active }}<hr>
user.last_login: {{ user.last_login }}<hr>
user.date_joined: {{ user.date_joined }}
{% endblock %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>UPLOAD</title>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
{% block body %}
<div class="container">
<form action="{% url 'accounts:upload_save' %}" method="POST" enctype="multipart/form-data">
<input type="file" name="files[]" multiple>
<input type="hidden" value="{{ p_id }}" name="p_id">
{% csrf_token %}
<input type="submit">
</form>
</div>
{% endblock %}
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>
So,I wrote multipart/form-data tag like
<form action="{% url 'accounts:upload_save' %}" method="POST" enctype="multipart/form-data">.
But, profile.html did not show the part of ~ .
it showed only {% extends "registration/accounts/base.html" %}
~ {% endblock %}.
How can i fix it?
Placing and position of {% block content %} is wrong in your code.
There are several issues with your code and I removed them.
You dont need an extra {% block body %}.
So you should use this code instead :
{% extends "registration/accounts/base.html" %}
{% block content %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>UPLOAD</title>
</head>
<body>
user.username: {{ user.username }}<hr>
user.is_staff: {{ user.is_staff }}<hr>
user.is_active: {{ user.is_active }}<hr>
user.last_login: {{ user.last_login }}<hr>
user.date_joined: {{ user.date_joined }}
<div class="container">
<form action="{% url 'accounts:upload_save' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="files[]" multiple>
<input type="hidden" value="{{ p_id }}" name="p_id">
<input type="submit" value="Upload">
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</body>
</html>
{% endblock %}
Also Note that, Place the csrf_token in correct position and add value="Upload" to input type="submit" .

Categories

Resources