preserve multiple GET parameters in Django URL - python

In my django project I have a page displaying a list of times. On this page there is 3 GET forms which are for:
Parsing through pages
Selecting graph data
Sorting items
If a user is to select a field in all of these forms the URL should look something like this:
http://127.0.0.1:8000/watchlist/?page=1&graph_data=price&sort=quantity_desc
But when a user submits one of these forms it only saves that GET parameter in the URL. eg:
selects page = 2
http://127.0.0.1:8000/watchlist/?page=2
selects sort = quantity_asc
http://127.0.0.1:8000/watchlist/?sort=quantity_asc
The page parameter is over written when both parameters should be present in the URL. How can i preserve multiple GET parameters in the URL?
views.py
def watchlist(request):
#get requests
graph_metric = request.GET.get("graph-data-options", "avg_price")
page = int(request.GET.get("page", 1))
sort_field = request.GET.get("sort-field", "avg_price-asc")
return render(request, "App/watchlist.html", context=context)
html
<!-- Page number -->
<form id="page-buttons-form" action="{% url 'watchlist' %}" method="GET">
{% for page_button in num_pages %}
<input name="page" type="submit" value="{{page_button}}">
{% endfor %}
</form>
<!-- Sort items -->
<form id="sort-form" action="{% url 'watchlist' %}" method="GET">
<label for="sort-field">Sort:</label>
<select onchange="this.form.submit()" name="sort-field">
{% for sort in sort_options %}
<option value="{{sort.value}}">{{sort.text}}</option>
{% endfor %}
</select>
</form>
<!-- Graph data -->
<form action="{% url 'watchlist' %}" method="GET">
<label for="graph-data-options">Graph Data</label>
<select onchange="this.form.submit()" name="graph-data-options">
{% for graph_option in graph_options %}
<option value="{{graph_option.value}}">{{graph_option.text}}</option>
{% endfor %}
</select>
</form>

This is a proof of concept to demonstrate how you can preserve GET parameters when submitting different forms. Each form runs a function fillHiddenFields before submitting, inserting existing URL parameters into the hidden fields.
Note: Apparently this does not work as a StackOverflow snippet, so you'll have to run this on your local machine.
function fillHiddenFields(event){
// extract query params from URL
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
// find hidden fields in form
let form = event.target;
const hiddentElmts = form.querySelectorAll('input[type=hidden]');
// update hidden fields with URL query params
for(let elmt of hiddentElmts){
if(elmt.name in params){
elmt.value = params[elmt.name];
}
}
// console.log form data to check that hidden fields are updated
let formdata = new FormData(form);
console.log(Object.fromEntries(formdata));
}
<body>
<form id="form1" action="javascript:void(0)" method="GET" onsubmit="fillHiddenFields(event)">
<input type="text" name="field1" value="Field 1">
<input type="hidden" name="field2" value="">
<input type="submit" value="Submit">
</form>
<form id="form2" action="javascript:void(0)" method="GET" onsubmit="fillHiddenFields(event)">
<input type="hidden" name="field1" value="">
<input type="text" name="field2" value="Field 2">
<input type="submit" value="Submit">
</form>
</body>

Related

How to access the selected option in an select tag with Django (not using Javascript)?

I have a form that has a select tag and dynamically created options for that tag as shown below. I want to access the selected tag if it is included in the POST request as part of the form in my Python/Django code:
<form action="{% url 'newprogram' %}" method="post" novalidate>
{% csrf_token %}
TODO: Add Program to School
<select name="schooloptions">
{% for school in schools %}
<option value="{{ school.name }}">{{ school.name }}</option>
{% endfor %}
</select>
<div class="form-group">
<input autofocus class="form-control" type="text" name="programname" placeholder="">
</div>
<input class="btn btn-primary" type="submit" value="Post">
</form>
I want to select the option that the user selects from the drop-down menu as follows but it does not work:
#login_required
def newprogram(request):
if request.method == "POST":
programname = request.POST["programname"]
school = request.POST["schooloptions"].selected() #This does not work and is what I need help with
schoolobj = School.objects.get("school")
school = Program(School=schoolobj, name=programname)
school.save()
return render(request, "network/index.html")
Any thoughts as to how I can access the selected option from a select HTML tag within a form?

Flask request.form[] not pulling data

I am trying to post a simple html form and pull the data into python/flask. request.form does not appear to be pulling my form data.
I have a function created to pull the variables if the request method is POST, but the URL ends up with the variables being blank. See code below
#app.route('/inquire',methods=['POST','GET'])
def inquire():
if request.method == 'POST':
name = request.form['dname']
email = request.form['demail']
message = request.form['dmessage']
return
redirect(url_for('inquire_success',name=name,email=email,message=message))
return render_template('inquire.html')
#app.route('/inquiresuccess/',methods=['POST','GET'])
def inquire_success(name,email,message):
return render_template('inquiresuccess.html',name=name,email=email,message=message)
the html below :
<div class="container">
<div class="main">
<form method="post" class="form" action="{{
url_for('inquire_success' }}">
<h2>Inquire below and we'll get back to you</h2>
<label>Name :</label>
<input type="text" name="dname" id="dname" value="name">
<label>Email :</label>
<input type="text" name="demail" id="demail" value="email">
<label>Project info :</label>
<textarea class="messagebox" name="dmessage" id="dmessage"
value="message">
</textarea>
<input type="submit" name="submit" id="submit" value=Submit>
</form>
I would like the code to redirect me to inquiresuccess.html with the variables displayed. Thanks for any help.
The form looks to be posting to the wrong endpoint. Try changing
<form method="post" class="form" action="{{ url_for('inquire_success' }}">
to
<form method="post" class="form" action="{{ url_for('inquire' }}">

