Skip to content

Commit f8af880

Browse files
authored
Merge pull request #488 from MongoEngine/example_app_style_update
Changed: Example app view style
2 parents 99ae06f + bf335f4 commit f8af880

File tree

8 files changed

+161
-88
lines changed

8 files changed

+161
-88
lines changed

example_app/app.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
from flask_debugtoolbar import DebugToolbarExtension
33
from pymongo import monitoring
44

5+
from example_app import views
56
from example_app.models import db
6-
from example_app.views import index, pagination
77
from flask_mongoengine.panels import mongo_command_logger
88

99
app = flask.Flask("example_app")
@@ -38,8 +38,8 @@
3838
db.init_app(app)
3939

4040

41-
app.add_url_rule("/", view_func=index)
42-
app.add_url_rule("/pagination", view_func=pagination)
41+
app.add_url_rule("/", view_func=views.index, methods=["GET", "POST"])
42+
app.add_url_rule("/pagination", view_func=views.pagination, methods=["GET", "POST"])
4343

4444
if __name__ == "__main__":
4545
app.run(host="0.0.0.0", port=8000)

example_app/compose/flask/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ RUN apt-get update && \
77
RUN groupadd -r flask && useradd -r -g flask flask
88
COPY --chown=flask . /flask_mongoengine
99
RUN pip install --upgrade pip \
10-
&& pip install -e /flask_mongoengine[toolbar,wtf]
10+
&& pip install -e /flask_mongoengine[toolbar,wtf] \
11+
&& pip install Faker
1112
WORKDIR /flask_mongoengine

example_app/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22

33
from flask_mongoengine import MongoEngine
4+
from flask_mongoengine.wtf.orm import model_form
45

56
db = MongoEngine()
67

@@ -10,3 +11,6 @@ class Todo(db.Document):
1011
text = db.StringField()
1112
done = db.BooleanField(default=False)
1213
pub_date = db.DateTimeField(default=datetime.datetime.now)
14+
15+
16+
TodoForm = model_form(Todo)

example_app/static/style.css

Lines changed: 0 additions & 17 deletions
This file was deleted.

example_app/templates/index.html

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
{% extends "layout.html" %}
22
{% block body %}
3-
{% for todo in todos %}
4-
<div>
5-
<h2>{{ todo.title }}</h2>
6-
{{ todo.text|safe }}
7-
</div>
8-
{% else %}
9-
<em>Unbelievable. No todos here so far <a href="/add">Add one</a></em>
10-
{% endfor %}
11-
<br/>
12-
<a href="{{ url_for('pagination') }}">See pagination</a>
3+
<p>This is demo application that shows Flask-Mongoengine features and integrations.</p>
4+
<p>Feel free to open Flask debug toolbar after any action to check executed database requests.</p>
5+
<p>If you use this application for first time, it is good idea to generate some fake data.</p>
6+
<p>
7+
Data will be generated inside docker container database.
8+
Two databases will be used to show Flask Debug Panel integration capabilities.
9+
</p>
10+
<p>You can also delete all data, to test forms only.</p>
11+
{% if message %}
12+
<p><mark>{{ message }}</mark></p>
13+
{% endif %}
14+
<form action="{{ url_for("index") }}" method="post">
15+
<input type="submit" name="button" value="Generate data"/>
16+
<input type="submit" name="button" value="Delete data"/>
17+
</form>
1318
{% endblock %}

example_app/templates/layout.html

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
<!doctype html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<title>Flask MongoEngine</title>
5-
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
4+
<title>Flask MongoEngine</title>
5+
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
66
</head>
77
<body>
8-
<div class=page>
9-
<h1>Toolbar example</h1>
8+
<nav>
9+
<ul>
10+
<li><a href="{{ url_for("index") }}">Home</a></li>
11+
<li><a href="{{ url_for("pagination") }}">Pagination</a></li>
12+
</ul>
13+
</nav>
14+
<div>
1015
<div>
11-
{% block body %}{% endblock %}
16+
{% block body %}{% endblock %}
1217
</div>
1318
</div>
1419
</body>

example_app/templates/pagination.html

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,68 @@
22

