Get value from post method to views from a for loop - python

I am trying to get a value from template to views.py of a django project. I am able to get the value of name="city" correctly but unable to get the exact value of name="category" in my views, instead I am getting the first element value for all the other elements in the loop. An idea to solve this will be very much helpful.
#category.html
{% for test in mytypes %}
<form id="myform" action="{% url 'my_city_category' %}" method="POST">
{% csrf_token %}
<a href="javascript: submitform()">
<div class="col-6 col-lg-3 col-md-4 col-sm-6 col-xl-2 hover-box mt-2 text-center">
<div class="pb-1 pt-2">
<img src="{{test.icon_image.url}}" width="100"/>
<h6 class="mt-3 text-body text-capitalize text-decoration-none">{{ test.category_type }}</h6>
<input type="hidden" name="category" value="{{ test.category_type }}"># unable to repeat the value while calling it in the views, stuck at the first value
<input type="hidden" name="city" value="{{ city }}"> #rendering the exact value
</div>
</div>
</a>
</form>
{% empty %}
<h6 class="mt-3 text-body text-capitalize text-decoration-none">No Categories Listed</h6>
{% endfor %}
#views.py
def City_specific_page(request):
city = request.POST.get('city')
category = request.POST.get('category')
business= Business.objects.filter(city__City=city, type__category_type=category)
return render(request, 'community_app/type_detail_city.html',{'business':business,'category':category,'city':city})
#urls.py
path('City', views.City_specific_page, name='my_city_category'),

Each <form> in your template includes the following tag:
<a href="javascript: submitform()">
I suspect that your submitform function is submitting the first form on the page, rather than the one that was clicked.
You can quickly determine if this is the problem by adding a submit button inside your <form> tags. Make sure it's not inside the <a> tags, eg:
<form id="myform" action="{% url 'my_city_category' %}" method="POST">
{% csrf_token %}
<button type="submit">Test</button>
<a href="javascript: submitform()">
<!-- the rest of your form code -->
Click the button labelled 'Test' to see if the correct form data is submitted.

Related

Django model id not changing through for loop

So I have a for loop in my Django template that loops through a product in my products model. The product model has an amount attribute that is supposed to change when the user clicks on the 'add' button. I have made a hidden form that launches the upvote method which takes a request and a pk and increases the amount attribute by 1.
The problem is that when I click on the add button, only two of the products' amount increase. I can't get the rest of the products' amount attribute to increases.
Here's the Django template code:
<div class="card-deck d-flex justify-content-start container-fluid">
{% for product in products %}
<div class="card lead m-3" style="min-width: 18rem;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{ product.product_id }}</h6>
<hr>
<p class="card-text">
Expiration date: {{ product.expiration_date }}
</p>
<p class="card-text">
amount: {{ product.amount }} <button class="btn btn-primary btn-sm">+</button>
</p>
<p class="card-text">
tags:
{% for t in product.tag.all %}
<span class="badge badge-primary">{{ t.name }}</span>
{% endfor %}
</p>
</div>
</div>
<form action="{% url 'upvote' pid=product.id %}" method="POST" id="upvote">
{% csrf_token %}
<input type="hidden">
</form>
here's the upvote method in the views.py file:
def upvote(request, pid):
if request.method == "POST":
product = get_object_or_404(models.Product, pk=pid)
product.amount += 1
product.save()
return redirect('home')
You end up having multiple elements with the same id (upvote) which is not allowed, and the Javascript code always uses the first form element it finds and submits that one.
To have unique form ids, change the following line
<form action="{% url 'upvote' pid=product.id %}" method="POST" id="upvote">
to
<form action="{% url 'upvote' pid=product.id %}" method="POST" id="upvote_{{ product.id }}">
and the following line
<a href="javascript:{document.getElementById('upvote').submit();}">
to
<a href="javascript:{document.getElementById('upvote_{{ product.id }}').submit();}">

Django form action attribute is not working propely

