diff --git a/README b/README index f32d446..36f7953 100644 --- a/README +++ b/README @@ -1,12 +1,15 @@ ## TODO: get all this inside a docker container and use compose to do the whole set (pg, flask, ?) # flask -> python web server # sqlalchemy -> provides db-agnostic python objects of db content (and more) -## flask-sqlachemy combines/wraps this to provide a db.* set of objects based on the 'app' that flask creates +# flask-sqlachemy combines/wraps this to provide a db.* set of objects based on the 'app' that flask creates +# marshmallow-sqlachemy provides a way to create a 'schema' of your class, then serialize an object to it -# --user sticks python libs in ~/.local/[bin|lib|share] -##LEARN: supposedly could use virtualenv instead? +# install needed binaries (maybe I could have done this instead of pip below too -- when I docker this shit, sort it out?) sudo apt install python3-psycopg2 libpq-dev -pip3 install --user flask sqlalchemy flask-sqlalchemy + +##LEARN: supposedly could use virtualenv instead of pip3 install --user? +# --user sticks python libs in ~/.local/[bin|lib|share] +pip3 install --user flask sqlalchemy flask-sqlalchemy flask-marshmallow SQLAlchemy-serializer # run the web server by: python3 main.py diff --git a/main.py b/main.py index 3ec39aa..5be35b5 100644 --- a/main.py +++ b/main.py @@ -2,13 +2,14 @@ from flask import Flask from flask import render_template from flask import request from flask_sqlalchemy import SQLAlchemy -import logging +from flask_marshmallow import Marshmallow DB_URL = 'postgresql+psycopg2://ddp:NWNlfa01@127.0.0.1:5432/library' app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = DB_URL app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) +ma = Marshmallow(app) ####################################### CLASSES / DB model ####################################### book_author_link = db.Table('book_author_link', db.Model.metadata, @@ -19,22 +20,51 @@ book_author_link = db.Table('book_author_link', db.Model.metadata, class Book(db.Model): id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True) title = db.Column(db.String(100), unique=True, nullable=False) + year_published = db.Column(db.Integer) + rating = db.Column(db.String(20)) + condition = db.Column(db.String(20)) + owned = db.Column(db.String(20)) + covertype = db.Column(db.String(20)) + notes = db.Column(db.Text) + blurb = db.Column(db.Text) + created = db.Column(db.Date) + modified = db.Column(db.Date) + author = db.relationship('Author', secondary=book_author_link) def __repr__(self): - return "".format(self.title, self.id, self.author, self.id ) -# return "".format(self.title, self.id, self.author, self.author.firstnames ) + return "".format(self.title, self.id, self.author ) class Author(db.Model): id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True) firstnames = db.Column(db.String(50), unique=False, nullable=False) surname = db.Column(db.String(30), unique=False, nullable=False) -# book = db.relationship('Book', secondary=book_author_link ) + book = db.relationship('Book', secondary=book_author_link ) def __repr__(self): - return "".format(self.firstnames, self.surname ) -# return "".format(self.firstnames, self.surname, self.book) + return "".format(self.firstnames, self.surname, self.book) + + + +### setup serializer schemas, to make returning books/authors easier +class AuthorSchema(ma.SQLAlchemyAutoSchema): + class Meta: + model = Author + include_relationships = True + load_instance = True + +class BookSchema(ma.SQLAlchemyAutoSchema): + author = ma.Nested(AuthorSchema, many=True) + class Meta: + model = Book + include_relationships = True + load_instance = True + +book_schema = BookSchema() +author_schema = AuthorSchema() + +print( book_schema ) ####################################### ROUTES ####################################### @app.route("/books", methods=["GET"]) @@ -47,8 +77,8 @@ def books(): @app.route("/book/", methods=["GET"]) def book(id): book = Book.query.get(id) - print( book ) - return render_template("books.html", books=book ) + book_s = book_schema.dump(book) + return render_template("books.html", books=book_s ) @app.route("/authors", methods=["GET"]) def author(): diff --git a/templates/books.html b/templates/books.html index 6f73b31..61c260d 100644 --- a/templates/books.html +++ b/templates/books.html @@ -8,37 +8,50 @@ + -
- - -
+ {% if books is not mapping %}

All Books

- {% if books is iterable %} - + - {% for book in books %} - + + + + + + + + {% endfor %}
TitleAuthor
TitleAuthorPublisherConditionOwnedCovertype
{{book.title}}{{ book.author[0]['surname'] }}, {{ book.author[0]['firstnames'] }}
{{book.title}}{{ book.author[0]['surname'] }}, {{book.author[0]['firstnames']}}{{ book.publisher}} + {% if book.condition == "Good" %} + + {% elif book.condition == "Average" %} + + {% else %} + + {% endif %} + {{ book.owned}}{{ book.covertype}}
{% else %} +

Book

{{books.title}}, {{ books.author[0]['surname'] }}, {{books.author[0]['firstnames']}}

{% endif %} +