How to structure form data within MongoDB (Python/Flask) - python

I am having trouble structuring my data within MongoDB from user forms.
My ideal document structure is this:
As you can see the ingredients are within an array that would be iterable.
However I cannot work out a way when submitting my form to do this. My form for the ingredients section looks like this:
<h4>Ingredients</h4>
</div>
<div class="row">
<div class="input-field col s6">
<input id="ingredients_1_name" name="ingredients_name_1" type="text" class="validate" required>
<label for="ingredients_1_name">Ingredient</label>
</div>
<div class="input-field col s3">
<input id="ingredients_1_quantity" name="ingredients_quantity_1" type="text" class="validate" required>
<label for="ingredients_1_quantity">Quantity</label>
</div>
<div class="input-field col s3">
<input id="ingredients_1_unit" name="ingredients_unit_1" type="text" class="validate" required>
<label for="ingredients_1_unit">Unit</label>
</div>
</div>
The user is able to press a JavaScript button that adds a new row with the name "ingredients_2_name" and so on. This leads to a very unstructured DB:
This is obviously a mess which when it comes to using the data requires an unnecessary amount of manipulation.
I can't seem to find any information online about how to send data from a HTML form to MongoDB in a defined way.
Currently on form submission, the view looks like this:
#app.route('/insert_recipe/', methods=['GET','POST'])
def insert_recipe():
"""
This function is called when a user clicks the submit button on the add
recipe form. Uses the insert_one() method to add to the recipes document.
"""
recipes = mongo.db.recipes
dictionary = recipes.insert_one(request.form.to_dict())
return redirect(url_for("get_recipes"))
This simply takes the input names as keys and the user input as values.
Is anyone able to describe how I am able to store form data within MongoDB in a structured way?

What you require is to convert a plain HTML-form-post request into a JSON-like structure without any data manipulations. I highly doubt that it's even possible, because JSON-objects use nested data and a key/index approach to access it and HTML-form-post data is flat and follows unique-id-approach to access it's data. I can see 2 possible solutions:
Use serialization library WTForms which will do python-data -> html-form -> python-data conversion for you and you wouldn't have to do an unnecessary amount of manipulation by yourself.
Make a webpage (a front-end) post request for you as a JSON-object.

Related

HTML, how to auto select the date time picker from sql database

I've a HTML form for editing existing data.
Let's say today is 10/06/2022 18:05 and i want to edit my course date time in my web app.
My course date on the data base is 21/08/2023 10:00. I want to change it to 22/08/2023 10:00. When I open my from on the web app all the inputs came with the existing data already selected. But date time picker comes as 10/06/2022 18:05. I've set the value as the date attribute of course object but it's not working. This works for the rest of the inputs but not for the datetime input.
I basically need the html date time picker comes with autoselected with the existing saved data <course.date> .
I'm writing this web app on python flask and using a postgresql for database. The other inputs comes with selected values but not datetime input.
Anyone has any ideas how to approach this one?
<form action="/courses/{{course.id}}" method="post">
<label for="course">Course Title</label>
<input type="text" name="title" value="{{course.title}}">
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date}}">
<label for="capacity">Capacity</label>
<input type="number" name="capacity" value="{{course.capacity}}">
<label for="active">Active</label>
<select name="active">
<option value="True">Active</option>
<option value="False" {% if course.active == False %} selected {%endif%}>Deactive</option>
</select>
<input type='submit' value="Update Course">
</form>
If I am understanding the issue right:
course_date in the database is: 21/08/2023 10:00
course_date in the app remains as the local-current time: 10/06/2022 18:05 (example)
GET request properly loads data from the database into the other fields except course-date
you've tried making a POST request to update course_date, but the field doesn't change
My suggestion to debug this is to look at the responses to your GET request. What do they come out as?
Inside your GET request's response,
if the course-date is 21/08/2023 10:00, that means your problem is in your javascript or the code that plugs in your field value inside the HTML. Your frontend field is simply ignoring the response from flask or the data is not being mapped/handled right
if the course-date is 10/06/2022 18:05 or is null. That means your flask backend is broken, double-check the flow of your data from the SQL select -> storing the data in a python variable -> sending the data out
Also remember to Hard-Reload.
Based on our exchange in comments, it looks like the issue is with the date format being passed in your template.
Changing:
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date}}">
To:
<label for="date">Date</label>
<input type="datetime-local" name="date" value="{{course.date.isoformat()}}">
Should correct the problem for you.

Trigger python code at server side from client in Angular4

I am new to Angular, I am building a simple application which should do.
Accept couple of parameters from web page(client side)
Upon form submit, it should trigger a python code at server side
Get the output file(jpg image) generated by python and display below the submit form.
As part of this, I have just coded the app.component.html and a blank python refresh module in app.component.ts, but I'm unable to
A. Code to call python code at server side and retrieve the output
Also, upon searching across many places, I got answers to get data from web api call but not executing a python at server side and retrieving data.
Any reference or a code to this will be really very helpful !
My app.component.html looks like
<form (submit)="pytrigger(parm1.value,parm2.value)">
<div>
<label for="parm1">Parm1:</label>
<input type="text" #parm1>
</div>
<div>
<label for="parm2">Parm2:</label>
<input type="text" #parm2>
</div>
<div >
<input type="submit" class="button">
</div>
</form>
My app.component.ts has function(which needs to be extended)
pytrigger(parm1,parm2){
console.log('entered pytrigger');
}

