I have a problem with the home page displaying form values. Although on the search page the values are fine. What could be the problem here? I copied the same form from the search page to the homepage but still, it doesn't work, the values are empty. Any hint is appreciated, thank you!
search page:
<form action="{% url 'search' %}">
<div class='flx around px'>
<input type='text' id='search-keyword' class='search-keyword form-control'
placeholder='keywords (pool,garage)'>
<select name='area' id='search-area' class='form-control'>
<option selected="true" disabled="disabled" selected>Area(All)</option>
{% for key,value in area_choices.items %}
<option value="{{ key }}" {% if key == values.area %} selected {% endif %}>{{ value }}</option>
{% endfor%}
</select>
</div>
<div class='flx around'>
<select name="bedrooms" class="form-control">
<option selected="true" disabled="disabled" selected>Bedrooms(All)</option>
{% for key,value in bedroom_choices.items %}
<option value = "{{ key }}"
{% if key == values.bedrooms %}
selected
{% endif %}
>{{ value }}</option>
{% endfor %}
</select>
<select name="price" class="form-control ">
<option selected="true" disabled="disabled" selected>Price(All)</option>
{% for key,value in price_choices.items %}
<option value = "{{ key }}"
{% if key == values.price %}
selected
{% endif %}
>{{ value }}</option>
{% endfor %}
</select>
</div>
<button type = "submit" class='btn fntmk my2 size'>Search <i class="fas fa-search size"></i></button>
</form>
home page:
<form action="{% url 'search' %}">
<div class = 'flx around px iphone'>
<input name = 'keywords' type = 'text' id = 'search-keyword' class = 'search-keyword form-control' placeholder = 'keywords (pool, garage)'>
<select name = 'area' id = 'search-area' class = 'form-control'>
{% for key,value in area_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
</div>
<div class = 'flx around iphone'>
<select name="bedrooms" class="form-control">
<option selected="true" disabled="disabled" selected>Bedrooms(All)</option>
{% for key,value in bedroom_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
<select name="price" class="form-control ">
<option selected="true" disabled="disabled" selected>Price(All)</option>
{% for key,value in price_choices.items %}
<option value = "{{ key }}">{{ value }}</option>
{% endfor %}
</select>
</div>
<button type = "submit" class = 'btn fntmk my2 size'>Search <i class="fas fa-search size"></i></button>
</form>
view:
from .choices import price_choices, bedroom_choices, area_choices
def search(request):
queryset_list = Oglas.objects.order_by('-list_date')
# keywords
if 'keywords' in request.GET:
keywords = request.GET['keywords']
if keywords:
queryset_list = queryset_list.filter(description__icontains = keywords)
# Area
if 'area' in request.GET:
area = request.GET['area']
if area:
queryset_list = queryset_list.filter(area__iexact = area)
# rooms
if 'bedrooms' in request.GET:
bedrooms = request.GET['bedrooms']
if bedrooms:
queryset_list = queryset_list.filter(bedrooms__lte=bedrooms)
# price
if 'price' in request.GET:
price = request.GET['price']
if price:
queryset_list = queryset_list.filter(price__lte = price)
context = {
'area_choices' : area_choices,
'bedroom_choices' : bedroom_choices,
'price_choices' : price_choices,
'listings' : queryset_list,
'values' : request.GET,
}
return render(request, 'pages/search.html', context)
Form are handled completly different. You're mixing up the template with the form handling.
Have a look in the doc first. You need to add a form object into your context.
Extract from the mentioned doc:
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
Related
In home.html
<div class="container">
<div class="row">
<div class="col-md-6">
<h3>Select products:</h3>
<form id="selectProduct" role="search" method="get" action="{% url 'home' %}">
<select name="parameters" data-placeholder="Choose products" class="chosen-select" multiple tabindex="4">
{% for p in productnames %}
{% if k == p %}
<option value="{{ p.productnames }}" selected> {{ p.productnames }} </option>
{% else%}
<option value="{{ p.id }}"> {{ p.productnames }} </option>
{% endif %}
{% endfor %}
</select><br/>
<label for="submit"></label><button id="submit" type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="row"></div><br />
<h3> Distribution of sales in the products:</h3>
</div>
</div>
{% for p in productList %}
{% for pin in productnames %}
<p>{{pin.id}} {{p}}</p>
{% if p == pin.id %}
<p>exists</p>
{% else %}
<p>not exist</p>
{% endif %}
{% endfor %}
{% endfor %}
<p>{{ productList }}</p>
in this html file 'p' always returns a string value for ex: it returns like '10' instead of 10. all i want is to convent this '10' to 10 or convert returned other p_in value to 10 to '10'.
in views.py
def productList(request):
if request.method == 'GET':
p = request.GET.get('parameters')
print(p)
#k = request.GET('parameters[]')
productnames = Products.objects.all()
context = {
'productList': p, 'productnames': productnames,
}
return render(request, 'home.html', context)
I tried to convert the values of the p in product list to integer. because it dosen't mactch the format with pin.id
You filter the queryset in the template using if-else which is not ideal. Instead you should perform this filtering in the view itself. Also your parameters is a select tag which may have multiple selected values yet you use .get('parameters') which will only give you one value instead you should use the getlist method [Django docs] of the QueryDict:
def productList(request):
if request.method == 'GET': # Do you even need to check this? You appear to only use a GET request...
p = request.GET.getlist('parameters')
productnames = Products.objects.all()
filtered_products = Products.objects.filter(pk__in=p)
context = {
'productList': p, 'productnames': productnames, 'filtered_products': filtered_products
}
return render(request, 'home.html', context)
In the template your loop would simply become:
{% for product in filtered_products %}
{{ product.productnames }}
{% endfor %}
Note: You should use a form class instead of manually making a form. See Building a form in
Django.
Also a models name should be singular hence instead of
Products you should name it Product. In general in
your code you also break various naming conventions in Python, I would
suggest you to look at PEP 8 -- Style Guide for Python
Code
In views.py
def productList(request):
if request.method == 'GET':
p = request.GET.getlist('parameters')
print(p)
#k = request.GET('parameters[]')
productnames = Products.objects.all()
context = {
'productList': p, 'productnames': productnames,
}
# --- logic later for chart ------
return render(request, 'home.html', context)
In home.html
<div class="container">
<div class="row">
<div class="col-md-6">
<h3>Select products:</h3>
<form id="selectProduct" role="search" method="get" action="{% url 'home' %}">
<select name="parameters" data-placeholder="Choose products" class="chosen-select" multiple tabindex="4">
{% for p in productnames %}
{% if k == p %}
<option value="{{ p.productnames }}" selected> {{ p.productnames }} </option>
{% else%}
<option value="{{ p.id }}"> {{ p.productnames }} </option>
{% endif %}
{% endfor %}
</select><br/>
<label for="submit"></label><button id="submit" type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
<div class="row"></div><br />
<h3> Distribution of sales in the products:</h3>
</div>
</div>
{% for p in productList %}
{% for pin in productnames %}
<p>{{pin.id|stringformat:"s"}} {{p}}</p>
{% if p == pin.id|stringformat:"s" %}
<p>exists</p>
{% else %}
<p>not exist</p>
{% endif %}
{% endfor %}
{% endfor %}
<p>{{ productList }}</p>
Note {{value|stringformat:"s"}} can be used to convert integer value to string value
I want to update / edit a product from a page by clicking a form button (UPDATE) after selecting product from a dropdown list or an auto-complete list.
List.html page works fine while clicking on UPDATE button update.html page cannot parse the POST data.
Manually I could access update.html with pk suffix (/update/1/), it is working fine too.
How can I pass pk's value alone to url?
views.py
class ProductUpdateView(UpdateView):
template_name = 'update.html'
model = Product
fields = ['name', 'description', 'image', 'file',]
success_url = '/list/'
class ProductsView(ListView,):
template_name = 'list.html'
model = Product
urls.py
urlpatterns = [
url(r'^list/$', ProductsView.as_view(), name='list'),
url(r'^update/(?P<pk>[0-9]+)/$', ProductUpdateView.as_view(), name='update'),
]
list.html
<body>
<form method='POST' action='/update/'> {% csrf_token %}
<select name='pk'>
{% for obj in object_list %}
<option value='{{ obj.id }}'>{{ obj.name }}</option>
{% endfor %}
</select>
<input type="submit" value='UPDATE'>
</form>
</body>
You can do this by only using <select>
<select name="select_path" id="select_path"
ONCHANGE="location = this.options[this.selectedIndex].value;">
{% for obj in object_list %}
<option value="{% url app_name:update obj.id %}">{{ obj.name }}
</option>
{% endfor %}
</select>
You just need to change the option value, I don't know the exact url, tewak as per your requirement.
I know it's a little bit late but this answer will definitely help someone.
<select name="select_path" id="select_path">
<option value="{{ initial_value }}">{{ initial_value name }}</option>
{% for obj in object_list %}
<option value="{{ edited object value }}">{{ edited obj.name }}
</option>
{% endfor %}
</select>
Get the value normally as you would when saving a form.
I'm really stuck on this one. I have a working view/template that has a form select option that populates options from my model
views.py
def random(request):
classroom = Classroom.objects.filter(teacher=request.user).order_by('course_block')
classblock = request.GET.get('class_block')
students = Student.objects.all().filter(classroom__course_block=classblock)
nicknames = [s.nickname for s in students]
data = serializers.serialize("json", students, fields = ("nickname", "attend"))
student_names = json.dumps(list(nicknames))
context = {'students': students}
context['classroom'] = classroom
context['student_names'] = student_names
context['data'] = data
template = loader.get_template('randomizer/randomize.html')
print (data)
return render(request, 'randomizer/randomize.html', context)
ramdomize template
{% extends 'randomizer/base.html' %}
{% load static %}
{% block body %}
<div id="djangorandom">
{{ classroom.id }}
<form action="{% url 'randomizer:random' %}" method="get">
{% csrf_token %}
<div class="form-group">
<select class="form-control" name="class_block">
{% for room in classroom %}
<option value={{ room.course_block }}>{{ room.get_course_block_display }}</option>
{% endfor %}
</select>
</div>
<span><input class="btn btn-default" type="submit" value="Submit"></span>
</form>
</div>
Page source returns:
<div class="form-group">
<select class="form-control" name="class_block">
<option value=11>Block 1-1</option>
<option value=13>Block 1-3</option>
<option value=14>Block 1-4</option>
<option value=P13>Pair 1-3</option>
</select>
</div>
Now I've copied a lot of this code for a slightly different template and purpose:
def pair(request):
classroom = Classroom.objects.filter(teacher=request.user).order_by('course_block')
classblock = request.GET.get('class_block')
students = Student.objects.all().filter(classroom__course_block=classblock)
nicknames = [s.nickname for s in students]
data = serializers.serialize("json", students, fields = ("nickname", "attend"))
student_names = json.dumps(list(nicknames))
context= {'classroom': classroom}
context['students'] = students
context['student_names'] = student_names
context['data'] = data
template = loader.get_template('randomizer/pairing.html')
print(data)
return render(request, 'randomizer/pairing.html')
{% extends 'randomizer/base.html' %}
{% load static %}
{% block body %}
<div id="djangorandom">
{{ classroom.id }}
<form action="{% url 'randomizer:pair' %}" method="get">
{% csrf_token %}
<div class="form-group">
<select class="form-control" name="class_block">
{% for room in classroom %}
<option value={{ room.course_block }}>{{ room.get_course_block_display }}</option>
{% endfor %}
</select>
</div>
<span><input class="btn btn-default" type="submit" value="Submit"></span>
</form>
</div>
But the page source doesn't show any of the options for the form selects:
<form action="/randomizer/pairing/" method="get">
<input type='hidden' name='csrfmiddlewaretoken' value='ADVUsnTserljrnDvRlmeTPyvjMOzva5xj7t8LSeDmPxnkBUtx4XmfXAI5aRfJky6' />
<div class="form-group">
<select class="form-control" name="class_block">
</select>
</div>
<span><input class="btn btn-default" type="submit" value="Submit"></span>
</form>
I've practically copied everything from the first view/template to the second view/template. I wondered if there was a scope issue where def pair re-uses the code from def random, but I commented out def random and that didn't help.
Your second view doesn't pass the context into the render() call, so there is no classroom variable and nothing to iterate over in the template.
(Note, in both views the template = loader.get_template(...) call is irrelevant and not used; you should remove those lines.)
I am trying to render fields manually in django formset.
<select class="form-control" id="{{ line_form.label.id_for_label }}" name="{{ line_form.label.name }}">
{% if form.label.value %}
<option value="{{ form.label.value }}">{{ form.label.value }}</option>
{% else %}
<option value="" selected>-</option>
{% endif %}
{% for item in view.items %}
<option value="{{item.id}}">{{item.name}}</option>
{% endfor %}
</select>
The name of the above field is label but i want it to lines-0-label. When i add a new form in the formset the above field has the same name it should be lines-1-label, and should increase so on. i.e., lines-2-label, lines-3-label, lines-4-label, ...., lines-101-label.
views.py
class InvoiceCreateView(generic.CreateView):
template_name = "books/invoice_create_or_update.html"
model = Invoice
form_class = InvoiceForm
formset_class = InvoiceLineFormSet
success_url = reverse_lazy("books:invoice-list")
In my html I am dynamically generating drop-down options with the same name
<form action="{% url manageCsv %}" method="post">
{% csrf_token %}
<p>
<input type="hidden" name="doc_id" value="{{ doc_id }}">
{% for column in file_columns %}
Column {{ forloop.counter0|add:1 }}
<select name="columns">
<option value="blank"></option>
{% for column_value in file_columns %}
<option value="{{ column_value }}">{{ column_value }}</option>
{% endfor %}
</select>
{% endfor %}
</p>
<p>
<input type="submit" value="Submit" />
</p>
</form>
UPDATE:
My Views.py :
def manageCsv(request):
if request.method == 'POST':
file_id = request.POST['doc_id']
csvColumns = request.POST['columns']
print >> sys.stderr, csvColumns['columns']
return HttpResponseRedirect(reverse('index'))
In my view when I print my request.POST I get everythin I need :
<QueryDict: {u'csrfmiddlewaretoken': [u'lGlxVmiYI9xFb5bV7cJPrP9GR0t0LYTi'], u'doc_id': [u'14'], u'columns': [u'Organisation', u'Sum of products']}>
But the problem I am facing is that when I assign csvColumns = request.POST['columns'] , csvColumns prints out only Sum of products from the list and not the entire List [u'Organisation', u'Sum of products']
How can I get the entire list ? What have I missed ?
Any help on this would be great
Thanks in advance
Try to do it like this as explained in the docs:
csvColumns = request.POST.getlist('columns',None)
Hope this helps!