I am working on app in django 1.11, on search feature. I installed elasticsearch - here all things are working.
In base.html and under url 127.0.0.1:8000 - I have form to search and I would like to keep this form here. On another hand I have search app with view, url, template - under url 127.0.0.1:8000/search/ - search is working here.
To solve this problem - search on main page and redirect on site with results I was trying to use action attribute in django form.
form in base.html
<form action="{% url 'search:search' %}" method="post">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</form>
view in search app
def search(request):
q = request.GET.get('q')
if q:
posts = PostDocument.search().query('match', title=q)
else:
posts = ''
return render(request, 'search/search.html', {'posts': posts})
template with results
{% extends 'base.html' %}
{% block content %}
{% for p in posts %}
{{ p.title }}
{% endfor %}
{% endblock content %}
{% block sidebar %}{% endblock sidebar %}
You here mix up GET and POST. If the method is method="post", then the data is passed in the request, and thus ends up in the request.POST query dictionary.
If on the other hand the method is method="get", then the data ends up in the querystring of the URL. In that case, you can indeed use request.GET.
Often (not always), search queries are done with querystrings, since then a person can copy the URL and send it to another person, and that person thus can see the search results.
You can thus change the form to:
<form action="{% url 'search:search' %}" method="get">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</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

Django: redirect user two pages back

I have a list of multiple objects from my database (named "plp's"), arranged in a table. Next to each "plp" element I have a button "Edit" to modify that particular entry.
Next, I redirect the user to a new url, where I pass the id of that "plp", and show the form to edit it, with a "save" button.
After pressing the "save", which is request.POST, I want to redirect the user back to the first url, with the list of all the "plp" objects in one list. That means to the site, where he first pressed "Edit".
Can I somehow save the url of where the "Edit" was clicked, and pass it to my views.py?
Thank you
listdns.html:
<td>
Uredi
</td>
urls.py:
rl(r'^(?P<plp_id>\d+)/uredi$', plp_list_uredi,name="plpuredi")
views.py:
def plp_list_uredi(request, plp_id=None):
moj_plp=PLPPostavka.objects.get(id=plp_id)
form=PLPPostavkaForm(request.POST or None,request=request,dns=moj_plp.dns, instance=moj_plp)
context ={
'plp':moj_plp,
'form':form,
}
if request.POST:
if form.is_valid():
plp = form.save()
return redirect(request.path)
return render(request, "plp_pos/uredi.html",context)
uredi.html
<form action="" method="POST">
{% csrf_token %}
<div class="box">
<div class="box-header">
<h4 class="box-title">
Urejanje PLP Postavke
</h4>
</div>
<div class="box-body">
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}" class="col-md-2 control-label detail">{{ field.label }}</label>
<div class="col-md-10">
{% if field|field_type == "datefield" %}
{% render_field field class+="form-control dateinput" %}
{% else %}
{% render_field field class+="form-control" %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
<div class="box-footer">
<div class="box-tools pull-right">
<input type="submit" value="Shrani" class="btn btn-primary" />
</div>
</div>
Don't you only have 1 page to edit all the elements? Then you could perhaps hardcode the link e.g.
return HttpResponseRedirect(my_edit_url)
If this doesn't work and you need to go 2 pages back take a look at this post:
How to redirect to previous page in Django after POST request

pass GET parameter to href link

I have question and don't know how to express it to find the answer
when I go to : http://127.0.0.1:8000/image/test/?title="test"
and then want to go to another page,it will go to : http://127.0.0.1:8000/image/test/?page=2"
I kow it should go to: http://127.0.0.1:8000/image/test/?title="test&page=2"
But don't know how to do it
How can I edit the url to pass the parameter(title="test) to go to the correct url ?
And I have a second question about urls too
if I'm now on path
http://127.0.0.1:8000/image/test/?title="test
How can I write the absolute href to go to http://127.0.0.1:8000/image/test/ ?
Please help me Thanks
test.html :
<form action="" method="get" class="searchtitle">
search title:<input type="text" name="title">
<button type="submit" value="submit" >search</button>
</form>
...
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
<form action="" method="get">
<td>GO to</td>
<td><input name="page" type="text" ></td>
td> page </td>
<td><input type="submit" value=" go to page "></td>
</form>
</span>
views.py:
def object_list_1(request, model):
if request.GET.get("title", None):
search_term = request.GET['title']
cls = get_model('mongo', model)
obj_list = cls.objects.filter(title__contains=search_term)
results = get_paginator(request, obj_list, 10)
template_name = 'filterimgs/%s_list.html' % model.lower()
return render_to_response(template_name, {'object_list': obj_list,'contacts': results},
context_instance=RequestContext(request))
The problem is this <a href="?page={{ contacts.previous_page_number }}">; here you are ignoring any query string (the ?title="test" part).
To fix this problem, you need to first enable the request template context processor, and then update your template so that it includes the full URL, like this:
<a href="{{ request.get_full_path }}&page={{ contact.previous_page_number }}">

Categories

Resources