post now complete visible, files added to db
This commit is contained in:
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,4 +1,5 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources.local.xml
|
||||
/dataSources.local.xml
|
||||
/dataSources/
|
||||
14
.idea/dataSources.xml
generated
14
.idea/dataSources.xml
generated
@@ -7,5 +7,19 @@
|
||||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="calender" uuid="17a463e8-6100-487f-bdd0-6ebd223d5bf6">
|
||||
<driver-ref>sqlite.xerial</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
|
||||
<jdbc-url>jdbc:sqlite:C:\Users\jbuer\PycharmProjects\dankventskalender3.0\instance\calender.sqlite</jdbc-url>
|
||||
<libraries>
|
||||
<library>
|
||||
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.25.1/license.txt</url>
|
||||
</library>
|
||||
<library>
|
||||
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.25.1/sqlite-jdbc-3.25.1.jar</url>
|
||||
</library>
|
||||
</libraries>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
@@ -11,15 +11,17 @@ from calender.db import get_db
|
||||
bp = Blueprint('calender', __name__)
|
||||
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
||||
|
||||
#Todo admin interface for managing submit, comments, submission date
|
||||
|
||||
@bp.route('/')
|
||||
def index():
|
||||
db = get_db()
|
||||
posts = db.execute(
|
||||
'SELECT p.id, title, body, created, author_id, username'
|
||||
'SELECT p.id, title, body, created, author_id, username, nickname, file'
|
||||
' FROM post p JOIN user u ON p.author_id = u.id'
|
||||
' ORDER BY created DESC'
|
||||
).fetchall()
|
||||
# noinspection PyUnresolvedReferences
|
||||
return render_template('calender/index.html', posts=posts)
|
||||
|
||||
|
||||
@@ -28,7 +30,19 @@ def index():
|
||||
def create():
|
||||
if request.method == 'POST':
|
||||
title = request.form['title']
|
||||
nickname = request.form['nickname']
|
||||
body = request.form['body']
|
||||
# check if the post request has the file part
|
||||
if 'file' not in request.files:
|
||||
flash('No file part')
|
||||
return redirect(request.url)
|
||||
file = request.files['file']
|
||||
# if user does not select file, browser also
|
||||
# submit an empty part without filename
|
||||
if file.filename == '':
|
||||
flash('No selected file')
|
||||
return redirect(request.url)
|
||||
|
||||
error = None
|
||||
|
||||
if not title:
|
||||
@@ -37,28 +51,18 @@ def create():
|
||||
if error is not None:
|
||||
flash(error)
|
||||
else:
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'INSERT INTO post (title, body, author_id)'
|
||||
' VALUES (?, ?, ?)',
|
||||
(title, body, g.user['id'])
|
||||
)
|
||||
db.commit()
|
||||
# check if the post request has the file part
|
||||
if 'file' not in request.files:
|
||||
flash('No file part')
|
||||
return redirect(request.url)
|
||||
file = request.files['file']
|
||||
# if user does not select file, browser also
|
||||
# submit an empty part without filename
|
||||
if file.filename == '':
|
||||
flash('No selected file')
|
||||
return redirect(request.url)
|
||||
if file and allowed_file(file.filename):
|
||||
filename = secure_filename(file.filename)
|
||||
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
|
||||
return redirect(url_for('calender.uploaded_file',
|
||||
filename=filename))
|
||||
db = get_db()
|
||||
db.execute(
|
||||
'INSERT INTO post (title, body, author_id, nickname, file)'
|
||||
' VALUES (?, ?, ?, ?, ?)',
|
||||
(title, body, g.user['id'], nickname, url_for('calender.uploaded_file',
|
||||
filename=filename))
|
||||
)
|
||||
db.commit()
|
||||
# return redirect(url_for('calender.uploaded_file',filename=filename))
|
||||
return redirect(url_for('calender.index'))
|
||||
|
||||
return render_template('calender/create.html')
|
||||
@@ -66,7 +70,7 @@ def create():
|
||||
|
||||
def get_post(id, check_author=True):
|
||||
post = get_db().execute(
|
||||
'SELECT p.id, title, body, created, author_id, username'
|
||||
'SELECT p.id, title, body, created, author_id, username, nickname, file'
|
||||
' FROM post p JOIN user u ON p.author_id = u.id'
|
||||
' WHERE p.id = ?',
|
||||
(id,)
|
||||
|
||||
@@ -22,6 +22,7 @@ def close_db(e=None):
|
||||
if db is not None:
|
||||
db.close()
|
||||
|
||||
|
||||
def init_db():
|
||||
db = get_db()
|
||||
|
||||
@@ -36,6 +37,7 @@ def init_db_command():
|
||||
init_db()
|
||||
click.echo('Initialized the database.')
|
||||
|
||||
|
||||
def init_app(app):
|
||||
app.teardown_appcontext(close_db)
|
||||
app.cli.add_command(init_db_command)
|
||||
|
||||
BIN
calender/media/memes/bbaum.png
Normal file
BIN
calender/media/memes/bbaum.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 224 KiB |
@@ -12,6 +12,8 @@ CREATE TABLE post (
|
||||
author_id INTEGER NOT NULL,
|
||||
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
title TEXT NOT NULL,
|
||||
nickname TEXT NOT NULL,
|
||||
body TEXT NOT NULL,
|
||||
file TEXT NOT NULL,
|
||||
FOREIGN KEY (author_id) REFERENCES user (id)
|
||||
);
|
||||
);
|
||||
|
||||
@@ -1,82 +1,80 @@
|
||||
|
||||
body, h1, h2, h3, h4, h5 {
|
||||
font-family: "Raleway", sans-serif;
|
||||
color: black;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.w3-content .w3-container-display img {
|
||||
max-width: 100%;
|
||||
}
|
||||
.w3-content .w3-container-display img{
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.w3-content {
|
||||
max-width: 800px;
|
||||
max-width: 800px;
|
||||
}
|
||||
footer{
|
||||
padding-left: 2px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
video {
|
||||
width:100%;
|
||||
max-width:500px;
|
||||
height:auto;
|
||||
}
|
||||
iframe{
|
||||
width:100%;
|
||||
max-width:500px;
|
||||
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
video {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
height: auto;
|
||||
}
|
||||
textarea{
|
||||
resize: none;
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.bgimg-1{
|
||||
}
|
||||
|
||||
.bgimg-1 {
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-image: url("horsehead.jpg");
|
||||
background-image: url("horsehead.jpg");
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.button_flash {
|
||||
background-color: #004A7F;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-family: Arial;
|
||||
font-size: 20px;
|
||||
padding: 5px 10px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
background-color: #004A7F;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-family: Arial;
|
||||
font-size: 20px;
|
||||
padding: 5px 10px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button_flash {
|
||||
-webkit-animation: glowing_red 1500ms infinite;
|
||||
-moz-animation: glowing_red 1500ms infinite;
|
||||
-o-animation: glowing_red 1500ms infinite;
|
||||
animation: glowing_red 1500ms infinite;
|
||||
-webkit-animation: glowing_red 1500ms infinite;
|
||||
-moz-animation: glowing_red 1500ms infinite;
|
||||
-o-animation: glowing_red 1500ms infinite;
|
||||
animation: glowing_red 1500ms infinite;
|
||||
}
|
||||
|
||||
.button_flash_animation {
|
||||
-webkit-animation: glowing_green 2000ms infinite;
|
||||
-moz-animation: glowing_green 2000ms infinite;
|
||||
-o-animation: glowing_green 2000ms infinite;
|
||||
animation: glowing_green 2000ms infinite;
|
||||
-webkit-animation: glowing_green 2000ms infinite;
|
||||
-moz-animation: glowing_green 2000ms infinite;
|
||||
-o-animation: glowing_green 2000ms infinite;
|
||||
animation: glowing_green 2000ms infinite;
|
||||
}
|
||||
|
||||
.rotated-image {
|
||||
animation: spin_img 1s infinite linear
|
||||
animation: spin_img 1s infinite linear
|
||||
}
|
||||
|
||||
.dropbtn {
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
@@ -99,7 +97,7 @@ textarea{
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
overflow: auto;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -110,101 +108,140 @@ textarea{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown a:hover {background-color: #f1f1f1}
|
||||
|
||||
.show {display:block;}
|
||||
.dropdown a:hover {
|
||||
background-color: #f1f1f1
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@-webkit-keyframes glowing_red {
|
||||
0% { background-color: #B20000; -webkit-box-shadow: 0 0 3px #B20000; }
|
||||
50% { background-color: #FF0000; -webkit-box-shadow: 0 0 40px #FF0000; }
|
||||
100% { background-color: #B20000; -webkit-box-shadow: 0 0 3px #B20000; }
|
||||
0% {
|
||||
background-color: #B20000;
|
||||
-webkit-box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
50% {
|
||||
background-color: #FF0000;
|
||||
-webkit-box-shadow: 0 0 40px #FF0000;
|
||||
}
|
||||
100% {
|
||||
background-color: #B20000;
|
||||
-webkit-box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes glowing_red {
|
||||
0% { background-color: #B20000; -moz-box-shadow: 0 0 3px #B20000; }
|
||||
50% { background-color: #FF0000; -moz-box-shadow: 0 0 40px #FF0000; }
|
||||
100% { background-color: #B20000; -moz-box-shadow: 0 0 3px #B20000; }
|
||||
0% {
|
||||
background-color: #B20000;
|
||||
-moz-box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
50% {
|
||||
background-color: #FF0000;
|
||||
-moz-box-shadow: 0 0 40px #FF0000;
|
||||
}
|
||||
100% {
|
||||
background-color: #B20000;
|
||||
-moz-box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes glowing_red {
|
||||
0% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
|
||||
50% { background-color: #FF0000; box-shadow: 0 0 40px #FF0000; }
|
||||
100% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
|
||||
0% {
|
||||
background-color: #B20000;
|
||||
box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
50% {
|
||||
background-color: #FF0000;
|
||||
box-shadow: 0 0 40px #FF0000;
|
||||
}
|
||||
100% {
|
||||
background-color: #B20000;
|
||||
box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glowing_red {
|
||||
0% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
|
||||
50% { background-color: #FF0000; box-shadow: 0 0 40px #FF0000; }
|
||||
100% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
|
||||
0% {
|
||||
background-color: #B20000;
|
||||
box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
50% {
|
||||
background-color: #FF0000;
|
||||
box-shadow: 0 0 40px #FF0000;
|
||||
}
|
||||
100% {
|
||||
background-color: #B20000;
|
||||
box-shadow: 0 0 3px #B20000;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes glowing_green {
|
||||
0% { background-color: #3fff00; -webkit-box-shadow: 0 0 3px #3fff00; }
|
||||
50% { background-color: #0ad100; -webkit-box-shadow: 0 0 40px #0ad100; }
|
||||
100% { background-color: #3fff00; -webkit-box-shadow: 0 0 3px #3fff00; }
|
||||
0% {
|
||||
background-color: #3fff00;
|
||||
-webkit-box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
50% {
|
||||
background-color: #0ad100;
|
||||
-webkit-box-shadow: 0 0 40px #0ad100;
|
||||
}
|
||||
100% {
|
||||
background-color: #3fff00;
|
||||
-webkit-box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
}
|
||||
|
||||
@-moz-keyframes glowing_green {
|
||||
0% { background-color: #3fff00; -moz-box-shadow: 0 0 3px #3fff00; }
|
||||
50% { background-color: #0ad100; -moz-box-shadow: 0 0 40px #0ad100; }
|
||||
100% { background-color: #3fff00; -moz-box-shadow: 0 0 3px #3fff00; }
|
||||
0% {
|
||||
background-color: #3fff00;
|
||||
-moz-box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
50% {
|
||||
background-color: #0ad100;
|
||||
-moz-box-shadow: 0 0 40px #0ad100;
|
||||
}
|
||||
100% {
|
||||
background-color: #3fff00;
|
||||
-moz-box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes glowing_green {
|
||||
0% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
|
||||
50% { background-color: #0ad100; box-shadow: 0 0 40px #0ad100; }
|
||||
100% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
|
||||
0% {
|
||||
background-color: #3fff00;
|
||||
box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
50% {
|
||||
background-color: #0ad100;
|
||||
box-shadow: 0 0 40px #0ad100;
|
||||
}
|
||||
100% {
|
||||
background-color: #3fff00;
|
||||
box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glowing_green {
|
||||
0% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
|
||||
50% { background-color: #0ad100; box-shadow: 0 0 40px #0ad100; }
|
||||
100% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
|
||||
0% {
|
||||
background-color: #3fff00;
|
||||
box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
50% {
|
||||
background-color: #0ad100;
|
||||
box-shadow: 0 0 40px #0ad100;
|
||||
}
|
||||
100% {
|
||||
background-color: #3fff00;
|
||||
box-shadow: 0 0 3px #3fff00;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@keyframes spin_img {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.button3 {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.button3:hover {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.button span {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.button span:after {
|
||||
content: '\00bb';
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
top: 0;
|
||||
right: -20px;
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.button:hover span {
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.button:hover span:after {
|
||||
opacity: 1;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
html { font-family: sans-serif; background: #eee; padding: 1rem; }
|
||||
body { max-width: 960px; margin: 0 auto; background: white; }
|
||||
h1 { font-family: serif; color: #377ba8; margin: 1rem 0; }
|
||||
a { color: #377ba8; }
|
||||
hr { border: none; border-top: 1px solid lightgray; }
|
||||
nav { background: lightgray; display: flex; align-items: center; padding: 0 0.5rem; }
|
||||
nav h1 { flex: auto; margin: 0; }
|
||||
nav h1 a { text-decoration: none; padding: 0.25rem 0.5rem; }
|
||||
nav ul { display: flex; list-style: none; margin: 0; padding: 0; }
|
||||
nav ul li a, nav ul li span, header .action { display: block; padding: 0.5rem; }
|
||||
.content { padding: 0 1rem 1rem; }
|
||||
.content > header { border-bottom: 1px solid lightgray; display: flex; align-items: flex-end; }
|
||||
.content > header h1 { flex: auto; margin: 1rem 0 0.25rem 0; }
|
||||
.flash { margin: 1em 0; padding: 1em; background: #cae6f6; border: 1px solid #377ba8; }
|
||||
.post > header { display: flex; align-items: flex-end; font-size: 0.85em; }
|
||||
.post > header > div:first-of-type { flex: auto; }
|
||||
.post > header h1 { font-size: 1.5em; margin-bottom: 0; }
|
||||
.post .about { color: slategray; font-style: italic; }
|
||||
.post .body { white-space: pre-line; }
|
||||
.content:last-child { margin-bottom: 0; }
|
||||
.content form { margin: 1em 0; display: flex; flex-direction: column; }
|
||||
.content label { font-weight: bold; margin-bottom: 0.5em; }
|
||||
.content input, .content textarea { margin-bottom: 1em; }
|
||||
.content textarea { min-height: 12em; resize: vertical; }
|
||||
input.danger { color: #cc2f2e; }
|
||||
input[type=submit] { align-self: start; min-width: 10em; }
|
||||
@@ -59,4 +59,5 @@
|
||||
</section>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</body>
|
||||
<footer class="w3-highway-red">Special thanks to <strong>Langspielplatte</strong> for hosting this webspace! <strong><3</strong> </footer>
|
||||
@@ -8,11 +8,14 @@
|
||||
<form method=post enctype=multipart/form-data>
|
||||
<label for="title">Title</label>
|
||||
<input name="title" id="title" value="{{ request.form['title'] }}" required>
|
||||
<label for="nickname">Nickname</label>
|
||||
<input name="nickname" id="nickname" value="{{ request.form['nickname'] }}" required>
|
||||
<label for="body">Body</label>
|
||||
<textarea name="body" id="body">{{ request.form['body'] }}</textarea>
|
||||
<label for="file">Body</label>
|
||||
<div>
|
||||
<p>Choose a mp4, webm, gif , png or jpg file.(max 25MB)</p>
|
||||
<input type="file" placeholder="meme" name="file" required>
|
||||
<input type="file" placeholder="meme" name="file" id="file" required>
|
||||
</div>
|
||||
<input type="submit" value=Upload>
|
||||
</form>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block header %}
|
||||
|
||||
|
||||
{% block header %}
|
||||
<div class="container w3-center">
|
||||
<h1>{% block title %}Welcome to the Dankventskalender 2020!{% endblock %}</h1>
|
||||
<div>
|
||||
@@ -14,25 +15,31 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% for post in posts %}
|
||||
<article class="post">
|
||||
<header>
|
||||
<div>
|
||||
<h1>{{ post['title'] }}</h1>
|
||||
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%Y-%m-%d') }}</div>
|
||||
</div>
|
||||
{% if g.user['id'] == post['author_id'] %}
|
||||
<a class="action" href="{{ url_for('calender.update', id=post['id']) }}">Edit</a>
|
||||
<div class="container w3-center">
|
||||
{% for post in posts %}
|
||||
<div class="item">
|
||||
<article class="post">
|
||||
<header>
|
||||
<div>
|
||||
<h1>{{ post['title'] }}</h1>
|
||||
<h2>{{ post['nickname'] }}</h2>
|
||||
<div class="about">by {{ post['username'] }}
|
||||
on {{ post['created'].strftime('%Y-%m-%d') }}</div>
|
||||
</div>
|
||||
{% if g.user['id'] == post['author_id'] %}
|
||||
<a class="action" href="{{ url_for('calender.update', id=post['id']) }}">Edit</a>
|
||||
{% endif %}
|
||||
</header>
|
||||
<img class="file" src="{{ post['file'] }}">
|
||||
<p class="body">{{ post['body'] }}</p>
|
||||
</article>
|
||||
{% if not loop.last %}
|
||||
<hr>
|
||||
{% endif %}
|
||||
</header>
|
||||
<p class="body">{{ post['body'] }}</p>
|
||||
</article>
|
||||
{% if not loop.last %}
|
||||
<hr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user