Trying to reproduce (in the simplest way possible) Maciej Cegłowski's http://pinboard.in; instead of Links and Tags, I have Books and Tags. Every Book can be tagged with any number of Tag's, and a Tag is associated with many Book's.
class Book(db.Model): __tablename__ = 'books' book_id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(120), unique=True) auth = db.Column(db.String(120), unique=True) comment = db.Column(db.String(120), unique=True) date_read = db.Column(db.DateTime) era = db.Column(db.String(36)) url = db.Column(db.String(120)) notable = db.Column(db.String(1)) tagged = db.relationship('Tag', secondary=assoc, backref=db.backref('thebooks',lazy='dynamic')) class Tag(db.Model): __tablename__ = 'tags' tag_id = db.Column(db.Integer, primary_key=True) tag_name = db.Column(db.String(120)) def construct_dict(query): books_dict = {} for each in query: # query is {<Book object>, <Tag object>} in the style of assoc table - therefore, must make a dictionary bc of the multiple tags per Book object book_data = books_dict.setdefault(each[0].book_id, {'bookkey':each[0], 'tagkey':[]}) # query is a list like this {index-book_id, {<Book object>}, {<Tag object #1>, <Tag object #2>, ... }} book_data['tagkey'].append(each[1]) return books_dict @app.route('/query') def query(): query = db.session.query(Book, Tag).outerjoin('tagged') # query to get all books and their tags books_dict = construct_dict(query) return render_template("query.html", query=query, books_dict=books_dict) This is where I start to get a bit lost; that is, in constructing the proper logic to handle what I'm trying to do, which is described in detail below.
{% for i in books_dict %} <a href="{{books_dict[i].bookkey.url}}" target="_blank">{{books_dict[i].bookkey.title}}</a> {% for i in books_dict[i].tagkey %} # tagkey is a list of Tag objects; for each Book's tagkey, print each Object's tag_name <a href="/tag/{{i.tag_name}}" class="tag-link">{{i.tag_name}}</a> {% endfor %} <a href="" class="edit">edit</a> # eventually, edit link will display the form <form method="add_tag_to_book"> {% for j in books_dict[i].tagkey %} <input type="text" name="tag" value="{{j.tag_name}}" /> {% endfor %} <input type="submit" value="save"> </form> {% endfor %} For any book, a user (just me for now) should be able to:
UPDATEtheassoctable such that a new association between a Book instance and Tag instance is created;- or, if the Tag does not exist, create a new Tag instance (and, of course,
UPDATEtheassoctable so that the Book instance is properly associated with the new Tag)
I think this task is complicated for me because I'm still struggling with scope in Jinja loops. I realize, however, I need to do something like this:
grab input from user; check to see if
tag_namealready exists in__tablename__ = "tags"if
tag_namealready exists, then grab itstag_idas well as thebook_idfor the Book instance AND add row toassoctable (i.e., book_id|tag_id)if
tag_namedoes not exist, create newTag()instance and then perform STEP 2