diff --git a/BUGs b/BUGs index 6d1e905..5a30e7a 100644 --- a/BUGs +++ b/BUGs @@ -6,3 +6,5 @@ * show books, only shows first author * starting on series remove button. If we click a subbook, then remove series button needs to be clever (might need client-side validation / confirmation, eg. this is a subbook, you want to remove all of the sub books from the series?) * series: 112, book/sub-book ordering is broken + +** I have made a mess of the series_div stuff && its just complex, is it the best solution? diff --git a/README b/README index 162ba42..5cb9764 100644 --- a/README +++ b/README @@ -31,13 +31,13 @@ python3 main.py ### TODO: - when remove a Parent book from a series, what do we do? (remove all sub books from series too?) - - need to add book to sub_book - - need to delete 1 book from sub_book - - need to create loan + - need to add sub_book to parent book + ** okay, tried to overload /book/ .. too hard, need to overload /book if anything... so add_sub button needs to call different URL, and then maybe this would work? ( if parent, then show extra bit AND, if parent, add the sub_book_link when adding new book??? + - need to delete 1 sub_book from book - need to add books to loan (on loan page, and via a book search?) - need to delete book from loan - - need to delete loan - need to delete all classes (and watch for referential integrity) + * book, condition, covertype, genre, loan - show books on shelf list - show books to buy view / printable - with ORM: should I lazy load all books (ajax the 2nd->last pages in, or not use ORM, and do a quick db.execute()....) diff --git a/main.py b/main.py index 264e3c5..113b547 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,4 @@ -from flask import Flask, render_template, request +from flask import Flask, render_template, request, redirect from flask_sqlalchemy import SQLAlchemy from flask_marshmallow import Marshmallow from flask_bootstrap import Bootstrap @@ -71,7 +71,7 @@ class Book_Sub_Book_Link(db.Model): return "".format(self.book_id, self.sub_book_id, self.sub_book_num) class Book(db.Model): - id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True) + id = db.Column(db.Integer, db.Sequence('book_id_seq'), primary_key=True ) title = db.Column(db.String(100), unique=True, nullable=False) author = db.relationship('Author', secondary=book_author_link) publisher = db.Column(db.Integer, db.ForeignKey('publisher.id')) @@ -170,12 +170,13 @@ class BookForm(FlaskForm): owned = SelectField( 'owned', choices=[(c.id, c.name) for c in Owned.query.order_by('id')] ) covertype = SelectField( 'covertype', choices=[(c.id, c.name) for c in Covertype.query.order_by('id')] ) condition = SelectField( 'condition', choices=[(c.id, c.name) for c in Condition.query.order_by('id')] ) - year_published = IntegerField('Year Published:', [validators.NumberRange(min=1900, max=2100)] ) + year_published = IntegerField('Year Published:', validators=[validators.DataRequired(), validators.NumberRange(min=1900, max=2100)] ) rating = SelectField( 'rating', choices=[(c.id, c.name) for c in Rating.query.order_by('id')] ) notes = TextAreaField('Notes:') blurb = TextAreaField('Blurb:') submit = SubmitField('Save' ) delete = SubmitField('Delete' ) + add_sub = SubmitField('Add Sub-Book' ) ################################# helper functions ################################### @@ -337,17 +338,69 @@ def subbooks_for_book(id): return render_template("subbooks_for_book.html", sub_books=sub_book, s2=subs ) + +### +### Need a route to /book then incorporate the below: +### +# elif 'add_sub' in request.form: +# alert="danger" +# message="Sorry, Adding a sub-book unsupported at present" +# book = Book.query.get(id) +# parent=request.form['add_sub_parent_id'] +# parent_book = Book.query.get(parent) +################################################################################ +# /book -> GET/POST -> creates a new book and when created, takes you back to +# /books (or /book/ -- if you added a sub-book of parent_id +################################################################################ +@app.route("/book", methods=["GET", "POST"]) +def new_book(): + form = BookForm(request.form) + author_list = GetAuthors() + genre_list = GetGenres() + if 'title' not in request.form: + return render_template("book.html", page_title='Create new Book', b=None, books=None, book_form=form, author_list=author_list, genre_list=genre_list, alert="", message="", poss_series_list=ListOfSeriesWithMissingBooks() ) + elif form.validate(): + book_authors=[] + for el in request.form: + if 'author-' in el: + book_authors.append( Author.query.get( request.form[el] ) ) + book_genres = [] + for genre in genre_list: + if "genre-{}".format(genre.id) in request.form: + book_genres.append( genre ) + book = Book( title=request.form["title"], owned=request.form['owned'], covertype=request.form['covertype'], condition=request.form['condition'], publisher=request.form['publisher'], year_published=request.form['year_published'], rating=request.form['rating'], notes=request.form['notes'], blurb=request.form['blurb'], genre=book_genres, author=book_authors ) + db.session.add(book) + db.session.commit() + st.SetMessage( "Created new Book ({})".format(book.title) ) + cnt=1 + for field in request.form: + if 'bsl-book_id-' in field and field != 'bsl-book_id-NUM': + cnt=int(re.findall( '\d+', field )[0]) + sql="insert into book_series_link (book_id, series_id, book_num) values ( {}, {}, {} )".format( book.id, request.form['bsl-series_id-{}'.format(cnt)], request.form['bsl-book_num-{}'.format(cnt)]) + db.engine.execute( sql ) + cnt=cnt+1 + return redirect( '/book/{}'.format(book.id) ) + else: + alert="danger" + message="Failed to create Book" + for field in form.errors: + message = "{}
{}={}".format( message, field, form.errors[field] ) + print( "Failed to create book: {}".format(message) ) + return render_template("book.html", page_title='Create new Book', b=None, books=None, book_form=form, author_list=author_list, genre_list=genre_list, alert=alert, message=message, poss_series_list=ListOfSeriesWithMissingBooks() ) + + @app.route("/book/", methods=["GET", "POST"]) def book(id): alert="success" message="" book_form = BookForm(request.form) - book = Book.query.get(id) if request.method == 'POST': if 'delete' in request.form: + book = Book.query.get(id) alert="danger" message="Sorry, Deleting unsupported at present" elif book_form.validate(): + book = Book.query.get(id) book.title = request.form['title'] book.owned = request.form['owned'] book.covertype = request.form['covertype'] @@ -377,7 +430,6 @@ def book(id): for field in request.form: if 'bsl-book_id-' in field and field != 'bsl-book_id-NUM': cnt=int(re.findall( '\d+', field )[0]) - print( "found: bsl-{} book_id == {}, series_id={}, book_num={}".format(cnt, request.form['bsl-book_id-{}'.format(cnt)], request.form['bsl-series_id-{}'.format(cnt)], request.form['bsl-book_num-{}'.format(cnt)]) ) sql="insert into book_series_link (book_id, series_id, book_num) values ( {}, {}, {} )".format( request.form['bsl-book_id-{}'.format(cnt)], request.form['bsl-series_id-{}'.format(cnt)], request.form['bsl-book_num-{}'.format(cnt)]) db.engine.execute( sql ) cnt=cnt+1 @@ -388,16 +440,19 @@ def book(id): message="Successfully Updated Book (id={})".format(id) else: alert="danger" - print( book_form) - message="Err... Failed to update Book (id={})".format(id) + message="Failed to update Book (id={})".format(id) + for field in book_form.errors: + message = "{}
{}={}".format( message, field, book_form.errors[field] ) + book = Book.query.get(id) else: + book = Book.query.get(id) book_form=BookForm(obj=book) author_list = GetAuthors() genre_list = GetGenres() book_s = book_schema.dump(book) - return render_template("book.html", b=book, books=book_s, book_form=book_form, author_list=author_list, genre_list=genre_list, alert=alert, message=message, n=book_form.notes, poss_series_list=ListOfSeriesWithMissingBooks() ) + return render_template("book.html", b=book, books=book_s, book_form=book_form, author_list=author_list, genre_list=genre_list, alert=alert, message=message, poss_series_list=ListOfSeriesWithMissingBooks() ) def GetCount( what, where ): st="select count(id) as count from book where " diff --git a/templates/base.html b/templates/base.html index 53abec6..6ea45e7 100644 --- a/templates/base.html +++ b/templates/base.html @@ -24,7 +24,7 @@