Can't get form data in view function: Django

I need to submit a string to a view function via a dropdown menu and submit button.
in my template I have:
<form action="{% url 'exec_task' %}" method="post">
{% csrf_token %}
<select id="select_task" form="select_task" name="select_task">
{% for task in available_tasks %}
<option id="selected_task" value="{{ task }}">{{ task }}</option>
{% endfor %}
</select>
<input class="button" type="submit" value="Run Selected Task">
</form>
in my view function I have:
def exec_task(request):
if request.method == 'POST':
task = request.POST.get('select_task')
print(task)
getattr(tasks, task)(0)
return redirect('management')
The print(task) always comes out as None, which generates an error when I try to call it via getattr in the next line.
I've read through all the questions and tutorials I can find on this and I don't know what I'm doing wrong, but when I print the request.POST object, all I get is the csrf token. The QueryDict has nothing else in it.
Any ideas?
As discussed in comments please remove
form="select_task" from select tag.
So final select tag / html would be.
<form action="{% url 'exec_task' %}" method="post">
{% csrf_token %}
<select id="select_task" name="select_task">
{% for task in available_tasks %}
<option id="selected_task" value="{{ task }}">{{ task }}</option>
{% endfor %}
</select>
<input class="button" type="submit" value="Run Selected Task">
</form>

Passing value along with form in POST data in Django

When I render the form in HTML, I use this view. the patient_id is used to denote what patient the check in is for and for name display and such.
def Checkin(request, patient_id):
patient = get_object_or_404(PatientInfo, pk=patient_id)
form = forms.PatientCheckinForm()
return render(request, 'patientRecords/checkin.html', {'patient': patient, 'form':form})
When I submit the patient form filled out as a POST method, I still need access to the patient_id. Currently this is the view that accepts the filled form:
def CheckinSubmit(request):
if request.method == 'POST':
form = forms.PatientCheckinForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.date_time_of_checkin = dt.now()
instance.patient = patient.patient_id
instance.save()
return redirect('patientRecords/index.html')
I want to set the instance.patient to the patient_id that was part of patient from the Checkin view. Is there a way to pass the patient data back along with the POST method or is there another way this can be done?
For reference, here is my template and I am using ModelForm not form.
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
Thanks in advance!
You should be able to simply add a hidden input to your form to capture the patient ID:
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
<input type="hidden" name="patient_id" value="{{patient.patient_id}}" />
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
(Note this assumes that the patient ID is accessible from the patient_id property of the patient object.)
Then, in your CheckinSubmit method, you can access this value via request.POST.get('patient_id')
Alternatively, it appears that your check in form loads with the patient ID in the URL. In your CheckinSubmit method, you should be able to access this URL through the request.META.HTTP_REFERER property. You could then parse the URL (e.g., using request.META.HTTP_REFERER.split('/')[len(request.META.HTTP_REFERER.split('/')) - 1] to pull out the patient ID.
Example
<form method="post" action = "{% url 'user_search_from_group' %}">
<div class="module-option clearfix">
<div class="input-append pull-left">
<input type="hidden" name="groupname" value="{{ gpname }}" />
{% csrf_token %}
<input type="text" class="span3" placeholder="Filter by name" id="username3" name="username3" required>
<button type="submit" class="btn" name="submit">
<i class="icon-search"></i>
</button>
</div>
</div>
</form>
Here a hidden field is used to pass a value along form.
def user_search_from_group(request):
if request.method == 'POST':
username3 = request.POST.get('username3')
gname = request.POST.get('groupname')
Using request we are use the value inside view

Passing session data to templates without customizing views

I'm working on adding subscriptions using django-registration. Right now, I'm trying to create a Paypal form on the registration_complete page.
I have created a session variable as follows:
def user_created(sender, user, request, **kwargs):
form = RegistrationFormEx(data=request.POST)
new_user = User.objects.get(username=request.POST['username'])
digest=hmac.new(str(request.POST['username'])+str(request.POST['password1']), str(request.POST['password1']),hashlib.sha1).hexdigest()
new_profile = UserProfile(user=new_user,api_key=digest)
new_profile.save()
#now add other fields including password hash as well
uid = new_profile.id
#Add username to session to pass it via Paypal later
request.session['username']=request.POST['username']
merchant_profile = MerchantProfile(user_id=uid,
create_time=datetime.datetime.now(),
modified_time=datetime.datetime.now(),
payment_card_id=uid,
current_state=1,
name=request.POST['name'],
)
merchant_profile.save()
return new_user
user_registered.connect(user_created)
My template for the Paypal form is is as follows:
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<p>
{% trans "You are now registered. Activation email sent." %}
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="sumit_1349250468_per#sample.com">
<input type="hidden" name="item_name" value="registration charge {{ request.session.username }}">
<input type="hidden" name="item_number" value="1">
<input type="hidden" name="amount" value="9.00">
<input type="hidden" name="no_shipping" value="0">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="lc" value="AU">
<input type="hidden" name="bn" value="PP-BuyNowBF">
<input type="image" src="https://www.paypal.com/en_AU/i/btn/btn_buynow_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src="https://www.paypal.com/en_AU/i/scr/pixel.gif" width="1" height="1">
<input type="hidden" name="return" value="http://url/payment_result?response=success">
<input type="hidden" name="cancel_return" value="http://url/sorry">
</form>
</p>
{% endblock %}
Without changing any views, how can I print the value for request.session.username in this template?
In settings.py, TEMPLATE_CONTEXT_PROCESSORS should include django.core.context_processors.request - This makes the request variable available to your templates.
Although, a word of warning: When the user activates his email and signs in after returning, the session variable will probably have changed.

Categories

Resources