PCv5/app/models/tag.py

57 lines
1.8 KiB
Python

from app import db
class TagInformation(db.Model):
"""Detailed information about tags, by dot-string tag identifier."""
__tablename__ = 'tag_information'
# The ID is the dot-string of the tag (eg. "calc.g35+e2")
id = db.Column(db.String(64), primary_key=True)
# List of uses. Note how we load tag information along individual tags, but
# we don't load uses unless the field is accessed.
uses = db.relationship('Tag', back_populates='tag', lazy='dynamic')
# Pretty name
pretty = db.Column(db.String(64))
# ... any other static information about tags
def __init__(self, id):
self.id = id
def category(self):
return self.id.split(".", 1)[0]
@staticmethod
def all_tags():
all_tags = {}
for ti in TagInformation.query.all():
ctgy = ti.category()
if ctgy not in all_tags:
all_tags[ctgy] = []
all_tags[ctgy].append(ti)
return all_tags
class Tag(db.Model):
"""Association between a Post and a dot-string tag identifier."""
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True)
# Tagged post
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), index=True)
post = db.relationship('Post', back_populates='tags', foreign_keys=post_id)
# Tag name. Note how we always load the information along the tag, but not
# the other way around.
tag_id = db.Column(db.String(64), db.ForeignKey('tag_information.id'),
index=True)
tag = db.relationship('TagInformation', back_populates='uses',
foreign_keys=tag_id, lazy='joined')
def __init__(self, post, tag):
self.post = post
if isinstance(tag, str):
tag = TagInformation.query.filter_by(id=tag).one()
self.tag = tag