Web2py: How to get items in FieldStorage?

I have a form that accepts image uploads:
<form name="upload" enctype="multipart/form-data" method="post" class="form-horizontal">
<div class="control-group">
<div class="span2">
<label for="image" class="control-label">Upload image:</label>
</div>
<div class="span10">
<input id="image" name="image" type="file" class="span7" accept="image/*"/>
</div>
</div>
<div class="form-group">
<div class="span2"></div>
<div class="span10">
<button class="btn btn-medium btn-primary" type="submit">Submit</button>
</div>
</div>
</form>
When I request.vars['image'], the following is returned:
FieldStorage('image', 'a.png', '\x89PNG\r\n\x1a\n\x00...')
How do I access these items? If I attempt to work with it as I would a dict, I receive an error that the object is not indexable. I've never worked with FieldStorage before, so I'm not exactly sure what I need to do to access this data.
If anyone else is interested, this worked:
request.vars['image'].filename
request.vars['image'].value
For the file name and binary data, respectively. Just needed a quick summary of the available attributes: http://python.about.com/od/cgiformswithpython/ss/pycgitut1_3.htm
This is extremely helpful if you are trying to check some aspects of a file before trying to process a form. I wanted to get the sha256 hash of an uploaded file and make sure it hadn't been uploaded before. The upload is in a field Field('file', 'upload').
Originally, I used the following, but this consumes the data in request.vars.file so that, after successful processing, the file written to disk is empty.
file_contents = request.vars.file.read()
form.vars.file_hash = hashlib.sha256(file_contents).hexdigest()
form.vars.file_length = len(file_contents)
However, in the updated code below datasci's answer allows you to access the data without consuming it from request.vars.file. Might be obvious, but it took a long time for me to figure out what was going on!
# Is there a file - the value will be None when the page first loads and
# can be 'str' if submit is pressed without a file selected.
if request.vars.file != None and not isinstance(request.vars.file, str):
form.vars.file_name = request.vars.file.filename
form.vars.file_hash = hashlib.sha256(request.vars.file.value).hexdigest()
form.vars.file_size= len(request.vars.file.value)
if form.process(onvalidation=validate_dataset_upload).accepted:
# notify upload has worked
response.flash = ('Upload successful. A validation check will be run and '
'you will get an email with the results when it finishes.')
All of this means that the validate_dataset_upload function can now check form.vars.file_hash does not already exist in the underlying table.

Python request input's id from a form

I use google app engine and python. I want to retrieve the id of an input and not the value. If I use self.request.get("thename") I get the value of the input.
Here is the html
<form method="post">
<input value=" " type="submit" name="thename" id="thenumberIneed"/>
</form>
I cannot put my data on the value tag because I have an image as a background on the input and if I enter there anything, the data shows infront of the image. So, I keep value empty.
If you don't want the value to show, change it to:
<input type="hidden" ... />
But I suspect there are other problems you should be solving, like why does your image get in the way of showing values in the page, and what kind of data you want to retrieve.
You shouldn't be using the id for this type of logic.
You would have better luck using a seperate hidden input field, for example.
<input type='hidden' name='myval' value='thenumberyouneed' />
And then you can just do your search for myval and get your answer.

Sending data to server flask html

I am trying to create a simple checkbox that sends the data to server here is my html code.
<form action="." method="POST">
<div class="checksheet">
<input id="XML Parser" class="checkbox" type="checkbox"/>XML Parser
<input id="Feed Parser" class="checkbox" type="checkbox"/>Feed Parser
<input id="Text Parser" class="checkbox" type="checkbox"/>Text Parser
<input id="Case Normalization" class="checkbox" type="checkbox"/>Case Normalization
<input id="Stemmer" class="checkbox" type="checkbox"/> Stemmer
</div>
<div class="submit"><input type="submit" value="Send" name="raw_text"></div>
</form>
What I am trying to do is very similar to the question asked here: Send Data from a textbox into Flask?
But except with the text box.. I have checkboxes.
But I get this error:
Not Found
The requested URL was not found on the server.
If you entered the URL manually please check your spelling and try again.
MY server side code (in flask) is:
#app.route('/raw_text.html')
def home ():
file = "sample.xml"
contents = open(file).read()
contents = contents.decode('utf-8')
return render_template('raw_text.html', contents=contents,file=file)
#app.route('/raw_text.html',methods=['POST'])
def get_data():
print "REQUEST ",request.form()
data = request.form['raw_text']
print data
return "Processed"
Any suggestions.
Thanks
A few things:
Your checkbox elements need a name attribute, this is what is used when the data is sent to the back end. Each checkbox that is related to each other needs to have the same name.
Your action attribute needs to point to a URL. If you are posting it to the same page as the form, you can remove the attribute.
ID's cannot contain spaces.
To be accessible the check boxes need <label>s,

Categories