Easiest way to get the value of a key in request.POST - django

I have a user with a list of schools he has entered in his userprofile. I want to give him the ability to delete any one of his entries.
The following is the way I am currently using to delete a database entry, based upon the value of a key in the template:
# in template
{% for education in educations %}
<p>{{ education.school }}
<input type="submit" name="delete_{{education.id}}" value="Delete" /></p>
{% endfor %}
# in view
if 'Delete' in request.POST.values():
for key in request.POST.keys():
if key.startswith('delete'):
education_id = key[7:]
profile.educations.remove(Education.objects.get(id=education_id))
Is there an easier way to get the value of a key, rather than having to iterate over for key in request.POST.keys()? Thank you.

Forms are free. Make more of them.
{% for education in educations %}
something something
<form action="..." method="POST">
<input type="hidden" name="id" value="{{ education.id }}">
<input type="submit" value="Delete">
</form>
{% endfor %}
Then in the view:
id = request.POST['id']
profile.educations.remove(...)
Or put the id a GET parameter, instead of a hidden field (just make sure you don't use GET method for a form — those should never have any side effects).

While I also agree that forms are nice, you can also simplify your code a bit:
if 'Delete' in request.POST.values():
for key in request.POST.keys():
if key.startswith('delete'):
education_id = key[7:]
profile.educations.remove(Education.objects.get(id=education_id))
Could be simplified into:
for education_id in [key[7:] for key, value in request.POST.iteritems() if value == 'Delete' and key.startswith('delete')]:
profile.educations.remove(Education.objects.get(id=education_id))
I came up with another approach using the filter function but it was much messier and looked less elegant than the above.

if request.method == 'POST' and 'button_name' in request.POST.keys():
do_something
elif other button name

Related

Django filter for result from checkbox form

I'm begginer of django and i try to implement search engine to look for recipes that contains selected ingredients.
I want to do form with all ingredients_type from my Model and user can select up to 3 of them (checkbox prefered). Then i want to filter recepe that contains them.
I was looking for generic form but never get right result.
Right now i have only a scratch and Im looking for any advice
model.py
class IngredientsType(models.Model):
type = models.CharField(max_length=60, blank=True)
def __str__(self):
return self.type
search.html
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<form method="POST" action="#">
<button type="submit" name="save" value="save">szukaj</button>
</form>
Do i have to create custom form or there is good way to use some of generic form?
I think what you are on the right path, but there are some mistakes in your code.
search.html
<form method="POST" action="">
{% csrf_token %}
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}" value="1">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<button type="submit" name="save" value="save">szukaj</button>
</form>
model.py
You might want to use many-to-many relationship to represent to relation between the ingredient types and the recipes.
views.py
Make sure you have the POST handling method to work with your filter query. This should get data from the form.

Retrieving data from an array of check boxes in a Django template

In a Django template, I'm displaying some usernames (or unames) along with check boxes like so:
<form method="POST" action="{% url 'process_unames' %}">
{% csrf_token %}
{% for name in unames %}
<input type="checkbox" name="target{{ forloop.counter0 }}" value="{{ unames|index:forloop.counter0 }}" checked>{{ name }}<br>
{% endfor %}
<button name="duration" value="{{ value }}" type="submit">Submit</button>
</form>
And then in the function process_unames, I'm trying to retrieve all checked unames via:
def process_unames(request, *args, **kwargs):
uname_list = request.POST.getlist('unames')
This is consistently yielding an empty list, regardless of which uname I check or uncheck. How do I fix this? An illustrative example would be great.
In case it matters, I haven't declared any form in forms.py with this Django template. Moreover, note that index is a custom template tag which does the following (and I can vouch it's correctly working):
from django.template.defaulttags import register
#register.filter(name='index')
def index(List, i):
return List[int(i)]
You are checking the wrong variable. You access the input by its name.
So for a single value you would retrieve the data for a form like this
<input type="checkbox" name="user_name" value={{uname}}>
via
request.POST.get('user_name')
See: https://docs.djangoproject.com/en/1.10/topics/forms/#the-work-that-needs-to-be-done
And if you have loop, you still give each relevant input the same name and use request.POST.getlist() to access the values as a list.
See: https://stackoverflow.com/a/23470119/630877
You don't have any fields called "unames" in the template. You have a bunch of unrelated checkboxes called "targetX" where X is a number. Replace that with just name="unames" and your code will work.
Note two things: firstly, you should be using Django's forms framework; and secondly, your filter is pointless because {{ name }} would already by the value in unames, since that is what you are iterating over (and, indeed, you are already using that as the label).
{% for name in unames %}
<input type="checkbox" name="unames" value="{{ name }}" checked>{{ name }}<br>
{% endfor %}

Django Forms to values of html <input> field

