I am trying to print a trial balance through a web app.
The app currently prints the description but not in a line by line format, I have had a look at the .filter function but I don't know how that would translate to MSSQL queries.
If anyone one has any examples for me , that would be a great help.
Views.py :
def home(request):
desc = "SELECT Description FROM [Kyle].[dbo].[_btblCbStatement] WHERE Account <> ''"
cursor = cnxn.cursor();
cursor.execute(desc);
description = cursor.fetchall()
return render(request , 'main/home.html' , {"description": description})
Home.html:
{% extends "main/base.html"%}
{% block content%}
<h1>HOME</h1>
{% for description in description %}
<div class="row mb-3">
<div class="col">
<p>{{ description }}</p>
</div>
{% endfor %}
</div>
{% endblock %}
Output:
fetchall returns a list of tuples (in this case a list of one-tuples since there is a single column in the SELECT clause).
The easiest way to fix this will be to convert description to a list of strings beforehand:
description = [tup[0] for tup in cursor.fetchall()]
BTW, I think {% endfor %} is on the wrong line. It should go after the closing </div> tag.
Related
The idea is to have a page where you rate a photo of a dog, and once rating is submitted, the next photo shows up. Not unlike hot or not, for dogs... I thought this part would be simple and maybe I just need to take a break and an answer will come to me.
So far i have implemented registering, logging in, a means to upload the photos, a database to store all this information(sqlite3) and other little tid bits.
The main page is "arena.html" and ive just thrown in the list of all DB photos at it in a for loop. the outcome is that all the photos show up stacked on top of each other. I would like some help to figure out a simple way to show just one photo, then after its rated, the next photo takes its place.
arena.html
{% extends "layout.html" %}
{% block title %}
Arena
{% endblock %}
{% block scripts %}
{% endblock %}
{% block head %}
{% endblock %}
{% block main %}
{% for photo in photos %}
<div><img src={{photo|replace("'", "")|replace(",", "")|replace("(", "")|replace(")", "")}} id="arena_pic" />
</div>
{% endfor %}
{% endblock %}
app.py
#app.route ("/arena", methods=["GET", "POST"])
#login_required
def arena():
if request.method == "GET":
try:
conn = sqlite3.connect('dogs.db')
cursor = conn.cursor()
print("DB Init")
sql = ("SELECT photo_address FROM photos;")
cursor.execute(sql)
rows = cursor.fetchall()
print(rows)
except sqlite3.Error as er:
conn.rollback()
print('SQLite error: %s' % (' '.join(er.args)))
print("Exception class is: ", er.__class__)
print('SQLite traceback: ')
exc_type, exc_value, exc_tb = sys.exc_info()
print(traceback.format_exception(exc_type, exc_value, exc_tb))
flash("Oops, There was an gathering error!")
return render_template("arena.html")
else:
conn.close()
return render_template("arena.html", photos = rows)
I thought about rendering a new template each time but i dont know how to do that dynamically.
There are some clues for you...
You may check the article first
Flask SQLalchemy - many to many - show photo with all tags (or blog with all posts etc)
And try the "jinjagrid" to batch processing as your html template. To be more clean and controllable.
<section class="section">
<div class="container">
{% for row in elements|batch(5) %} ## batch times by your demand
<div class="columns">
{% for column in row %}
<div class="column">
<p class="notification is-danger">{{ column }}</p>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</section>
Here comes the reference:
https://youtu.be/lhpNRDGzInw
https://github.com/PrettyPrinted/youtube_video_code/tree/master/2020/06/29/How%20to%20Create%20a%20Grid%20in%20a%20Jinja2%20Template
I have codes for a simple message blog that very body can leave message. One of the problems is that the message display from sqlite db is without format, e.g. without paragraph. How can I impove it (or add markdown enable)? I appreciate your help. Thank you.
main app py
#app.route('/')
def index():
conn = db_conn()
posts = conn.execute('SELECT * FROM table_posts').fetchall()
conn.close()
return render_template('index.html', posts=posts)
#app.route('/create_new_post', methods=('GET', 'POST'))
def create_new_post():
if request.method == 'POST':
content = request.form['content']
conn = db_conn()
conn.execute('INSERT INTO table_posts (content) VALUES (?)', (content,))
conn.commit()
conn.close()
return redirect(url_for('index'))
else:
return render_template('create_new_post.html')
index.html
{% extends 'base.html' %}
{% block title %}
Simple Message Board
{% endblock %}
{% block content %}
{% for post in posts %}
<br>
<div class="card">
<div class="card-body">
<p class="card-text"> {{ post['content'] }} </p>
<span class="badge badge-secondary">{{ post['time_stamp'] }}</span>
</div>
</div>
{% endfor %}
{% endblock %}
The outcome i want is as follows:
Text of 1st line
Text of 2nd line
Text of 3rd line
But the actual content displayed is as follows:
Text of 1st line Text of 2nd line Text of 3rd line
I think you are trying to render the body as html not as text.
jinja autoescapes the text , you can stop autoescaping,
For that you can use the safe filter of jinja.
{{ post['content']|safe }}
You can also see the docs
I am doing a flask tutorial here, and in the end, keep developing section it says to implement a search box that filters the index page by name,after trail and error I came up to displaying the search page, but still I don't get the results back of my search.
Here is my Search HTML:
<form method="GET" action="{{ url_for('blog.search') }}">
<input type="text" placeholder="Search by" name="q" value="{{ request.args.get('q', '') }}">
<button type="submit">Go</button>
</form>
Here is my route
from flask import request
#bp.route('/search', methods=['GET','POST'])
def search():
db = get_db()
query = request.args.get('q')
posts = db.execute(
"SELECT title, body FROM post WHERE body LIKE ? ",
('%'+ query +'%',)).fetchall()
return render_template('blog/search.html', posts=posts )
Here is my search 'blog/search.html' template
<ul>
{% for post in posts %}
<li> {{ post['title'] }} </li>
<li> {{ post['body'] }} </li>
{% endfor %}
</ul>
Is there a problem in my route or the sql query?
or is there a better way to implement a search, in flask without any extensions, thanks.
I have figured it out.
it was a mistake on my end on the 'blog/search.html' template below is my working code
my route for search:
#bp.route('/search', methods=['GET','POST'])
def search():
db = get_db()
query = request.args.get('q')
posts = db.execute(
"select id, title from post where title LIKE ? ",
('%'+ query+'%',)
).fetchall()
return render_template('blog/search.html', posts=posts)
note: this route only checks for the title of my db
my new 'blog/search.html' template:
{% if posts %}
<ul>
{% for post in posts %}
<li>{{ post[1] }}</li>
{% endfor %}
</ul>
{% else %}
<p>no entries</p>
{% endif %}
note: '{{ url_for... }}' is a link used to look into details of the search
Hope this gets helpful to someone trying to implement a search in this tutorial.
cheers :)
I'm building a Netflix like website for my Devops course. I made a Python list of dictionaries (Mockfilms) to define my films, and want to populate a database (Ratings) with reviews in preparation for sending data in the format :filmid: :userid: :rating: to a recommendation engine.
My index page is a list of film images with a link to a review form under each one. I want each review form to appear on a different url (/review/ID where ID is saved in mockfilms as oid). In order to do this I want to access mockfilms.oid, then pass it to the view function to make the url for the form. Once the form is complete I then want to add this ID to the Ratings database. Here is what I have so far:
Index:
{% extends "base.html" %}
{% block content %}
<h1>Hello, {{ current_user.username }}! Welcome to our extensive video library:</h1>
{% for film in mockfilms %}
{% set ID = film.oid %}
<div>
<a href = {{ film.video }}>
<img src = {{ film.image }} alt = "doh" style = "width:200px;height:200px;border:0;">
</a>
</div>
<div>
">Leave a review here!
{% endfor %}
{% endblock %}
Route:
#app.route('/review/<ID>', methods = ['GET', 'POST'])
#login_required
def review(ID):
form = ReviewForm()
if form.validate_on_submit():
review = Ratings(User_id = current_user.id, Score_given = form.score.data, Film_id = ID)
db.session.add(review)
db.session.commit()
flash('Thanks for your review')
return redirect(url_for('index'))
return render_template('review.html', title='Review Page', form=form)
The following error is what I get when I run it:
File "/home/jc/Desktop/Lokal/DevopsAssig/microblog/Kilfinnan/lib/python3.5/site-packages/werkzeug/routing.py", line 1768, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'review'. Did you forget to specify values ['ID']?
From this I assume that the issue is with the ID variable within this template. My searchings and learnings led me to believe that {% set %} in the index template would let me declare the ID variable and then use it in the dynamic.
Try this:
{% block content %}
<h1>
Hello, {{ current_user.username }}!
Welcome to our extensive video library:
</h1>
{% for film in mockfilms %}
<div>
<a href="{{ film.video }}">
<img src="{{ film.image }}" alt="doh" style="width:200px;height:200px;border:0;" />
</a>
</div>
<div>
<a href="{{ url_for('review', ID=film.oid) }}">
Leave a review here!
</a>
</div>
{% endfor %}
{% endblock %}
Ultimately your solution was quite close, but it is not necessary to use the Jinja set command when you need to pass the variable into url_for() function using the keyword for the parameter. You could still do it using {% set ID = film.oid %} but it would be a bit superfluous.
Try to provide key=value arguments into your url_for function.
Something like this
">Leave a review here!
Also Flask have a great documentation, Flask docs
So I have been tinkering for a while with jinja2 and google app engine. I am just writing a small toy app on my spare time; the app has a webpage that displays the ten most recent posts along with its comments.
All of the blog posts print fine onto the page by using the following within the google data store, after the Post object is created and stored in the database of course. I use the following query to get the ten posts to be displayed.
recent_blog_posts = ndb.gql("SELECT * FROM Posts ORDER BY created_at
DESC LIMIT 10;")
The blogpage.html code below:
{% block content %}
{% for post in recent_blog_posts %}
<div>
<h3>{{post.title}}</h3>
<pre>
<p style="max-width: 100%;">{{post.post}}</p>
</pre>
<p>By: {{post.by_user}}</p>
<!-- this is where I want the comments to go (explained below)-->
<h4>Leave A Comment:</h4>
<form method="post">
<textarea name="comment" value="{{comment}}" style="height: 50px; width: 200px;"></textarea>
<input type="hidden" name="post_key" value="{{post.key}}">
<br>
<button>Comment</button>
</form>
</div>
<hr>
{% endfor %}
{% endblock %}
I just iterated over the ten objects in the query above to print all of the blog posts. However, this is where it gets tricky for me.
I create a new Comment instance with the following:
new_comment = Comments(comment = comment,
user = user.name, parent = ndb.Key(Posts, int(post_key)))
new_comment_key = new_comment.put()
When I print the new Comment instances onto the screen, just to see, they all print out correctly with the right parent and their own ids.
Now this is where I am not sure on how to take each Comment instance and print it with its corresponding post. How can I accomplish that?
I have searched everywhere, and even added this to the html template above. (In place of the comment from the html template above)
{% for comment in comment_query %}
{{comment.comment}}
{% endfor %}
With the query below:
recent_comments = Comments.query(ancestor=ndb.Key(Posts, int(new_string))).order(-Comments.created_at).fetch(limit=3)
This obviously just prints out all of the Comments instances for all of the Posts instances on the page.
Thanks In Advance
Just form the output list in the backend itself.
recent_blog_posts = ndb.gql("SELECT * FROM Posts ORDER BY created_at
DESC LIMIT 10;")
posts_with_comments = []
for post in recent_blog_posts:
recent_comments = Comments.query(ancestor=post.key).order(-Comments.created_at).fetch(limit=3)
posts_with_comments.append([post, recent_commmnets])
Then iterate over posts_with_comments in the template like
{% for post,comments in posts_with_comments %}
<div>
<h3>{{post.title}}</h3>
<pre>
<p style="max-width: 100%;">{{post.post}}</p>
</pre>
<p>By: {{post.by_user}}</p>
<p> Comments: </p>
{% for commnet in comments %}
{{ comment }}
{% endfor %}
{% endfor %}