How to get list of checked checkboxes in django? - python

Here, 'arr' is a list passed from a previous view. The values(string type) of this list along with the check boxes are successfully being displayed.
<form action="{% url 'prec' %}" method="post">
{% for link in arr %}
<input type="checkbox" name="checks[]" value="{{link}}" />{{link}}<br>
{% endfor %}
<input type="submit" value="Submit">
</form>
In views function, I create a list of the fields/boxes checked by the user.
(views.py):
from django.shortcuts import render
def prec(request):
if request.method == 'POST':
var = request.POST.getlist('checks[]')
return render(request, 'Link5_prec.html', {'variables':var})
Then, in another template, I want to display the values checked by the user(along with the index of that checkbox like [0,2,3]). But nothing is being displayed.
(Link5_prec.html):
{% for v in variables %}
<h1>{{v}}</h1>
{% endfor %}
Also, if possible, in the first template, I want to make a checkbox of all the elements in the 'arr' list except the last element.

Related

Redirecting buttons with values to other django templates/views

Firstly, I am getting a csv file from the user.
(Template file:)
<form method="post" action="{% url 'rowcol' %}" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="file" accept=".csv">
<button type="submit">Upload File</button>
</form>
Then i am generating a list of all the columns present in the file and then calling another html file. (views.py:)
def rowcol(request):
if request.method == 'POST':
file = request.FILES['file']
dataset=pd.read_csv(file)
lst=list(dataset)
return render(request, 'Link5_rc.html', {'arr':lst})
return HttpResponse('')
In that html file, i am creating buttons for all the columns present.(Link5_rc.html:)
{% for link in arr %}
<form action=" " method="post">
<button name="{{link}}" type="submit" value="{{link}}">{{link}}</button>
</form>
{% endfor %}
Now the following is the part where i am stuck: I want these buttons to redirect to another html page or maybe a view in views.py , where i can show to the user which column he/she selected and then perform further actions on that particular column.
You can pass one or more values to the request as in the following example:
Some text
You can use variables like:
Some text
In your app urls.py you should set the following to receive the extra data in the request:
url(r'^your_name/(?P<value_1>[\d\D]+)$', views.your_view, name="your_url_alias")
Then, in your view function you should receive the data as in:
def your_view(request, value_1):
An then you can use the value to filter the queryset.

Can I build my form without using Django form?