I am trying to access the values of a Bootstrap btn-group from Django and from the documentation I have found, it seems that you should use Forms in Django for such tasks.
This is what the html looks like, right now:
<div class="col-md-6">
{% for metric in metrics %}
<input name="{{ metric.name }}" type="hidden" value="0"/>
{% endfor %}
<div class="btn-group" data-toggle="buttons">
{% for metric in metrics %}
<button type="button" class="btn btn-default" data-checkbox-name="{{ metric.name }}">{{ metric.name }}</button>
{% endfor %}
</div>
</div>
How can I use forms to get the values of the input fields?
Here it is a basic example about using a form in django
views.py:
#login_required
def your_view(request): # Add this code into your view
if request.method == 'POST':
# So here you can do a loop over POST fields like this
data_list = [] # We will insert all the inputs in this array
for key in request.POST:
data_list.append(request.POST[key])
# Here you can manage the the data_list and do whatever you need
# The content of the data_list depend on your inputs
# It could be string, integer....
# YOUR VIEW CODE
template (form example):
<form action="." method="post" id="add_user_form">
{% csrf_token %}
{% for metric in metrics %}
<input type="text" name="{{ metric.name }}" placeholder="whatever you want">
{% endfor %}
<input type="submit" value="submit" class="default"/> # Submit button
</form>
{% csrf_token %} : You need to put this in every form you use
action="." : This make the post to the actual page
But anyway I strongly recommend you to check this Django Forms Documentation to unterstand better the logic, and also check the ModelForms because can save you a lot of time when you need to make a form for a model that exists in your Django Models
You are'n forced to use django forms, this is just a way to get a sort of organization.
in you views toy can get the values sent to the server by using request.GET or request.POST, depending of the method of the form.
to get a list of values you have received just do a
print request.POST
request.POST is a dictionary, so you can get any value fron them by its key:
print request.POST['<key>']

How to send dynamic hidden form variables using POST

I have a page that pulls out entries from the database as 'users' and lists them. A typical result looks like this:
John
Marty
Tom
Jane
Chris
Now I would like to click on a specific the name and go to their specific page. For this, I have a form that posts to a view that expects the user that has been "clicked"
So far, I have a form inside a loop that goes through each 'user' in 'users' table. The setup works fine but the major problem is that the form element 'name' is replaced by the last user. No matter, whose name I click it always passes the last user's username.
{% for user in users %}
<h1>{{ user.firstName }} {{ user.lastName }}</h1>
<form action="/friend_profile/" method="post" accept-charset="utf-8">
<input type="hidden" name="selectedFriend" value ={{ user.userName }}>
<button type="submit" value="view profile">
{% endfor %}
I am not using DJango forms and just using request.method == 'POST' for receiving variables.
So my dumb question would be, is there a way to dynamically create 'name' form element and submit its contents specific to the user? Right now, the form always submits the user "Chris" no matter which user I click because its the last one on the list.
Right now, the form always submits the user "Chris" no matter which user I click because its the last one on the list.
That's because you didn't close your <form> tag, so the browser sees one big bunch of nested forms.
Also, you need to quote and escape the value attribute in your hidden input:
<form action="/friend_profile/" method="post" accept-charset="utf-8">
<input type="hidden" name="selectedFriend" value="{{ user.userName|escape }}">
<button type="submit" value="view profile">
</form>

How do I change the template being displayed after the user clicks a button?

I'm quite new to Django, so I aplogize if I am making dumb mistakes.
Here is the code I have so far:
For views.py:
def bylog(request):
if request.POST.get('Filter'):
return render(request, 'index.html', context)
filtered_login = Invalid.objects.values_list('login').distinct()
filtered = []
for item in filtered_login:
filtered.append(item[0])
results = {'results': results, 'filtered': filtered}
return render(request, 'bylog.html', context)
Here is a snippet of bylog.html:
<select id>"dropdown">
{% for item in filtered %}
<option value={{ item }}">{{ item }}</option>
{% endfor %}
</select>
<input type="submit" value="Filter" name="Filter" />
My main goal is to get the value from the drop down list, and after the user clicks the Filter button, the value gets passed to another template.
Is that even possible?
Thanks for you help.
The basic for your goal I supose it is to manage POST in django, meaning that you want to send any data/variables from a template to a view and then do any operation with it (send it to another template, or store...)
The basic for this is(Using HTML form, not Django form):
- Create a HTML form in the template
- Add the selects/inputs with the data you want to manage and a button/input to make the post
- Manage the post in the view
EXAMPLE
template form
<form id="" method="post" action=".">
{% csrf_token %}
<select id="any_name" name="any_name">"dropdown">
{% for item in filtered %}
<option value={{ item }}">{{ item }}</option>
{% endfor %}
</select>
<input type="submit" value="Filter" name="Filter" />
</form>
view.py
def your_view(request):
if request.method == 'POST': # If anyone clicks filter, you receive POST method
data = request.POST['any_name']
# Do what you need here with the data
# You can call another template and send this data
# You can change any_name for the variable you want, changing the name and id in the select
#Your view code
I recommend you to read about Django forms because if you need a bigger form, to manage the data of a model with a lot of fields, a Django Form will save you a lot of time
Working with Django Forms