33
{# Macro for creating navigation links #}
44
{% macro render_navigation(pagination, endpoint) %}
5-
<div class=pagination>
6-
{% for page in pagination.iter_pages() %}
7-
{% if page %}
8-
{% if page != pagination.page %}
9-
<a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
10-
{% else %}
11-
<strong>{{ page }}</strong>
12-
{% endif %}
13-
{% else %}
14-
<span class=ellipsis></span>
15-
{% endif %}
16-
{% endfor %}
17-
</div>
5+
<div>
6+
{% for page in pagination.iter_pages() %}
7+
{% if page %}
8+
{% if page != pagination.page %}
9+
<a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
10+
{% else %}
11+
<strong>{{ page }}</strong>
12+
{% endif %}
13+
{% else %}
14+
<span>nothing to show</span>
15+
{% endif %}
16+
{% endfor %}
17+
</div>
1818
{% endmacro %}
1919

20-
{% block body %}
21-
22-
<div class="todos">
23-
<ul>
24-
{% for todo in todos_page.items %}
25-
<li>{{ todo.title }}</li>
26-
{% endfor %}
27-
</ul>
28-
</div>
20+
{% macro with_errors(field) %}
21+
<div class="form_field">
22+
{% if field.errors %}
23+
{% set css_class = 'has_error ' + kwargs.pop('class', '') %}
24+
{{ field.label }}{{ field(class=css_class, **kwargs) }}{% if field.flags.required %}*{% endif %}
25+
<ul class="errors">{% for error in field.errors %}
26+
<li>{{ error|e }}</li>{% endfor %}</ul>
27+
{% else %}
28+
{{ field.label }}{{ field(**kwargs) }}{% if field.flags.required %}*{% endif %}
29+
{% endif %}
30+
</div>
31+
{% endmacro %}
2932

30-
<div class="navigation">
31-
{{ render_navigation(todos_page, 'pagination') }}
32-
</div>
33+
{% block body %}
3334

35+
<div>
36+
<table>
37+
<thead>
38+
<tr>
39+
<th>Title</th>
40+
<th>Text</th>
41+
<th>Done</th>
42+
<th>Publication date</th>
43+
</tr>
44+
</thead>
45+
<tbody>
46+
{% for todo in todos_page.items %}
47+
<tr>
48+
<td>{{ todo.title }}</td>
49+
<td>{{ todo.text }}</td>
50+
<td>{{ todo.done }}</td>
51+
<td>{{ todo.pub_date }}</td>
52+
</tr>
53+
{% endfor %}
54+
</tbody>
55+
</table>
56+
</div>
57+
<div>
58+
{{ render_navigation(todos_page, "pagination") }}
59+
</div>
60+
<div>
61+
<form method="POST" action="{{ url_for("pagination") }}">
62+
{% for field in form %}
63+
{{ with_errors(field, style='font-weight: bold') }}
64+
{% endfor %}
65+
<input type="submit" value="Create">
66+
</form>
67+
</div>
3468

3569
{% endblock %}

example_app/views.py

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,78 @@
1-
import flask
1+
"""Demo views for example application."""
2+
from faker import Faker
3+
from flask import render_template, request
24
from mongoengine.context_managers import switch_db
35

6+
from example_app import models
47

5-
def index():
6-
from models import Todo
7-
8-
with switch_db(Todo, "default") as Todo:
9-
# As a list to test debug toolbar
10-
Todo.objects().delete() # Removes
11-
Todo(title="Simple todo A", text="12345678910").save() # Insert
12-
Todo(title="Simple todo B", text="12345678910").save() # Insert
13-
Todo(title="Simple todo C", text="12345678910").save() # Insert
8+
9+
def generate_data():
10+
"""Generates fake data for all supported models and views."""
11+
fake = Faker(locale=["en_US"])
12+
13+
with switch_db(models.Todo, "default"):
14+
models.Todo.objects().delete() # Removes
15+
models.Todo(
16+
title="Simple todo A", text=fake.sentence(), done=False
17+
).save() # Insert
18+
models.Todo(
19+
title="Simple todo B", text=fake.sentence(), done=True
20+
).save() # Insert
21+
models.Todo(
22+
title="Simple todo C", text=fake.sentence(), done=True
23+
).save() # Insert
1424
# Bulk insert
15-
bulk = (Todo(title="Bulk 1"), Todo(title="Bulk 2"))
16-
Todo.objects().insert(bulk)
17-
Todo.objects(title__contains="B").order_by("-title").update(
25+
bulk = (
26+
models.Todo(title="Bulk 1", text=fake.sentence(), done=False),
27+
models.Todo(title="Bulk 2", text=fake.sentence(), done=True),
28+
)
29+
models.Todo.objects().insert(bulk)
30+
models.Todo.objects(title__contains="B").order_by("-title").update(
1831
set__text="Hello world"
1932
) # Update
20-
Todo.objects(title__contains="C").order_by("-title").delete() # Removes
21-
todos = list(Todo.objects.order_by("-title", "done")[2:10])
22-
todos = Todo.objects.all().order_by("-title")
23-
return flask.render_template("index.html", todos=todos)
33+
models.Todo.objects(title__contains="C").order_by("-title").delete() # Removes
2434

35+
with switch_db(models.Todo, "secondary"):
36+
models.Todo.objects().delete()
37+
for _ in range(10):
38+
models.Todo(
39+
title=fake.text(max_nb_chars=59),
40+
text=fake.sentence(),
41+
done=fake.pybool(),
42+
pub_date=fake.date(),
43+
).save()
2544

26-
def pagination():
27-
from models import Todo
2845

29-
with switch_db(Todo, "secondary") as Todo:
30-
Todo.objects().delete()
31-
for i in range(10):
32-
Todo(title=f"Simple todo {i}", text="12345678910").save()
46+
def delete_data():
47+
"""Clear database."""
48+
with switch_db(models.Todo, "default"):
49+
models.Todo.objects().delete()
50+
with switch_db(models.Todo, "secondary"):
51+
models.Todo.objects().delete()
52+
53+
54+
def index():
55+
"""Return page with welcome words and instructions."""
56+
message = None
57+
if request.method == "POST":
58+
if request.form["button"] == "Generate data":
59+
generate_data()
60+
message = "Fake data generated"
61+
if request.form["button"] == "Delete data":
62+
delete_data()
63+
message = "All data deleted"
64+
return render_template("index.html", message=message)
65+
66+
67+
def pagination():
68+
"""Return pagination and easy form demonstration."""
69+
form = models.TodoForm()
3370

34-
page_num = int(flask.request.args.get("page") or 1)
35-
todos_page = Todo.objects.paginate(page=page_num, per_page=3)
71+
with switch_db(models.Todo, "secondary"):
72+
if request.method == "POST":
73+
form.validate_on_submit()
74+
form.save()
75+
page_num = int(request.args.get("page") or 1)
76+
todos_page = models.Todo.objects.paginate(page=page_num, per_page=3)
3677

37-
return flask.render_template("pagination.html", todos_page=todos_page)
78+
return render_template("pagination.html", todos_page=todos_page, form=form)

0 commit comments

Comments
 (0)