I'm using Django and I just did a big form Using HTML5 and bootstrap. Can I still send the form via the post method to django if I'm not using it to generate the form? Should I definitely redo my form using Django?
NOTE: There may be a better way of doing this, if there is I'd really like to know, this is just how I have done it in the past.
You will still need a forms.py file in your app.
In forms.py:
from django import forms
class MyForm(forms.Form):
# FORM FIELDS HERE
Then put the form in the context dictionary for your view:
def myView(request):
if request.method == "POST":
# FORM PROCESSING HERE
else:
myform = MyForm() #create empty form
return render(request, "template.html", {"myform": myForm}
Now in your template you can add:
<form id="myForm" name="myFormName" method="post" action=".">
{% csrf_token %}
{% for field in myform %}
{{ field.as_hidden }}
{% endfor %}
</form>
This will add your django form to the page without displaying it. All of your form inputs are given the id id_fieldName where fieldName is the field name you defined in the forms.py file.
Now when the user clicks your "submit" button (which I am assuming is a bootstrap button given the rest of your form is). You can use Jquery to input the bootstrap field values into those of the hidden form.
Something like:
$("#mySubmitButton").click(function() {
$("#id_djangoFormField").val($("#myBootstrapFormField").val());
$("#myForm").submit();
}
);
This will submit the django form with the inputs from bootstrap. This can be processed in the view as normal using cleaned_data["fieldName"].
A bit late I post the solution I found for including a form in a modal in a class based detail view. Dunno if it's really orthodox but it works.
I don't use any Form Class or Model. (Django 3.9)
Within the template, I send a field value of my object in a hidden div. If this value is missing for a special action (because for the most of actions on the object, it's not required), a modal pops asking for updating the given field. This modal is triggered with JS that check the presence (or not) of the required value.
In the modal, I display a list of radio choices buttons in an ordinary form inviting the user to update the field. The form's action leads to a view that will update the given field.
modal.html
<form action="{% url 'update-sku-column' object.pk %}" method="post">
{% csrf_token %}
{% if csv_headers %}
<div class="m-3 ps-3">
{% for header in csv_headers %}
{% for csv_sample in csv_samples %}
{% if forloop.counter0 == forloop.parentloop.counter0 %}
<div class="form-check">
<input class="form-check-input" type="radio" name="chosen-field" value="{{ forloop.counter0 }}">
<label class="form-check-label" for="{{ forloop.counter0 }}">
<span class="ms-3">{{ header }} </span>: <span class="ms-1 text-secondary">{{ csv_sample }}</span>
</label>
</div>
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% endif %}
<div class="modal-footer">
<button type="submit" class="btn btn-success">Enregistrer</button>
</div>
</form>
urls.py
[...]
path('flow/<int:pk>/update-sku-column',
set_sku_column, name='update-sku-column'),
[...]
views.py
#login_required
def set_sku_column(request, pk):
if request.method == 'POST':
column = request.POST['chosen-field']
flow = Flow.objects.get(pk=pk)
flow.fl_ref_index = column
flow.save()
return redirect('mappings-list', pk=pk)
[...]
Even if I can imagine it's not the best way, it works.
don't forget the {% csrf_token %}otherwise it won't

Django - How do I delete single database entries on button click?

I'm trying to set up a user profile where you can enter skills. Entering the skills and save them in the databse already works. Now I want to give the user the opportunity to delete every single one of them with a button click. I tried posting the ID of each skill on button click in the URL and read it out in my view to get the item and delete it, but that does not work like I thought and I cant find out why...
MY VIEW
def profile_settings(request, id=None):
# get logged in user object from session
user_id = request.user.id
# get related userprofile
userprofile = UserProfile.objects.get(pk=user_id)
# get all skills of the userprofile
user_skills = Skill.objects.filter(user=userprofile)
if request.method == 'POST':
form = SkillForm(request.POST)
if 'delete-skill' in request.POST:
if id:
print(id)
skill = Skill.objects.get(pk=id).delete()
elif 'add-skill' in request.POST:
if form.is_valid():
# get data from form
name = form.cleaned_data['name']
category = form.cleaned_data['category']
rating = form.cleaned_data['rating']
# create new skill object for a user
new_skill = Skill(name=name, category=category, rating=rating, user=userprofile)
# save it in the database
new_skill.save()
else:
form = SkillForm()
return render(request, 'profile-settings.html', {'skillform': form, 'existing_skills': user_skills})
MY URLS
urlpatterns = [
url(r'^landing', views.landing, name='landing'),
url(r'^neuigkeiten', views.news, name='news'),
url(r'^profileinstellungen/', views.profile_settings, name='profileinstellungen'),
url(r'^profileinstellungen/(?P<id>\d+)/$', views.profile_settings, name='profileinstellungen'),
]
MY TEMPLATE
{% extends 'base.html' %}
{% block content %}
<form method="post" style="margin-top: 300px">
{% csrf_token %}
{{ skillform }}
<input type="submit" value="Hinzufügen" name="add-skill "/>
</form>
<form method="post">
{% csrf_token %}
<ul>
{% for skill in existing_skills %}
<li>{{ skill.name }}</li>
<input href="{% url 'profileinstellungen' id=skill.id%}" type="submit" value="Löschen" name="delete-skill"/>
{% endfor %}
</ul>
</form>
{% endblock %}
It does not post the ID of the skill in the URL. Is there an alternative approach?
Try to change this :
<input href="{% url 'profileinstellungen' id=skill.id%}" type="submit" value="Löschen" name="delete-skill"/>
by this :
<input href="{% url 'profileinstellungen' %}{{skill.id}}" type="submit" value="Löschen" name="delete-skill"/>
because the "url" will know automatically that "skill.id" was related to "id"
You have forgotten to include dollar signs at the end of the regexes in your URL patterns. It should be:
urlpatterns = [
url(r'^landing$', views.landing, name='landing'),
url(r'^neuigkeiten$', views.news, name='news'),
url(r'^profileinstellungen/$', views.profile_settings, name='profileinstellungen'),
url(r'^profileinstellungen/(?P<id>\d+)/$', views.profile_settings, name='profileinstellungen'),
]
In particular, the problem is the regex r'^profileinstellungen/. Without the dollar, it matches URLs like /profileinstellungen/4/, so the id is not passed to the view.
Secondly, it doesn't make sense to give the input an href attribute. Each input should be in a separate form, and you can set the form action to the URL you wish to submit the post request to.
<ul>
{% for skill in existing_skills %}
<form method="post" action="{% url 'profileinstellungen' id=skill.id%}">
{% csrf_token %}
<li>
{{ skill.name }}
<input type="submit" value="Löschen" name="delete-skill"/>
</li>
</form>
{% endfor %}
</ul>

Display form input with Django

So basically I want to make a simple form I can enter text and the after I hit submit, see the text.
Here is my forms.py:
class Search(forms.Form):
search = forms.CharField()
Here is my views.py:
def search(request):
context = RequestContext(request)
if request.method == 'POST':
search = Search(data=request.POST)
if search.is_valid():
ticker = search.save()
ticker.save()
success = True
else:
print search.errors
else:
search = Search()
return render_to_response('ui/search.html', {"search":search}, context)
Here is the html form that you use to type in (I'm using bootstrap for styling purposes):
<form class="navbar-form navbar-right" role="search" action="/search/" method="post" name="tick">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter stock symbol">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
And finally, I want the text entered in the form to be displayed on "search.html" which looks like this currently:
{% extends 'ui/base.html' %}
{% block title %} search {% endblock %}
{% block body_block %}
<br>
<p>test</p>
{{ form.search.data }} <!--I'm pretty sure this is not correct -->
{% endblock %}
Anyone know how I can do this? Thanks.
Your form name is search.
To render the value with modern django, you need to call the value method of the field, therefore your template should look like the following:
{{ search.search.value }}
Your template is wrong, as you suspect.
It is looking for a context variable named "form", but you have given it a context dictionary with a key named "search".
Also, "data" is the argument that you use to build up your Search object (correctly), but when you want to extract the user's input from it, you should use the field names instead, and you need to call value() on them in order to get the bound value. So, to get the contents of the text field called search, you should use search.search.value.
Try changing the line
{{ form.search.data }}
to
{{ search.search.value }}

Submitting multiple forms in Django

I'm not sure if i'm going about this completely the wrong way, but in my html template i have a for loop that i want to present multiple forms, and one submit button to submit the data from all forms:
{% for i in Attribute_list %}
<form action="/Project/create/" method=post>{% csrf_token %}
{{ i }}:
<input type=text name={{ i }}><br>
<hr>
{% endfor %}
<input type=submit>
The problem with this is it only submits the last form.
The other problem i'm running into is getting the data back from the view. Since i'm naming the form the variable "i", i don't know how to "get" this data in my views.py:
def create_config(request):
if request.method == 'POST':
data_list = []
for data in request.POST.getlist():
data_list.append(data)
can You check this?
<form action="/Project/create/" method="post">
{% csrf_token %}
{% for i in Attribute_list %}
{{ i }}: <input type="text" name="{{ i }}"><br>
<hr>
{% endfor %}
<input type="submit">
</form>
As I understand without JS regardless how many forms You create only one POST request will be made.
In oyur example HTML is not valid so It can behave different ways in different browsers. But as soon as You have not closed form last one should be submitted.
As for second part
def create_config(request):
if request.method == 'POST':
data_list = []
for data in request.POST.getlist():
data_list.append(data)
I think You should use your Attribute_list. Or You can just iterate over all `POST' variables obtained.
def create_config(request):
if request.method == 'POST':
data_list = []
for key in request.POST:
data_list.append(request.POST[key]) # or .extend(request.POST.getlist(key)

Categories