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
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 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.
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
this is my code:
#app.route('/user_article/<username>/<title>')
def user_article(username,title):
db = get_db()
cu = db.cursor()
cu.execute("select *from article where username='%s',title='%s'" %(username,title))
data = cu.fetchone()
article = data[2]
return render_template('user_article.html',article=article)
and my html code:
{% for data in user_article %}
<p>
<a href='{{ url_for("user_article",username={{data[0]}},title={{data[1]}}) }}'>{{data[1]}}</a>
</p>
{% endfor %}
when i run the code i got an error:
jinja2.exceptions.TemplateSyntaxError: expected token ':', got '}'
what should i do to get the parameters?thanks
This line should be without double brackets
url_for("user_article",username=data[0],title=data[1])
html code
{% for data in user_article %}
<p>
<a href='{{ url_for("user_article",username=data[0],title=data[1]) }}'>{{data[1]}}</a>
</p>
{% endfor %}
I want to make some kind of search engine for student's information by entering their first name in html input field, but I have some troubles with my code. I am using Flask with Python though.
Here is my project.py code:
#app.route('/search', methods=['GET', 'POST'])
def search():
if request.method == "POST":
db = MySQLdb.connect(user="root", passwd="", db="cs324", host="127.0.0.1")
c=db.cursor()
c.executemany('''select * from student where name = %s''', request.form['search'])
for r in c.fetchall():
print r[0],r[1],r[2]
return redirect(url_for('search'))
return render_template('search.html')
Here is my search.html code:
{% extends "hello.html" %}
{% block content %}
<div class="search">
<form action="" method=post>
<input type=text name=search value="{{ request.form.search}}"></br>
<div class="actions"><input type=submit value="Search"></div>
</form>
</div>
{% for message in get_flashed_messages() %}
<div class=flash>
{{ message }}
</div>
{% endfor %}
{% endblock %}
When I hit Search button nothing happens, I checked database it has some data in it so it is not empty, I can't find where am I making a mistake, please help?
Make sure, action point to proper url
I think you render the form with wrong action for submitting the form.
Your version is using action="" and I guess, it shall be action="/search"
So your template shall be changed like:
{% extends "hello.html" %}
{% block content %}
<div class="search">
<form action="/search" method=post>
<input type=text name=search value="{{ request.form.search}}"></br>
<div class="actions"><input type=submit value="Search"></div>
</form>
</div>
{% for message in get_flashed_messages() %}
<div class=flash>
{{ message }}
</div>
{% endfor %}
{% endblock %}
Do not redirect out of your result
Your existing code is processing POST, but within first loop it ends up returning with redirect
#app.route('/search', methods=['GET', 'POST'])
def search():
if request.method == "POST":
db = MySQLdb.connect(user="root", passwd="", db="cs324", host="127.0.0.1")
c=db.cursor()
c.executemany('''select * from student where name = %s''', request.form['search'])
for r in c.fetchall():
print r[0],r[1],r[2]
return redirect(url_for('search')) # <- Here you jump away from whatever result you create
return render_template('search.html')
Do render your template for final report
Your code does not show in POST branch any attempt to render what you have found in the database.
Instead of print r[0], r[1]... you shall call render_template()
Something like this
#app.route('/search', methods=['GET', 'POST'])
def search():
if request.method == "POST":
db = MySQLdb.connect(user="root", passwd="", db="cs324", host="127.0.0.1")
c=db.cursor()
c.executemany('''select * from student where name = %s''', request.form['search'])
return render_template("results.html", records=c.fetchall())
return render_template('search.html')