I have jquery send out a request to the api endpoint. Code below:
$.get("http://localhost:5000/api/update/"+ elm2, function(data){});
The endpoint is defined like this:
#app.route('/api/update/<id>', methods=['GET'])
def check_new_entries(id):
result = Trades.query.filter_by(id=id).first_or_404()
new_entries = Trades.query.filter(Trades.time_recorded > result.time_recorded).all()
The table being queried from is:
class Trades(db.Model):
id = db.Column(db.String,default=lambda: str(uuid4().hex), primary_key=True)
amount = db.Column(db.Integer, unique=False)
time_recorded = db.Column(db.DateTime, unique=False)
The problem:
Jquery is successfully sending the correct request, with the variable being of type string but when the first query is executed, it fails to return anything.
I have a similar endpoint in another application and it works fine.. why is this one an exception? What could be missing? I am sure that the record that I am querying is in the database so it should return it.
#app.route('/api/update/<id>', methods=['GET',])
def check_new_entries(id):
result = Trades.query.filter_by(id=id).first()
if result:
new_entries = Trades.query.filter(Trades.time_recorded >= result.time_recorded).all()
The problem is that some unexpected space was before the rest of the string. The error originated from jquery and jinja where jquery was getting the html contents of an element and sending them as the variable. The jinja syntax was something like:
<p> {{ variable }}</p>
When jquery fetches the html contents, it takes the space btwn the paragraph opening tag and the opening curly braces as well. The variable transmitted had a leading space which caused the error.
Related
I am trying to get a list sets of information :
Name:
Date:
Status:
It will be displayed in the HTML page so e.g
Name: John
Date: 11 January 2018
Status: Pending
Name: Alex
Date: 10 January 2018
Status: Pending
There will be a button for each of the above data named 'Confirm'.
How do I go about so that when I click the 'Confirm' button on one of the data above, it will only process and make use of that data?
e.g if I click the button on Name : Alex, it will only get the info of Alex.
How do I go about doing this in Python Flask?
I can do a POST but how do I capture that the data being sent is from that specific set?
Please give me some suggestions.
Thank you
Use Identities
Information that is stored on a computer has to be identified through a means somehow. This can be done with an index such as an incrementing index, a GUID, a SHA hash or some other kind of random generator that can create an random id. The random id can then be given a 'purpose' to represent that data.
I'm not sure how you have implemented this in Flask. Whether this is done with
some kind of SQL driver, a JSON/XML object, or whether this is written in plain text. However, the place to start is how you're storing your data so that you can figure out the best way to use it.
Use of Payloads
Payloads are basically where you can give or send all data rather than metadata or identities. This could allow you to identify or change the information before it is stored or sent. However this is normally done to upload/download and change data with an API rather than used to identify data as it would take longer to process.
Solution
The best one out of the two would be to use identification. The implementation could be as simple as visiting a link that contains an ID that (REST) API's would typically use (e.g. /statuses/1 or /statuses/321THISISUNIQUE).
You could create a form that contains that id as part of a value such as:
<form action='/statuses' method='POST'>
<input type='hidden' name='id' value='321THISISUNIQUE'/>
<input class='confirm' type='submit' value='confirm'/>
</form>
Example to get a status using an id
#app.route('/statuses/<id>')
def getStatus(id):
return 'Status for %s' % id
Example to use POST with an id (Refer to Flask - the request object)
#app.route('/statuses', methods=['POST'])
def changeStatus():
# Technically this should be a PUT request as part of REST
id = request.args.id
return 'Change status with id %s' % id
Using flask-sqlalchemy would make it easy for you. Then you can retreive all data from database, and when user click the button you will call a view function which will take Name or you can change to the person id.
db = SQLAlchemy(app)
class Person(db.Model):
Name = db.Column(db.String)
Date = db.Column(db.DateTime)
Status = db.Column(db.String)
#app.route('/')
def index():
persons = Person.query.all()
return render_template('index.html', persons=persons)
#app.route('person-info/<name>')
def person_info(name):
person = Person.query.filter_by(Name=name).first()
return render_template('person.html', person=person)
#index.html
{% for person in persons %}
...
<a href="{{ url_for('person_info', name=person.Name)}}">
{% endfor %}
#person.html
{{person.Name}}{{person.Status}}{{person.Date}}
Sorry if this is a noob question I am still learning. I have passed a variable from python code to a jinja2 HTML template to set up a URL, like this:
Delete
When this link is pressed it should run a query that deletes the entity with that ID. But when the link is pressed it goes to /delete/1827424298 for example, which results in a 404 error as the request handler doesn't exist.
I need to pass that ID back into my python code so it can run a method to delete the entity with that same ID. How do I go about doing this? Using webapp2 if that is important.
class DeleteRequestHandler(webapp2.RequestHandler):
def get():
template = template_env.get_template('myrequests.html')
context = {
'results': results.key.id()
}
self.response.out.write(template.render(context))
EDIT: I've added my delete handler - it is incomplete as I have yet to add the query to delete the entity. My thinking behind it so far is I can grab the results.key.id() from the jinja2 template and put it into results but I am not sure if this would work.
So I think what you're confused about is how to set up a route handler with a dynamic part to the URL. It's a shame that this is completely skipped over in the webapp2 tutorial, as it's a fundamental part of writing any web application. However, it is covered well in the guide to routing, which you should read.
At its simplest, it's just a matter of putting a regex in the route:
app = webapp2.WSGIApplication([
...
(r'/delete/(\d+)', MyDeleteHandler),
])
which will now route any URL of the form /delete/<number>/ to your deletion handler.
The ID that you pass in the URL will be the first positional argument to the handler method:
class MyDeleteHandler:
def get(self, item_id):
key = ndb.Key(MyModel, item_id) # or whatever
I am currently using Python Flask and Jinja2. I have a table with some message. I want to basically have a button on the menu with the number of messages that a user has.
I've used this to make my sidebar global so it can appear on multiple pages:
app.jinja_env.globals.update(...)
This is the code I've used to get the number of messages:
def message_notification():
c.execute("SELECT count(*) FROM messages WHERE read = 0 AND receiver = ?",(session['username'],))
msgnotifcation = c.fetchone()
return msgnotifcation[0]
However I am getting this error:
RuntimeError: Working outside of request context.
Is there any other way to do this as I figured out that the problem is to do with the session['username'] bit.
You need to move this code so that it executes before the template starts to render, i.e. it will be inside the request context.
Flask provides the context_processor decorator to achieve this. http://flask.pocoo.org/docs/0.12/templating/#context-processors The values returned will be available in all your templates as though they had been returned as any other context item from a view.
#app.context_processor
def message_count():
value = ...your sql...
return dict(message_count=value)
Then in your views you can use:
{{ message_count }}
This question already has answers here:
Passing HTML to template using Flask/Jinja2
(7 answers)
Closed 9 months ago.
I'm building a web page to show articles.
In my database, I have to attributes, one of which is used to put Markdown code and the other to save HTML code converted from the Markdown code. I want to get the HTML and add it to my base HTML.
I use Flask framework and SQLAlchemy and the data is saved in sqlite database.
My model:
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String)
body = db.Column(db.String)
timestamp = db.Column(db.String)
tag = db.Column(db.String)
info = db.Column(db.String)
body_markdown = db.Column(db.String)
and my view function:
def post(post_id):
post = db.session.query(Post).filter(Post.id == post_id).first()
return render_template('post.html',
post = post,)
Firstly, I tried:
<div class="post-body">
{{post.body}}
</div>
It shows the whole string with HTML tag.
post.body.decode("utf-8") and post.body.decode("ascii") didn't work, either.
When I debug the program, I found that the database returns u'string'.
How can I get pure HTML code and apply it in my base HTML file?
By default Jinja2 (the template engine for Flask) assumes input inside of {{ }} is unsafe and will not allow js or html inside them. You can solve this by using the safe filter inside your template. This will tell Jinja2 that the content is safe to render as is, and not to escape the html/javascript.
{{ post.body | safe }}
I am relatively new to Flask and I could not figure out what is the problem with my function nor I could find that someone had had the same problem. It is even difficult to explain.
Template url_for link:
<a href="{{ url_for('view_post', pc=post.product_category_by.product_cat_name, post_id=post.id, ui=post.author_id) }}">
Flask view function: (Flask SQLAlchemy. PostgreSQL)
#app.route('/viewref/<pc>/<int:post_id><int:ui>')
def view_post(pc, post_id, ui):
post = db.session.query(Post).filter_by(id=post_id).first()
db.session.commit()
gc.collect()
return render_template('view_post.html', post=post)
Example:
Lets take a post with ID 26 and two users (or authors of post) with IDs 9 and 10. When I pass a user with ID 9, I get redirected to the correct view with the end url: /viewref/productCat/269 (26 is post id and 9 is user id). Great, it works and I see a post!
The problem:
But when a user with ID 10 or higher (12, 299 etc.) get passed in the url_for, the query of view_post function pulls None from the database, subsequently my view_post.html template throws an Error
(UndefinedError: 'None' has no attribute 'product_category_by')
What is the connection?
The key of the view_post function is only to fetch a post by a given post_id. Why does it get None in the cases where user ID > 9, if my function takes only post_id for the query and other variables are used for the url construction only?
P.S. It all works fine if I exclude ui from the url_for and view_post function.
I'm not sure how you're expecting the URL router to tell where post_id ends and ui starts. You should use an actual separator:
#app.route('/viewref/<pc>/<int:post_id>/<int:ui>')
I think you should change your URL scheme. What if the user id is 12 and the post_id is 34? In your URL it would be concatenated to 1234. How can we tell this apart from post_id: 1, user_id: 234 versus post_id: 123, user_id: 4?