model_view

This commit is contained in:
Daniel Tsvetkov 2020-03-25 16:23:24 +01:00
parent 4a8d8da076
commit 9559d029bf
7 changed files with 149 additions and 1 deletions

View File

@ -13,6 +13,7 @@ DATABASE_FILE = os.path.join(DATA_DIR, "db.sqlite")
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(DATABASE_FILE) SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(DATABASE_FILE)
TEMPLATES_FOLDER = os.path.join(basepath, "webapp", "templates") TEMPLATES_FOLDER = os.path.join(basepath, "webapp", "templates")
STATIC_FOLDER = os.path.join(basepath, "webapp", "static")
MAKEDIRS = [ MAKEDIRS = [
DATA_DIR, TASKS_DIR, TASKS_IN_DIR, TASKS_PROC_DIR, TASKS_BUF_DIR, DATA_DIR, TASKS_DIR, TASKS_IN_DIR, TASKS_PROC_DIR, TASKS_BUF_DIR,

View File

@ -1,4 +1,4 @@
from config import TEMPLATES_FOLDER from config import TEMPLATES_FOLDER, STATIC_FOLDER
from oshipka import init_db from oshipka import init_db
from populate import populate_db from populate import populate_db
@ -8,6 +8,7 @@ if init_db(app):
populate_db(app) populate_db(app)
app.template_folder = TEMPLATES_FOLDER app.template_folder = TEMPLATES_FOLDER
app.static_folder = STATIC_FOLDER
if __name__ == "__main__": if __name__ == "__main__":
app.run(debug=True) app.run(debug=True)

View File

@ -16,13 +16,24 @@ Usage $0 [ bootstrap | worker | web ]
" "
worker () { worker () {
source venv/bin/activate
python worker.py python worker.py
} }
web () { web () {
source venv/bin/activate
python run.py python run.py
} }
init_venv() {
virtualenv -p python3 venv
}
install_reqs() {
source venv/bin/activate
pip install -r requirements.txt
}
bootstrap() { bootstrap() {
shift shift
PROJECT_PATH=$1 PROJECT_PATH=$1
@ -52,6 +63,8 @@ bootstrap() {
echo "INFO: Bootstrapping project $PROJECT_NAME..." echo "INFO: Bootstrapping project $PROJECT_NAME..."
mkdir -p ${PROJECT_PATH} mkdir -p ${PROJECT_PATH}
cp -r ${OSHIPKA_PATH}/bootstrap/* ${PROJECT_PATH}/ cp -r ${OSHIPKA_PATH}/bootstrap/* ${PROJECT_PATH}/
cp ${OSHIPKA_PATH}/bootstrap/.gitignore ${PROJECT_PATH}/.gitignore
init_venv
} }
command_main() { command_main() {

View File

@ -0,0 +1,10 @@
{% extends "layout.html" %}
{% block content %}
<h1>Delete {{ model_name }}:{{ instance.uuid }} ?</h1>
<form action="{{ url_for('delete_' + model_name, uuid=instance.uuid) }}" method="post">
<input type="hidden" value="{{ request.args.next }}" name="_next"/>
<input type="submit"/>
</form>
<a href="{{ request.args.next }}">Back</a>
{% endblock %}

View File

@ -0,0 +1,16 @@
{% extends "layout.html" %}
{% block content %}
<h2>{{ model_name_pl }}:</h2>
<ul>
{% for instance in instances %}
<li>
[
<a href="{{ url_for('update_' + model_name, uuid=instance.uuid) }}">e</a> |
<a href="{{ url_for('delete_' + model_name, uuid=instance.uuid, next=url_for('home')) }}">x</a>
]
<a href="{{ url_for('get_' + model_name, uuid=song.uuid) }}">{{ instance[list_display] }}</a>
</li>
{% endfor %}
</ul>
{% endblock %}

106
oshipka/webapp/views.py Normal file
View File

@ -0,0 +1,106 @@
import inflect
from flask import flash, render_template, redirect, request, url_for
from oshipka.persistance import db
def list_view(model_view, template):
def inner():
instances = model_view.model.query.all()
return render_template(template, instances=instances)
return inner
def get_view(model_view, template):
def inner(uuid):
model = model_view.model
instance = model.query.filter_by(uuid=uuid).first()
if not instance:
flash("No {}:{}".format(model_view.model_name, uuid))
return redirect(request.referrer or url_for('home'))
return render_template(template, instance=instance)
return inner
def serialize_form():
return dict(request.form)
def update_view(model_view, template):
def inner(uuid):
model = model_view.model
instance = model.query.filter_by(uuid=uuid).first()
if not instance:
flash("No {}:{}".format(model_view.model_name, uuid))
return redirect(request.referrer or url_for('home'))
if request.method == "GET":
return render_template(template, instance=instance)
serialized_form = serialize_form()
_next = serialized_form.pop('_next') if '_next' in serialized_form else None
for k, v in serialized_form.items():
setattr(instance, k, v)
db.session.add(instance)
db.session.commit()
flash("Updated {}:{}".format(model_view.model_name, uuid))
return redirect(_next or request.referrer or url_for('home'))
return inner
def delete_view(model_view):
def inner(uuid):
model = model_view.model
instance = model.query.filter_by(uuid=uuid).first()
if not instance:
flash("No {}:{}".format(model_view.model_name, uuid))
return redirect(request.referrer or url_for('home'))
if request.method == "GET":
return render_template("delete_instance.html", instance=instance,
model_name=model_view.model_name)
serialized_form = serialize_form()
_next = serialized_form.pop('_next') if '_next' in serialized_form else None
db.session.delete(instance)
db.session.commit()
flash("Deleted {}:{}".format(model_view.model_name, uuid))
return redirect(_next or request.referrer or url_for('home'))
return inner
class ModelView(object):
def __init__(self, app, model):
self.app = app
self.model = model
p = inflect.engine()
self.model_name = model.__name__.lower()
self.model_name_pl = p.plural(self.model_name)
def register_list(self, list_template):
url = '/{}'.format(self.model_name_pl)
self.app.add_url_rule(url,
'list_{}'.format(self.model_name),
list_view(self, list_template))
def register_get(self, retrieve_template):
url = '/{}/<uuid>'.format(self.model_name_pl)
self.app.add_url_rule(url,
'get_{}'.format(self.model_name),
get_view(self, retrieve_template))
def register_update(self, update_template):
url = '/{}/<uuid>/edit'.format(self.model_name_pl)
self.app.add_url_rule(url, methods=["GET", "POST"],
endpoint='update_{}'.format(self.model_name),
view_func=update_view(self, update_template))
def register_delete(self):
url = '/{}/<uuid>/delete'.format(self.model_name_pl)
self.app.add_url_rule(url, methods=["GET", "POST"],
endpoint='delete_{}'.format(self.model_name),
view_func=delete_view(self))

View File

@ -3,6 +3,7 @@ filelock==3.0.12
Flask==1.1.1 Flask==1.1.1
Flask-SQLAlchemy==2.4.1 Flask-SQLAlchemy==2.4.1
Flask-Table==0.5.0 Flask-Table==0.5.0
inflect==4.1.0
itsdangerous==1.1.0 itsdangerous==1.1.0
Jinja2==2.11.1 Jinja2==2.11.1
MarkupSafe==1.1.1 MarkupSafe==1.1.1