In templates folder I have index.html and template.html
I'm trying to GET data from a form in index.html, process the data and POST the results in template.html as .
index.html:
<form method="POST">
<select class="browser-default custom-select" name="regions_brato">
<option selected>Open this select menu</option>
{% for each,key in new_dict.items() %}
<option value="{{each}}">{{each}}</option>
{% endfor %}
</select>
<select name="list_status">
{% for key in listStatus %}
<option value="{{key}}">{{key}}</option>
{% endfor %}
</select>
<input type="submit">
</form>
template.html:
..
<body>
{% for each,key in res.items() %}
<p>{{each}}</p>
{% endfor %}
</body>
..
Flask:
#application.route('/', methods=['GET', 'POST'])
def form():
listStatus = ['en', 'fr', 'bg']
new_dict = {}
with open('fr.json') as json_file:
data = json.load(json_file)
for each in data:
new_dict.setdefault(each['admin'], []).append(each['city'])
if request.method == 'GET':
return render_template('index.html', listStatus=listStatus, default="en", new_dict=new_dict)
else:
return redirect(url_for('template'))
#application.route('/template')
def template():
region = request.form["regions_brato"]
lang = request.form["list_status"]
res = get_feel(region, lang, 30)
return render_template("template.html", res=res)
Can anyone point me to where exactly I have messed up the GET/POST requests and any possible solution ?
I don't know if you messed up something, but I know you can't test posting without some help, it is not viewable. You need an app like Postman or a server. Maybe it is just that.
Related
So I have a form that updates a key_instance object with a borrower. Currently my app needs the user to enter the name of the borrower, but I want it to display a dropdown list of data from another model the user model to select from, is there anyway to do this in a class based view? Here are my views.py and my template. What I was thinking is that I would like to use a get_list_or_404 on the user model and display it as a drop down list in the template and use that selection to populate the form field.
I manged to get the dropdown list to display in my template but I'm not sure as to how to save that value in my views.
Does anyone know if this is the right way or if this is doable? Thank you!!
views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(Users)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = UpdateKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = form.cleaned_data['borrower']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
form = UpdateKeyForm(initial={'borrower': 'N/A'})
return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst':key_inst})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
<table style="display: inline-flex">
{{ form}}
</table>
<select name = 'name'>
{% for name in names %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
Here is how I manged to do it, Not sure if this is the best 'pythonic' or best practice. Please let me know if it's not.
my views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(User)
# If this is a POST request then process the Form data
if request.method == 'POST':
name = request.POST['name']
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = name
key_inst.save()
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
pass
return render(request, 'catalog/keyinstance_request_update.html', {'keyinst':key_inst, 'names':names})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
</br>
<select name = 'name' required>
{% for key in names %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
I want to query data,use the selectfield as a condition,then show the result in a html and use paginage.
my question is when i display my data,the first can display normally but when i click the next_page,the selectfield is none and the data can not display.
what should I do to keep the selectfield when I click the next_page?
Your view should accept an integer to allow for the passing of the current datum. Below is an example:
#app.route('/view/<int:page>',methods=['GET'])
def view(page=1):
if request.method == 'POST':
select = int(request.form.get('select'))
print(select)
per_page = 2
try:
users = User.query.order_by(User.email.asc()).paginate(select,
per_page=per_page,
error_out=False)
except NameError:
users = User.query.order_by(User.email.asc()).paginate(page,
per_page=per_page,
error_out=False)
return render_template('view.html',users=users)
The view would look something like this:
<html>
<head>Welcome</head>
<body>
<form method="POST" action="{{ url_for('view', page=users.prev_num + 1) }}">
<div>
<div>
<span>Please select</span>
<select name="select">
{% for user in users.items %}
<option value="{{ user.id }}">{{ user.username }}</option>
{% endfor %}
</select>
</div>
<button type="submit">Go</button>
</div>
</form>
{% if users.has_prev %}<< Newer users{% else %}<< Newer posts{% endif %} |
{% if users.has_next %}Older users >>{% else %}Older posts >>{% endif %}
</body>
</html>
I am having issues with a search form. I am trying to make a search field that queries the database and returns results on my results page. I have the page returning 1 result with a certain query and the other query with multiple rows I get this error get() returned more than one MyModel -- it returned 791!. This may seem silly as I am new to Django Forms. Please let me know if you need any other info. I have tried using .filter but that returns nothing. I have looked at multiple SO questions and some have helped but still having a little issue. My code is below:
views.py
from django.shortcuts import render
from .models import Model
def index(request):
return render(request, 'index.html')
def search(request):
query = request.GET.get('q')
if query:
query = str(query)
results = myModel.objects.get(
site=query
)
context = {"results": results}
return render(request, 'results.html', context)
results.html
{% if results %}
<ul>
<li><p>{{ results.url }}</p></li>
</ul>
{% else %}
<p>Nothing Available.</p>
{% endif %}
index.html
<form action="/results/" method="GET">
{% csrf_token %}
<input id="search_box" type="text" name="q" placeholder="Search...">
<button id="search_submit" type="submit" class="btn btn-defaultbtnlg"><i class="fa fa-search fa-fw"></i> <span class="networkname">Search</span></button>
</form>
Your search query can return more than one result, so you should use filter() instead of get().
results = myModel.objects.filter(
site=query
)
Then in your template, loop through the results
{% if results %}
<ul>
{% for result in results %}
<li><p>{{ result.url }}</p></li>
{% endfor %}
</ul>
{% else %}
<p>Nothing Available.</p>
{% endif %}
I'm making a post from a webpage that is generated dynamically from Django DB content. The data is put into a combo box and is supposed to send the customer id back to Django so I can parse some more queries with it and then display only the customers data that was selected.
However instead of retruning my post data it returns the csrf token instead of the posted data.
<form method='post' action='' id='customers'>
{% csrf_token %}
<select>
{% for item in customer %}
<option value={{ item.customer_id }} name='customer_id'>{{ item.customer_name }}</option>
{% endfor %}
<input type = 'submit' value='Edit'>
</select>
{{ post }}
{{post.customer_id}} #doesnt work either.
this is what it returns:
<QueryDict: {u'csrfmiddlewaretoken': [u'CpzKrwmZsmfiiNHngNWDFSNxqUoBykYO']}>
def portal(request):
customers = Customer.objects.all()
if request.method == 'POST':
vm_groups = Vm_group.objects.all()
vms = Vm.objects.all()
selected_customer = request.POST.copy()
#selected_customer_id = selected_customer['customer_id']
post = selected_customer
context = Context({'customer': customers, 'vm_groups':vm_groups, 'vms':vms, 'post':post,
})
return render(request, 'portal.html', context)
else:
context = Context({'customer': customers,})
return render(request, 'portal.html', context)
Also how would I get just the customer_id from the returned data once it works correctly?
selected_customer = request.POST.copy()
selected_customer_id = selected_customer['customer_id']
Like so?
You need to put the name attribute on the select element, not the option.
But you should probably be using Django's forms framework, anyway.
As #Daniel told that, You need to add name field to select tag not for option tag,
<select name='customer_id'>
{% for item in customer %}
<option value={{ item.customer_id }} >{{ item.customer_name }}</option>
{% endfor %}
<input type = 'submit' value='Edit'>
</select>
I use Django Endless Paginator plugin.
I try to change the value of ENDLESS_PAGINATION_PER_PAGE from template side.
As default is 10.
I want to realize some dropbox where the user can change between (Example: 10,20,50,100 Objects).
Thanks for answer, but something not work property.
1. I have view.py
def adv_search(request):
objects = None
if request.GET.get('key'):
form = AdvancedSearchForm(request.GET)
if form.is_valid():
repo = Repository()
objects = list(repo.find_objects('*'+form.cleaned_data['key'] +'*', type=FileObject, chunksize=20))
return render(request, 'templates/adv_search.html', {'form': form, 'objects': objects })
return render(request, 'templates/adv_search.html', {'form': AdvancedSearchForm(), 'objects': objects})
2. Then forms.py
class AdvancedSearchForm(forms.Form):
key = forms.CharField(max_length=500, label="", widget= forms.TextInput(attrs={'class': 'label'}))
show_props = forms.MultipleChoiceField(choices = (("pid", "pid"),("title", "title"),("type","type"),("source","source"),("date","date"),("publisher","publisher"),("subject","subject"),("label","label"),("cDate","cDate"),("mDate","mDate")),required=False, widget=forms.CheckboxSelectMultiple(attrs={'class': 'my-class'}))
paginator = forms.ChoiceField(choices =(('10', '10'),('20','20'), ('50','50'), ('100','100')) ,required=False, )
3. adv_search.html
{% paginate paginator objects %}
{% for obj in objects %}
...
<div class="paginator">
{% get_pages %}
{{ pages.first_as_arrow }}
{% show_pages %}
{{ pages.last_as_arrow }}
<form method="get">
{{ form.paginator }}
<input type="submit" Value="Go">
</form>
{{ pages.total_count }} total objects
</div>
Everything works except select
Thanks Andrey
You can have a form which will set pagination per page and then use that submitted value in template. Here is an example:
View
from django.shortcuts import render
from .models import Entry
def endless_view(request):
pagination_per_page = request.GET.get('per_page', 10)
entries = Entry.objects.all()
return render(request, 'some_template.html', {'pagination_per_page':
pagination_per_page, 'entries': entries})
Template
{% extends 'base.html' %}
{% load endless %}
{% block content %}
{# #}
<form action="" method="get">
<select name="per_page">
<option value="10">10 per page</option>
<option value="20">20 per page</option>
<option value="50">50 per page</option>
<option value="100">100 per page</option>
</select>
<input type="submit" Value="Go">
</form>
{% paginate pagination_per_page entries %}
{% for entry in entries %}
{# your code to show the entry #}
{% endfor %}
{% show_pages %}
{% endblock content %}
Reference
http://django-endless-pagination.readthedocs.org/en/latest/templatetags_reference.html