removed all old *_lst tables, added corresponding new classes, etc. fro covertype, owned, rating, and dropped tables from DB, etc. Updated base.html to use new tables as drop-downs that are set correctly. So far slight hack on BookForm, will finish that after syncing this all back to mara. If I do the sync, and export/import this version of DB, then the fixes.sql and fix_db() code included in main.py can be removed. Finally, lamely added a favicon and a static/ to support it
This commit is contained in:
2
README
2
README
@@ -14,7 +14,7 @@ sudo apt install python3-pip python3-psycopg2 libpq-dev
|
||||
pip3 install --user flask sqlalchemy flask-sqlalchemy flask-marshmallow SQLAlchemy-serializer flask-wtf flask-bootstrap marshmallow-sqlalchemy
|
||||
|
||||
|
||||
### alter db that was saved by:
|
||||
### fix up db changes by running those in fixes.sql
|
||||
psql library
|
||||
alter table genre_lst rename to genre;
|
||||
alter table genre rename COLUMN genre to name;
|
||||
|
||||
@@ -36,8 +36,6 @@ class ConditionForm(Form):
|
||||
@app.route("/conditions", methods=["GET"])
|
||||
def conditions():
|
||||
conditions = Condition.query.order_by('id').all()
|
||||
print ( Condition.query.order_by('id') )
|
||||
print ( conditions )
|
||||
return render_template("conditions.html", conditions=conditions)
|
||||
|
||||
################################################################################
|
||||
|
||||
66
covertype.py
Normal file
66
covertype.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from wtforms import SubmitField, StringField, HiddenField, SelectField, validators, Form
|
||||
from flask import request, render_template
|
||||
from __main__ import db, app, ma
|
||||
|
||||
################################################################################
|
||||
# Class describing Covertype in the database, and via sqlalchemy, connected to the DB as well
|
||||
################################################################################
|
||||
class Covertype(db.Model):
|
||||
id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
|
||||
name = db.Column(db.String(50), unique=False, nullable=False)
|
||||
|
||||
def __repr__(self):
|
||||
return "<id: {}, name: {}>".format(self.id,self.name)
|
||||
|
||||
################################################################################
|
||||
# Helper class that inherits a .dump() method to turn class Covertype into json / useful in jinja2
|
||||
################################################################################
|
||||
class CovertypeSchema(ma.SQLAlchemyAutoSchema):
|
||||
class Meta: model = Covertype
|
||||
|
||||
|
||||
################################################################################
|
||||
# Helper class that defines a form for covertype, used to make html <form>, with field validation (via wtforms)
|
||||
################################################################################
|
||||
class CovertypeForm(Form):
|
||||
id = HiddenField()
|
||||
name = StringField('Name:', [validators.DataRequired()])
|
||||
submit = SubmitField('Save' )
|
||||
delete = SubmitField('Delete' )
|
||||
|
||||
################################################################################
|
||||
# Routes for covertype data
|
||||
#
|
||||
# /covertypes -> GET only -> prints out list of all covertypes
|
||||
################################################################################
|
||||
@app.route("/covertypes", methods=["GET"])
|
||||
def covertypes():
|
||||
covertypes = Covertype.query.order_by('id').all()
|
||||
return render_template("covertypes.html", covertypes=covertypes)
|
||||
|
||||
################################################################################
|
||||
# /covertype/<id> -> GET/POST(save or delete) -> shows/edits/delets a single
|
||||
# covertype
|
||||
################################################################################
|
||||
@app.route("/covertype/<id>", methods=["GET", "POST"])
|
||||
def covertype(id):
|
||||
### DDP: should this be request.form or request.values?
|
||||
alert="Success"
|
||||
covertype_form = CovertypeForm(request.form)
|
||||
if request.method == 'POST' and covertype_form.validate():
|
||||
id = request.form['id']
|
||||
covertype = Covertype.query.get(id)
|
||||
try:
|
||||
request.form['submit']
|
||||
except:
|
||||
message="Sorry, Deleting unsupported at present"
|
||||
alert="Danger"
|
||||
else:
|
||||
covertype.name = request.form['name']
|
||||
db.session.commit()
|
||||
message="Successfully Updated Covertype (id={})".format(id)
|
||||
else:
|
||||
covertype = Covertype.query.get(id)
|
||||
covertype_form = CovertypeForm(request.values, obj=covertype)
|
||||
message=""
|
||||
return render_template("covertype.html", covertype=covertype, alert=alert, message=message, covertype_form=covertype_form)
|
||||
75
fixes.sql
75
fixes.sql
@@ -1,10 +1,79 @@
|
||||
ALTER TABLE genre_lst RENAME TO genre;
|
||||
ALTER TABLE genre RENAME COLUMN genre TO name;
|
||||
|
||||
CREATE TABLE condition (
|
||||
id INTEGER,
|
||||
name VARCHAR(20) not null,
|
||||
constraint pk_condition primary key(id)
|
||||
id INTEGER,
|
||||
name VARCHAR(20) not null,
|
||||
constraint pk_condition primary key(id)
|
||||
);
|
||||
INSERT INTO condition VALUES ( 1, 'Good' );
|
||||
INSERT INTO condition VALUES ( 2, 'Average' );
|
||||
INSERT INTO condition VALUES ( 3, 'Needs Replacing' );
|
||||
INSERT INTO condition VALUES ( 4, 'N/A' );
|
||||
ALTER TABLE book ADD COLUMN temp_cond integer , ADD CONSTRAINT fk_book_condition_new foreign key(temp_cond) REFERENCES condition(id)
|
||||
|
||||
CREATE TABLE covertype (
|
||||
id INTEGER,
|
||||
name VARCHAR(20) not null,
|
||||
constraint pk_covertype primary key(id)
|
||||
);
|
||||
INSERT INTO covertype VALUES ( 1, 'Paperback' );
|
||||
INSERT INTO covertype VALUES ( 2, 'Over-size Paperback' );
|
||||
INSERT INTO covertype VALUES ( 3, 'Hardcover' );
|
||||
INSERT INTO covertype VALUES ( 4, 'N/A' );
|
||||
ALTER TABLE book ADD COLUMN temp_cover integer , ADD CONSTRAINT fk_book_covertype_new foreign key(temp_cover) REFERENCES covertype(id)
|
||||
|
||||
CREATE TABLE owned (
|
||||
id INTEGER,
|
||||
name VARCHAR(20) not null,
|
||||
constraint pk_owned primary key(id)
|
||||
);
|
||||
INSERT INTO owned VALUES ( 1, 'Currently Owned' );
|
||||
INSERT INTO owned VALUES ( 2, 'On Wish List' );
|
||||
INSERT INTO owned VALUES ( 3, 'Sold' );
|
||||
ALTER TABLE book ADD COLUMN temp_owned integer , ADD CONSTRAINT fk_book_owned_new foreign key(temp_owned) REFERENCES owned(id);
|
||||
|
||||
CREATE TABLE rating (
|
||||
id INTEGER,
|
||||
name VARCHAR(20) not null,
|
||||
constraint pk_rating primary key(id)
|
||||
);
|
||||
INSERT INTO rating VALUES ( 1, '10' );
|
||||
INSERT INTO rating VALUES ( 2, '9' );
|
||||
INSERT INTO rating VALUES ( 3, '8' );
|
||||
INSERT INTO rating VALUES ( 4, '7' );
|
||||
INSERT INTO rating VALUES ( 5, '6' );
|
||||
INSERT INTO rating VALUES ( 6, '5' );
|
||||
INSERT INTO rating VALUES ( 7, '4' );
|
||||
INSERT INTO rating VALUES ( 8, '3' );
|
||||
INSERT INTO rating VALUES ( 9, '2' );
|
||||
INSERT INTO rating VALUES ( 10, '1' );
|
||||
INSERT INTO rating VALUES ( 11, 'N/A' );
|
||||
INSERT INTO rating VALUES ( 12, 'Undefined' );
|
||||
ALTER TABLE book ADD COLUMN temp_rating integer, ADD CONSTRAINT fk_book_rating_new foreign key(temp_rating) REFERENCES rating(id);
|
||||
|
||||
|
||||
### fore each new table (e.g do above), then
|
||||
# add appropriate new field to Book class definition, eg for condition:
|
||||
temp_cond = db.Column(db.Integer)
|
||||
|
||||
# then run python code with fix_db() -- which fixes appropriate Book.<new_field>, then:
|
||||
|
||||
ALTER TABLE book DROP COLUMN condition;
|
||||
ALTER TABLE book RENAME COLUMN temp_cond TO condition;
|
||||
|
||||
ALTER TABLE book DROP COLUMN covertype;
|
||||
ALTER TABLE book RENAME COLUMN temp_cover TO covertype;
|
||||
|
||||
ALTER TABLE book DROP COLUMN owned;
|
||||
ALTER TABLE book RENAME COLUMN temp_owned TO owned;
|
||||
|
||||
ALTER TABLE book DROP COLUMN rating;
|
||||
ALTER TABLE book RENAME COLUMN temp_rating TO rating;
|
||||
|
||||
DROP TABLE condition_lst
|
||||
DROP TABLE covertype_lst
|
||||
DROP TABLE owned_lst
|
||||
DROP TABLE rating_lst
|
||||
|
||||
# then modify main.py again, to delete condition and rename temp_<field> to <feild> in class Book
|
||||
|
||||
42
main.py
42
main.py
@@ -1,10 +1,9 @@
|
||||
from flask import Flask
|
||||
from flask import render_template
|
||||
from flask import request
|
||||
from flask import Flask, render_template, request
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_marshmallow import Marshmallow
|
||||
from flask_bootstrap import Bootstrap
|
||||
from wtforms import SubmitField, StringField, HiddenField, SelectField, validators, Form
|
||||
from flask_wtf import FlaskForm
|
||||
|
||||
app = Flask(__name__)
|
||||
### what is this value? I gather I should chagne it?
|
||||
@@ -20,6 +19,9 @@ from author import Author, AuthorForm, AuthorSchema
|
||||
from publisher import Publisher, PublisherForm, PublisherSchema
|
||||
from genre import Genre, GenreForm, GenreSchema
|
||||
from condition import Condition, ConditionForm, ConditionSchema
|
||||
from covertype import Covertype, CovertypeForm, CovertypeSchema
|
||||
from owned import Owned, OwnedForm, OwnedSchema
|
||||
from rating import Rating, RatingForm, RatingSchema
|
||||
|
||||
####################################### CLASSES / DB model #######################################
|
||||
book_author_link = db.Table('book_author_link', db.Model.metadata,
|
||||
@@ -53,10 +55,10 @@ class Book(db.Model):
|
||||
publisher = db.relationship('Publisher', secondary=book_publisher_link)
|
||||
genre = db.relationship('Genre', secondary=book_genre_link )
|
||||
year_published = db.Column(db.Integer)
|
||||
owned = db.Column(db.String(20))
|
||||
covertype = db.Column(db.String(20))
|
||||
condition = db.Column(db.String(20))
|
||||
rating = db.Column(db.String(20))
|
||||
condition = db.Column(db.Integer, db.ForeignKey('condition.id'))
|
||||
covertype = db.Column(db.Integer, db.ForeignKey('covertype.id'))
|
||||
owned = db.Column(db.Integer, db.ForeignKey('owned.id'))
|
||||
rating = db.Column(db.Integer, db.ForeignKey('rating.id'))
|
||||
notes = db.Column(db.Text)
|
||||
blurb = db.Column(db.Text)
|
||||
created = db.Column(db.Date)
|
||||
@@ -85,12 +87,15 @@ class BookSchema(ma.SQLAlchemyAutoSchema):
|
||||
#
|
||||
# To be completed
|
||||
#
|
||||
class BookForm(Form):
|
||||
class BookForm(FlaskForm):
|
||||
# I think I'll have to skip setting default on create, and using jquery to
|
||||
# change it when I create the from? (or maybe I could use a default=set_me
|
||||
# in the line below, then when I set create set_me = book.condition before
|
||||
# bf=BookForm()
|
||||
condition = SelectField( 'condition', choices=[(c.id, c.name) for c in Condition.query.order_by('id')] )
|
||||
covertype = SelectField( 'covertype', choices=[(c.id, c.name) for c in Covertype.query.order_by('id')] )
|
||||
owned = SelectField( 'owned', choices=[(c.id, c.name) for c in Owned.query.order_by('id')] )
|
||||
rating = SelectField( 'rating', choices=[(c.id, c.name) for c in Rating.query.order_by('id')] )
|
||||
|
||||
|
||||
### DDP: do I need many=True on Author as books have many authors? (or in BookSchema declaration above?)
|
||||
@@ -136,11 +141,30 @@ def book(id):
|
||||
|
||||
book_s['sub_book'] = sub_book
|
||||
|
||||
return render_template("book.html", books=book_s, subs=sub_book )
|
||||
book_form=BookForm(request.form)
|
||||
# set defaults for drop-down's based on this book
|
||||
book_form.condition.default = book.condition
|
||||
book_form.covertype.default = book.covertype
|
||||
book_form.owned.default = book.owned
|
||||
book_form.rating.default = book.rating
|
||||
print(book_form)
|
||||
book_form.process()
|
||||
return render_template("book.html", books=book_s, subs=sub_book, book_form=book_form )
|
||||
|
||||
@app.route("/", methods=["GET"])
|
||||
def main_page():
|
||||
return render_template("base.html")
|
||||
|
||||
def fix_db():
|
||||
books = Book.query.all()
|
||||
for book in books:
|
||||
rating=Rating.query.filter_by(name=book.rating).all()
|
||||
book.temp_rating=rating[0].id
|
||||
print(book.temp_rating)
|
||||
db.session.commit()
|
||||
print( "ran fix_db()")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# fix_db()
|
||||
app.run(host="0.0.0.0", debug=True)
|
||||
|
||||
66
owned.py
Normal file
66
owned.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from wtforms import SubmitField, StringField, HiddenField, SelectField, validators, Form
|
||||
from flask import request, render_template
|
||||
from __main__ import db, app, ma
|
||||
|
||||
################################################################################
|
||||
# Class describing Owned in the database, and via sqlalchemy, connected to the DB as well
|
||||
################################################################################
|
||||
class Owned(db.Model):
|
||||
id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
|
||||
name = db.Column(db.String(50), unique=False, nullable=False)
|
||||
|
||||
def __repr__(self):
|
||||
return "<id: {}, name: {}>".format(self.id,self.name)
|
||||
|
||||
################################################################################
|
||||
# Helper class that inherits a .dump() method to turn class Owned into json / useful in jinja2
|
||||
################################################################################
|
||||
class OwnedSchema(ma.SQLAlchemyAutoSchema):
|
||||
class Meta: model = Owned
|
||||
|
||||
|
||||
################################################################################
|
||||
# Helper class that defines a form for owned, used to make html <form>, with field validation (via wtforms)
|
||||
################################################################################
|
||||
class OwnedForm(Form):
|
||||
id = HiddenField()
|
||||
name = StringField('Name:', [validators.DataRequired()])
|
||||
submit = SubmitField('Save' )
|
||||
delete = SubmitField('Delete' )
|
||||
|
||||
################################################################################
|
||||
# Routes for owned data
|
||||
#
|
||||
# /owneds -> GET only -> prints out list of all owneds
|
||||
################################################################################
|
||||
@app.route("/owneds", methods=["GET"])
|
||||
def owneds():
|
||||
owneds = Owned.query.order_by('id').all()
|
||||
return render_template("owneds.html", owneds=owneds)
|
||||
|
||||
################################################################################
|
||||
# /owned/<id> -> GET/POST(save or delete) -> shows/edits/delets a single
|
||||
# owned
|
||||
################################################################################
|
||||
@app.route("/owned/<id>", methods=["GET", "POST"])
|
||||
def owned(id):
|
||||
### DDP: should this be request.form or request.values?
|
||||
alert="Success"
|
||||
owned_form = OwnedForm(request.form)
|
||||
if request.method == 'POST' and owned_form.validate():
|
||||
id = request.form['id']
|
||||
owned = Owned.query.get(id)
|
||||
try:
|
||||
request.form['submit']
|
||||
except:
|
||||
message="Sorry, Deleting unsupported at present"
|
||||
alert="Danger"
|
||||
else:
|
||||
owned.name = request.form['name']
|
||||
db.session.commit()
|
||||
message="Successfully Updated Owned (id={})".format(id)
|
||||
else:
|
||||
owned = Owned.query.get(id)
|
||||
owned_form = OwnedForm(request.values, obj=owned)
|
||||
message=""
|
||||
return render_template("owned.html", owned=owned, alert=alert, message=message, owned_form=owned_form)
|
||||
66
rating.py
Normal file
66
rating.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from wtforms import SubmitField, StringField, HiddenField, SelectField, validators, Form
|
||||
from flask import request, render_template
|
||||
from __main__ import db, app, ma
|
||||
|
||||
################################################################################
|
||||
# Class describing Rating in the database, and via sqlalchemy, connected to the DB as well
|
||||
################################################################################
|
||||
class Rating(db.Model):
|
||||
id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
|
||||
name = db.Column(db.String(50), unique=False, nullable=False)
|
||||
|
||||
def __repr__(self):
|
||||
return "<id: {}, name: {}>".format(self.id,self.name)
|
||||
|
||||
################################################################################
|
||||
# Helper class that inherits a .dump() method to turn class Rating into json / useful in jinja2
|
||||
################################################################################
|
||||
class RatingSchema(ma.SQLAlchemyAutoSchema):
|
||||
class Meta: model = Rating
|
||||
|
||||
|
||||
################################################################################
|
||||
# Helper class that defines a form for rating, used to make html <form>, with field validation (via wtforms)
|
||||
################################################################################
|
||||
class RatingForm(Form):
|
||||
id = HiddenField()
|
||||
name = StringField('Name:', [validators.DataRequired()])
|
||||
submit = SubmitField('Save' )
|
||||
delete = SubmitField('Delete' )
|
||||
|
||||
################################################################################
|
||||
# Routes for rating data
|
||||
#
|
||||
# /ratings -> GET only -> prints out list of all ratings
|
||||
################################################################################
|
||||
@app.route("/ratings", methods=["GET"])
|
||||
def ratings():
|
||||
ratings = Rating.query.order_by('id').all()
|
||||
return render_template("ratings.html", ratings=ratings)
|
||||
|
||||
################################################################################
|
||||
# /rating/<id> -> GET/POST(save or delete) -> shows/edits/delets a single
|
||||
# rating
|
||||
################################################################################
|
||||
@app.route("/rating/<id>", methods=["GET", "POST"])
|
||||
def rating(id):
|
||||
### DDP: should this be request.form or request.values?
|
||||
alert="Success"
|
||||
rating_form = RatingForm(request.form)
|
||||
if request.method == 'POST' and rating_form.validate():
|
||||
id = request.form['id']
|
||||
rating = Rating.query.get(id)
|
||||
try:
|
||||
request.form['submit']
|
||||
except:
|
||||
message="Sorry, Deleting unsupported at present"
|
||||
alert="Danger"
|
||||
else:
|
||||
rating.name = request.form['name']
|
||||
db.session.commit()
|
||||
message="Successfully Updated Rating (id={})".format(id)
|
||||
else:
|
||||
rating = Rating.query.get(id)
|
||||
rating_form = RatingForm(request.values, obj=rating)
|
||||
message=""
|
||||
return render_template("rating.html", rating=rating, alert=alert, message=message, rating_form=rating_form)
|
||||
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -8,6 +8,7 @@
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.18.0/dist/bootstrap-table.min.css">
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap4.min.css">
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
|
||||
<script src="https://kit.fontawesome.com/9b4c7cf470.js" crossorigin="anonymous"></script>
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
</head>
|
||||
@@ -48,8 +49,12 @@
|
||||
<a class="dropdown-item" href="{{url_for('genres')}}">Show Genres</a>
|
||||
<a class="dropdown-item" href="{{url_for('conditions')}}">Create new Condition</a>
|
||||
<a class="dropdown-item" href="{{url_for('conditions')}}">Show Conditions</a>
|
||||
<a class="dropdown-item" href="{{url_for('genres')}}">Create new Covertype</a>
|
||||
<a class="dropdown-item" href="{{url_for('genres')}}">Show Covertypes</a>
|
||||
<a class="dropdown-item" href="{{url_for('covertypes')}}">Create new Covertype</a>
|
||||
<a class="dropdown-item" href="{{url_for('covertypes')}}">Show Covertypes</a>
|
||||
<a class="dropdown-item" href="{{url_for('owneds')}}">Create new Owned Type</a>
|
||||
<a class="dropdown-item" href="{{url_for('owneds')}}">Show Owned Types</a>
|
||||
<a class="dropdown-item" href="{{url_for('ratings')}}">Create new Rating</a>
|
||||
<a class="dropdown-item" href="{{url_for('ratings')}}">Show Owned Ratings</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,44 +3,52 @@
|
||||
<h3><center>View/Edit Book</center></h1>
|
||||
{% set keys = [ 'title', 'author', 'publisher', 'genre', 'owned', 'covertype', 'condition', 'year_published', 'rating', 'notes', 'blurb' ] %}
|
||||
<div class="container">
|
||||
<div class="row with-margin">
|
||||
<div class="row">
|
||||
<form class="form col-lg-12">
|
||||
{% for key in keys %}
|
||||
<div class="input-group input-group-lg">
|
||||
{% if key == "condition" or key == "covertype" or key == "owned" or key == "rating" %}
|
||||
<div class="form-row">
|
||||
<label for="{{key}}" class="col-lg-2 col-form-label">{{key}}:</label>
|
||||
<div class="col-lg-10">
|
||||
{{book_form[key](class="form-control")}}
|
||||
</div class="col-lg-10">
|
||||
</div class="form-row">
|
||||
{% else %}
|
||||
<div class="form-row">
|
||||
<label for="{{key}}" class="col-lg-2 col-form-label">{{key}}:</label>
|
||||
<div class="col-lg-10">
|
||||
<div class="row">
|
||||
{% if books[key] is iterable and books[key] is not string %}
|
||||
{% set cnt = namespace(idx=0, val=0) %}
|
||||
{% for objects in books[key] %}
|
||||
{% set cnt.val = 0 %}
|
||||
{% set str = namespace(val="") %}
|
||||
{% for attr in objects %}
|
||||
{% if attr != "id" %}
|
||||
{% if cnt.val > 0 %}
|
||||
{% set str.val=str.val+", "+objects[attr] %}
|
||||
{% else %}
|
||||
{% set str.val=str.val+objects[attr] %}
|
||||
{% if books[key] is iterable and books[key] is not string %}
|
||||
<div class="row" style="margin-left:0px; margin-right:0px;">
|
||||
{% set cnt = namespace(idx=0, val=0) %}
|
||||
{% for objects in books[key] %}
|
||||
{% set cnt.val = 0 %}
|
||||
{% set str = namespace(val="") %}
|
||||
{% for attr in objects %}
|
||||
{% if attr != "id" %}
|
||||
{% if cnt.val > 0 %}
|
||||
{% set str.val=str.val+", "+objects[attr] %}
|
||||
{% else %}
|
||||
{% set str.val=str.val+objects[attr] %}
|
||||
{% endif %}
|
||||
{% set cnt.val = cnt.val + 1 %}
|
||||
{% endif %}
|
||||
{% set cnt.val = cnt.val + 1 %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<span class="form-control col-lg-{{((12/books[key]|length)|int)}}" id="{{key}}-{{books[key][cnt.idx].id}}">
|
||||
<a href="{{url_for(key, id=books[key][cnt.idx].id)}}">{{str.val}}</a>
|
||||
</span>
|
||||
{% set cnt.idx = cnt.idx+1 %}
|
||||
{% endfor %}
|
||||
<span class="form-control col-lg-{{((12/books[key]|length)|int)}}" id="{{key}}-{{books[key][cnt.idx].id}}">
|
||||
<a href="{{url_for(key, id=books[key][cnt.idx].id)}}">{{str.val}}</a>
|
||||
</span>
|
||||
{% set cnt.idx = cnt.idx+1 %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</table>
|
||||
{% else %}
|
||||
{% if key == "notes" or key == "blurb" %}
|
||||
<textarea rows="5" type="text" class="form-control input-lg" id="{{key}}">{{books[key]}}</textarea>
|
||||
</div class="row">
|
||||
{% else %}
|
||||
<input type="text" class="form-control input-lg" id="{{key}}" value="{{books[key]}}">
|
||||
{% if key == "notes" or key == "blurb" %}
|
||||
<textarea rows="5" type="text" class="form-control input-lg" id="{{key}}">{{books[key]}}</textarea>
|
||||
{% else %}
|
||||
<input type="text" class="form-control input-lg" id="{{key}}" value="{{books[key]}}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div class="col-lg-8">
|
||||
</div class="form-group">
|
||||
</div class="col-lg-10">
|
||||
</div class="form-row">
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
</div class="row">
|
||||
|
||||
24
templates/covertype.html
Normal file
24
templates/covertype.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends "base.html" %} {% block main_content %}
|
||||
<h3><center>Covertype</center></h3>
|
||||
<div class="container">
|
||||
<right>
|
||||
{% if message|length %}
|
||||
<div class="row alert alert-{{alert}}">
|
||||
{{message}}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<form class="form form-inline col-xl-12" action="" method="POST">
|
||||
{{ wtf.form_field( covertype_form.id, form_type='inline' ) }}
|
||||
<div class="col-xl-12">
|
||||
{{ wtf.form_field( covertype_form.name, form_type='horizontal', horizontal_columns=('xl', 2, 10), style="width:100%" ) }}
|
||||
</div>
|
||||
<div class="col-xl-12">
|
||||
<br></br>
|
||||
</div>
|
||||
{{ wtf.form_field( covertype_form.submit, horizontal_columns=('xl', 2, 2), class="btn btn-primary offset-xl-1 col-xl-2" )}}
|
||||
{{ wtf.form_field( covertype_form.delete, horizontal_columns=('xl', 2, 2), class="btn btn-danger offset-xl-1 col-xl-2" )}}
|
||||
</form>
|
||||
</div class="row">
|
||||
</div class="container">
|
||||
{% endblock main_content %}
|
||||
15
templates/covertypes.html
Normal file
15
templates/covertypes.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block main_content %}
|
||||
<h3>Covertypes</h3>
|
||||
<table id="book_table" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
|
||||
<thead>
|
||||
<tr class="thead-light"><th>Name</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for covertype in covertypes %}
|
||||
<tr><td data-sort="{{covertype.id}}"><a href="{{url_for('covertype', id=covertype.id )}}">{{covertype.name}}</a></td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock main_content %}
|
||||
24
templates/owned.html
Normal file
24
templates/owned.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends "base.html" %} {% block main_content %}
|
||||
<h3><center>Owned</center></h3>
|
||||
<div class="container">
|
||||
<right>
|
||||
{% if message|length %}
|
||||
<div class="row alert alert-{{alert}}">
|
||||
{{message}}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<form class="form form-inline col-xl-12" action="" method="POST">
|
||||
{{ wtf.form_field( owned_form.id, form_type='inline' ) }}
|
||||
<div class="col-xl-12">
|
||||
{{ wtf.form_field( owned_form.name, form_type='horizontal', horizontal_columns=('xl', 2, 10), style="width:100%" ) }}
|
||||
</div>
|
||||
<div class="col-xl-12">
|
||||
<br></br>
|
||||
</div>
|
||||
{{ wtf.form_field( owned_form.submit, horizontal_columns=('xl', 2, 2), class="btn btn-primary offset-xl-1 col-xl-2" )}}
|
||||
{{ wtf.form_field( owned_form.delete, horizontal_columns=('xl', 2, 2), class="btn btn-danger offset-xl-1 col-xl-2" )}}
|
||||
</form>
|
||||
</div class="row">
|
||||
</div class="container">
|
||||
{% endblock main_content %}
|
||||
15
templates/owneds.html
Normal file
15
templates/owneds.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block main_content %}
|
||||
<h3>Owned List</h3>
|
||||
<table id="book_table" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
|
||||
<thead>
|
||||
<tr class="thead-light"><th>Name</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for owned in owneds %}
|
||||
<tr><td data-sort="{{owned.id}}"><a href="{{url_for('owned', id=owned.id )}}">{{owned.name}}</a></td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock main_content %}
|
||||
24
templates/rating.html
Normal file
24
templates/rating.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends "base.html" %} {% block main_content %}
|
||||
<h3><center>Rating</center></h3>
|
||||
<div class="container">
|
||||
<right>
|
||||
{% if message|length %}
|
||||
<div class="row alert alert-{{alert}}">
|
||||
{{message}}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<form class="form form-inline col-xl-12" action="" method="POST">
|
||||
{{ wtf.form_field( rating_form.id, form_type='inline' ) }}
|
||||
<div class="col-xl-12">
|
||||
{{ wtf.form_field( rating_form.name, form_type='horizontal', horizontal_columns=('xl', 2, 10), style="width:100%" ) }}
|
||||
</div>
|
||||
<div class="col-xl-12">
|
||||
<br></br>
|
||||
</div>
|
||||
{{ wtf.form_field( rating_form.submit, horizontal_columns=('xl', 2, 2), class="btn btn-primary offset-xl-1 col-xl-2" )}}
|
||||
{{ wtf.form_field( rating_form.delete, horizontal_columns=('xl', 2, 2), class="btn btn-danger offset-xl-1 col-xl-2" )}}
|
||||
</form>
|
||||
</div class="row">
|
||||
</div class="container">
|
||||
{% endblock main_content %}
|
||||
15
templates/ratings.html
Normal file
15
templates/ratings.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block main_content %}
|
||||
<h3>Ratings</h3>
|
||||
<table id="book_table" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
|
||||
<thead>
|
||||
<tr class="thead-light"><th>Name</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for rating in ratings %}
|
||||
<tr><td data-sort="{{rating.id}}"><a href="{{url_for('rating', id=rating.id )}}">{{rating.name}}</a></td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock main_content %}
|
||||
Reference in New Issue
Block a user