Flask request issue - python

I'm making different sized tables base off a given list and it is generated via a for loop with flask in HTML. The issue that I am having is that I'm not sure how to retrieve the values that are being entered into the type="number" form. Here is an example of my code.
HTML code:
<table>
<tr>
<th><h1>Name</h1></th>
<th><h1>Number</h1></th>
</tr>
{% for i in range(names|length) %}
<tr>
<td><h2>{{ names[i] }}</h2></td>
<td><form>
<input type="number" name="{{ i }}" placeholder="0" step="1" min="0" max="10" formmethod="post">
</form></td>
<td><form>
<input type="submit" class="btn" name="save_button" value="Save" formmethod="post">
</form></td>
</tr>
{% endfor %}
</table>
Flask code:
#app.route('/', methods=['GET', 'POST'])
def phone():
names = ['Jacob', 'Joe', 'Billy', 'Sue', 'Sally']
if request.form.get('save_button'):
for name in names:
print(request.form.get('name')
return render_template('phone.html', names=names)
The only thing returned is "None." Any help is greatly appreciated.

try request.form.get("0")
its because your inputs name is not "name" so there is no value in request.form.get("name")
<input type="number" name="{{ i }}" placeholder="0" step="1" min="0" max="10" formmethod="post">
sets the name to whatever i is (ie a value from 0..N)..,

Related

How to combine two dictionaries in Python without duplicates

Hey I'm trying to combine two dictionaries filled with JSON data without duplicates. I'm using Flask and Jinja2 to build an api to fetch json data from an api and post it on a web page, I want to be able to filter based off of tags and then combine the results every time I make a request. Currently I'm able to filter based off of tags chosen by submitting buttons on Jinja but I'm having trouble getting it to combine when I select a new tag, when a new tag is selected it filters only using that tag and doesn't combine the dictionary from the previous result.
main.py:
#app.route('/api', methods=['GET', 'POST'])
def add_tag():
name = request.form['tags']
form = APInameForm()
url= 'https://api.hatchways.io/assessment/blog/posts?tag='+name
try:
api = requests.get(url).json()
api = api['posts']
ilist = []
nlist = []
for i in api:
ilist.append(i)
if not ilist:
output = '{<br>'
output = output + '"error": "Tags parameter is required" <br>'
output = output + '}'
return output
return render_template('/index.html', test=ilist)
except requests.ConnectionError:
return "Connection Error"
#app.route('/')
def index():
return render_template("index.html")
index.html:
{% extends 'base.html' %}
{% block content %}
<form class="text-center pt-3" method="POST" action="/api">
<input type="text" class="form-control" placeholder="Search" name="tags">
<input type="submit" value="Search" />
</form>
<br/><br/><br/>
<h1>Recommended Tags:</h1>
<form class="form-inline" method="POST" action="/api">
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="tech">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="history">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="startups">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="health">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="science">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="design">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="culture">
</input>
</div>
<div class="control">
<input type="submit" class="btn btn-primary mb-2" name="tags" value="history">
</input>
</div>
</form>
<br/><br/><br/>
<code>
{<br>
"posts": [{<br>
{% for item in test %}
"id": {{ item.id }}<br>
"author": {{ item.author }}<br>
"autherId": {{ item.authorId }}<br>
"likes": {{ item.likes }}<br>
"popularity" :{{ item.popularity }}<br>
"reads": {{ item.reads }}<br>
"tags": {{ item.tags }}<br><br>
{% endfor %}
}
]
</code>
{% endblock %}
I am not sure I really understand your question.
But could it be that a simple use of a set will solve your problem?
Sets can't have duplicates
https://www.w3schools.com/python/python_sets.asp
You need to store the previous data somewhere outside these functions to be able to use it in later calls to them. Temporarily, that could be in a variable defined at the top level in your module (.py file).
If you need it to persist longer (across worker threads, sessions or restarts of your custom server), you might need to write to a file or database.
To merge the JSON dictionaries you can use the dict.update method (see official docs).
Given two dict instances d1, d2, calling d1.update(d2) will merge d2 into d1, overwriting values for any keys that are the same.
combined_data = {}
#app.route('/api', methods=['GET', 'POST'])
def add_tag():
response = requests.get(url)
data = response.json()
combined_data.update(data)
# ..now render combined_data

Django formset error for ID "Select a valid choice. That choice is not one of the available choices"

I am posting a formset in Django. The form on the client side is generated dynamically using a file uploaded by the user. I render it like this:
<form method="post" id="add3">
{{ formset.management_form }}
{% csrf_token %}
<table id="forms">
<tbody>
{% for lst in result %}
<input type="hidden" name="form-{{ forloop.counter0 }}-id" value="{{ forloop.counter }}" id="id_form-{{ forloop.counter0 }}-id">
<tr>
<td>
<input type="hidden" name="form-{{ forloop.counter0 }}-expense" id="id_form-{{ forloop.counter0 }}-expense" value="{{lst.0}}"/>
</td>
<td>
<input type="hidden" name="form-{{ forloop.counter0 }}-amount" id="id_form-{{ forloop.counter0 }}-amount" value="{{lst.1}}"/>
</td>
{% endfor %}
</tbody>
</table>
</form>
I get the following error on the server side when I receive the formset. Formset is_valid returns False and I get the error:
id: Select a valid choice. That choice is not one of the available choices
How can I fix this? What's the right way to pass an ID?
Note: I am updating management_form total-forms using Javascript. If that matters.

How to save data entered in a bootstrap modal into another model

I am trying to create a django based load-requirement matching web-app which takes "Load details" in a model called ShipperBoardModel where people(manufacturers) post that they want certain items to be delivered somewhere, and other people(called transporters) who bid on those posts, that they can get that job done, for their chosen price.
ShipperBoardModel
class ShipperBoardModel(models.Model):
From = models.CharField(max_length=100,null=True)
To = models.CharField(max_length=100,null=True)
Type = models.CharField(max_length=100,null=True)
Length = models.CharField(max_length=100,null=True)
Weight = models.CharField(max_length=100,null=True)
Numberoftrucks = models.IntegerField(null=True)
MaterialType = models.CharField(null=True,max_length=100)
Loadingtime = models.DateTimeField(null=True)
def _str_(self):
return self.Origin
I created the first 'loads' table where many people posted their loads on it, and this is being displayed on a page "/loads/" where it shows all active loads available for bidding.
I added a "Bid now" button next to every row, clicking on which opens a form which asks the transporters what price they are willing to bid for that particular load/task.
On clicking 'Bid now', we get a pre-filled form in a bootstrap modal relative to the row it is in. Then, a transporter enters his bid for that task/load, which I want to save into another model called 'SupplierBidModel'.
I just want to figure out how to save that bid price, into that model, along with the BidID, and the transporterID which every transporter already has when they registered.
Here is the form, followed by the model:
class SupplierBidModel(models.Model):
BidID = models.AutoField(primary_key=True)
Load_ID = models.OneToOneField(ShipperBoardModel,on_delete=models.CASCADE)
Supplier_ID = models.OneToOneField(SupplierBoardModel,on_delete=models.CASCADE)
Bid_amount = models.IntegerField(null=True)
I have some data saved in my models.py, and using that model I am rendering a table. Now, for each row I want the user to enter a single entry, which should save that data into another model.
Here is the template :
{% block content %}
<table>
{% for item in data %}
<tr>
<th>From</th>
<th>To</th>
<th>Weight</th>
<th>Length</th>
<th>Type</th>
<th>Material Type</th>
<th>Number of Trucks</th>
<th>Loading Time</th>
</tr>
<tr>
<td>{{ item.From }}</td>
<td>{{ item.To }}</td>
<td>{{ item.Weight }}</td>
<td>{{ item.Length }}</td>
<td>{{ item.Type }}</td>
<td>{{ item.MaterialType }}</td>
<td>{{ item.Numberoftrucks }}</td>
<td>{{ item.Loadingtime }}</td>
<td>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal{{ item.id }}">Bid
now! for id {{ item.id }} </button>
</td>
{# {% endfor %}#}
<div class="modal fade" id="myModal{{ item.id }}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.To }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.From }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Weight }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Length }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Type }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.MaterialType }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Numberoftrucks }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here..." value="{{ item.Loadingtime }}" disabled>
<input class="form-control" id="disabledInput" type="text"
placeholder="Disabled input here...">Bid
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</tr>
{% endfor %}
</table>
{% endblock %}
I do not yet know how to render a form, on a page in django, where there exists a form already. The only way to render form I know of, is using the urls.py method :
urlpatterns = [
url(r'supplier', views.supplierboardfun, name='supplierboard'),
url(r'shipper', views.shipperboardfun, name='shipperboard'),
url(r'loads', views.suppliertablefun, name='supplierboardtable')
]
which calls the function suppliertablefun()
def suppliertablefun(request): # function to display shipperboardmodel
data = ShipperBoardModel.objects.all()
return render(request, 'supplierboard/board.html', locals())
I am probably missing on how to render a multiple forms with different models in django, or how to save data from an input box, and save it to the model of my liking along with some relative information.
I figured it out. I was able to do it as such
def suppliertablefun(request): # function to display shipperboardmodel
data = ShipperBoardModel.objects.all()
if request.method == 'POST':
forminput = BiddingForm(request.POST)
if forminput.is_valid():
forminput.save()
forminput = BiddingForm(request.POST)
return render(request, 'supplierboard/board.html', locals(),{'forminput': forminput})

how to read input from arrays in django

I have the following form
{% for key in keys %}
<th>
<div class="card-body">
<label for="{{ key }}">Should We import this column?</label>
<input id="{{ key }}" name="import[]" value="{{ key }}" type="checkbox">
</div>
</th>
{% endfor %}
which renders like this
<input id="name" name="import[]" value="name" type="checkbox">
<input id="name" name="import[]" value="email" type="checkbox">
<input id="name" name="import[]" value="category" type="checkbox">
what I expect is when the checkboxes are selected the value should be present in the import[] array. but after the form is posted, what I get is,
# from request.POST array
'import[]' = 'email' # whichever I selected last
where what i expect is the following,
import = [
'email',
'name'
]
how can i achieve this in django, i am not using any forms so far.
Django 2, Python 3.5

Unable to delete row in datastore

I am new to Google App Engine and datastore so please be patient :)
My code below is trying to ask for user inputs, either entering or deleting an entry, and the results will be shown directly in a table on the same page. When I tried to delete a particular entry in the datastore, the row does not get deleted in the datastore and sometimes new rows with empty data are added. Why does this happen?
class Events(ndb.Model):
name = ndb.StringProperty()
desc = ndb.StringProperty()
class Promote(webapp2.RequestHandler):
def get(self):
query = ndb.gql("SELECT * "
"FROM Events "
)
template_values = {"events" : query,}
template = jinja_environment.get_template('promote.htm')
self.response.out.write(template.render(template_values))
def post(self):
event = Events(name = self.request.get('name'), desc = self.request.get('desc'))
event.put()
self.redirect('/promote')
class Delete(webapp2.RequestHandler):
def post(self):
event = ndb.Key('Events', self.request.get('eventname'))
event.delete()
self.redirect('/promote')
app = webapp2.WSGIApplication([('/', Main),
('/publicsearch', PublicSearch),
('/promote', Promote),
('/delete',Delete)],
debug=True)
This is the html code
<div class="jumbotron">
<div class = "container">
<form action="/promote" method="post">
<fieldset>
<div class="row-fluid">
<p> Promote your event here! </p>
<div class="row-fluid">
<div class="span6">
<p> Name of event: <br>
<textarea class="input-block-level" name="name" rows="1" cols = "50"> </textarea></p>
<p> Event description: <br>
<textarea class="input-block-level" name="desc" rows="3" cols = "50"> </textarea></p>
<p><input type="submit" value="Submit">
</div>
</div>
</div>
</div>
</div>
<h4> Events feed </h4>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th width="30%">Name</th>
<th width="60%">Description</th>
<th>Delete Event</th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td>{{ event.name }} </td>
<td>{{ event.desc }} </td>
<td>
<form action="/delete" method="post">
<input type="hidden" name="eventkey" value="{{ event.key.urlsafe() }}">
<input type="submit" value="Delete">
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
Thanks!
The key is not based on the event name, because you haven't specified any key when creating the events: they'll just use a numeric id.
The better thing to do here would be to put the actual key in the hidden input: you can use the urlsafe method to output a string that can be used in templates.
<input type="hidden" name="eventkey" value="{{ event.key.urlsafe() }}">
and in the view:
event = ndb.Key(urlsafe=self.request.get('eventkey'))

Categories

Resources