streamlined declarative mapping code, (re)added assoc. proxies, fixed bugs caused by the switch to declarative

This commit is contained in:
eclipse 2025-07-19 00:26:27 +02:00
parent 091c977f03
commit 3dd08fb4c4
3 changed files with 136 additions and 114 deletions

View File

@ -1,27 +1,28 @@
# code is based on output from `sqlacodegen --generator declarative sqlite:///path/to/the_works.sqlite` # code is built upon output from sqlacodegen
from typing import List, Optional
from sqlalchemy import Column, ForeignKey, Table, types
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from flask import url_for
import sys import sys
from typing import List, Optional
from sqlalchemy import ForeignKey, types
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy
from flask import url_for
class Base(DeclarativeBase): class Base(DeclarativeBase):
def _asdict(self): def asdict(self) -> dict:
d = {} d = {}
for col in self.__table__.c: for col in self.__table__.c:
if type(col.type) == types.BLOB: if isinstance(col.type, types.BLOB):
d[col.key] = "Blob (NULL)" if self.__getattribute__(col.key) == None else f"Blob ({sys.getsizeof(self.__getattribute__(col.key))} Bytes)" d[col.key] = "Blob (NULL)" if self.__getattribute__(col.key) is None else f"Blob ({sys.getsizeof(self.__getattribute__(col.key))} Bytes)"
else: else:
value = str(self.__getattribute__(col.key)) if isinstance(value := self.__getattribute__(col.key), str) and len(value) > 50:
d[col.key] = value[:50] + '...' if len(value) > 50 else value d[col.key] = value[:48] + '...'
else:
d[col.key] = value
return d return d
def __repr__(self): def __repr__(self) -> str:
return f"{type(self).__name__}({str(self._asdict())})" return f"{type(self).__name__}({str(self.asdict())})"
class Genre(Base): class Genre(Base):
@ -30,8 +31,8 @@ class Genre(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Genre: Mapped[str] Genre: Mapped[str]
text: Mapped[List['Text']] = relationship('Text', secondary='Text_Genre', back_populates='genre') texte: Mapped[List['Text_Genre']] = relationship(back_populates='genre')
werk: Mapped[List['Werk']] = relationship('Werk', secondary='Werk_Genre', back_populates='genre') werke: Mapped[List['Werk_Genre']] = relationship(back_populates='genre')
class Herausgeber(Base): class Herausgeber(Base):
@ -40,7 +41,7 @@ class Herausgeber(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Name: Mapped[str] Name: Mapped[str]
werk: Mapped[List['Werk']] = relationship('Werk', secondary='Werk_Herausgeber', back_populates='herausgeber') werke: Mapped[List['Werk_Herausgeber']] = relationship(back_populates='herausgeber')
class Pseudonym(Base): class Pseudonym(Base):
@ -49,7 +50,7 @@ class Pseudonym(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Pseudonym: Mapped[str] Pseudonym: Mapped[str]
veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship('Veroeffentlichung', back_populates='pseudonym') veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship(back_populates='pseudonym')
class Sprache(Base): class Sprache(Base):
@ -58,7 +59,7 @@ class Sprache(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Sprache: Mapped[str] Sprache: Mapped[str]
text: Mapped[List['Text']] = relationship('Text', back_populates='sprache') text: Mapped[List['Text']] = relationship(back_populates='sprache')
class Textform(Base): class Textform(Base):
@ -67,7 +68,7 @@ class Textform(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Textform: Mapped[str] Textform: Mapped[str]
text: Mapped[List['Text']] = relationship('Text', back_populates='textform') text: Mapped[List['Text']] = relationship(back_populates='textform')
class Titelbild(Base): class Titelbild(Base):
@ -83,10 +84,10 @@ class Titelbild(Base):
Thumbnail: Mapped[bytes] Thumbnail: Mapped[bytes]
sha256: Mapped[str] = mapped_column(unique=True) sha256: Mapped[str] = mapped_column(unique=True)
werk: Mapped[List['Werk']] = relationship('Werk', back_populates='titelbild') werk: Mapped[List['Werk']] = relationship(back_populates='titelbild')
def _asdict_with_urls(self): def asdict_with_urls(self):
tb = self._asdict() tb = self.asdict()
tb["Bild"] = url_for("titelbild.image", id=self.ID) tb["Bild"] = url_for("titelbild.image", id=self.ID)
tb["Thumbnail"] = url_for("titelbild.thumbnail", id=self.ID) tb["Thumbnail"] = url_for("titelbild.thumbnail", id=self.ID)
return tb return tb
@ -98,8 +99,8 @@ class Verlag(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Verlag: Mapped[str] Verlag: Mapped[str]
reihe: Mapped[List['Reihe']] = relationship('Reihe', back_populates='verlag') reihe: Mapped[List['Reihe']] = relationship(back_populates='verlag')
werk: Mapped[List['Werk']] = relationship('Werk', back_populates='verlag') werk: Mapped[List['Werk']] = relationship(back_populates='verlag')
class Werksform(Base): class Werksform(Base):
@ -108,7 +109,7 @@ class Werksform(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Werksform: Mapped[str] Werksform: Mapped[str]
werk: Mapped[List['Werk']] = relationship('Werk', back_populates='werksform') werk: Mapped[List['Werk']] = relationship(back_populates='werksform')
class Reihe(Base): class Reihe(Base):
@ -116,92 +117,117 @@ class Reihe(Base):
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Titel: Mapped[str] Titel: Mapped[str]
Verlag: Mapped[Optional[str]] = mapped_column('Verlag', ForeignKey('Verlag.ID'))
verlag: Mapped[Optional['Verlag']] = relationship('Verlag', back_populates='reihe') Verlag: Mapped[Optional[str]] = mapped_column(ForeignKey('Verlag.ID'))
text: Mapped[List['Text']] = relationship('Text', back_populates='reihe') verlag: Mapped['Verlag'] = relationship(back_populates='reihe')
werk: Mapped[List['Werk']] = relationship('Werk', back_populates='reihe')
text: Mapped[List['Text']] = relationship(back_populates='reihe')
werk: Mapped[List['Werk']] = relationship(back_populates='reihe')
class Text(Base): class Text(Base):
__tablename__ = 'Text' __tablename__ = 'Text'
# regular columns
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Titel: Mapped[str] Titel: Mapped[str]
Untertitel: Mapped[Optional[str]] Untertitel: Mapped[Optional[str]]
Reihe: Mapped[Optional[int]] = mapped_column('Reihe', ForeignKey('Reihe.ID'))
Textform: Mapped[Optional[int]] = mapped_column('Textform', ForeignKey('Textform.ID'))
Sprache: Mapped[Optional[int]] = mapped_column('Sprache', ForeignKey('Sprache.ID'))
genre: Mapped[List['Genre']] = relationship('Genre', secondary='Text_Genre', back_populates='text') # many-to-one
reihe: Mapped[Optional['Reihe']] = relationship('Reihe', back_populates='text') Reihe: Mapped[Optional[int]] = mapped_column(ForeignKey('Reihe.ID'))
sprache: Mapped[Optional['Sprache']] = relationship('Sprache', back_populates='text') reihe: Mapped[Optional["Reihe"]] = relationship(back_populates="text")
textform: Mapped[Optional['Textform']] = relationship('Textform', back_populates='text') Sprache: Mapped[int] = mapped_column(ForeignKey('Sprache.ID'))
veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship('Veroeffentlichung', back_populates='text') sprache: Mapped['Sprache'] = relationship(back_populates='text')
Textform: Mapped[int] = mapped_column(ForeignKey('Textform.ID'))
textform: Mapped['Textform'] = relationship(back_populates='text')
# one-to-many
veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship(back_populates='text')
# many-to-many
genres: Mapped[List['Text_Genre']] = relationship(back_populates='text', cascade="all, delete-orphan")
genre_ids: AssociationProxy[List["Genre"]] = association_proxy("genres", "Genre", creator=lambda genre_id: Text_Genre(Genre=genre_id))
class Werk(Base): class Werk(Base):
__tablename__ = 'Werk' __tablename__ = 'Werk'
# regular columns
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Titel: Mapped[str] Titel: Mapped[str]
Untertitel: Mapped[Optional[str]] Untertitel: Mapped[Optional[str]]
Werksform: Mapped[Optional[int]] = mapped_column('Werksform', ForeignKey('Werksform.ID'))
Verlag: Mapped[Optional[int]] = mapped_column('Verlag', ForeignKey('Verlag.ID'))
Reihe: Mapped[Optional[int]] = mapped_column('Reihe', ForeignKey('Reihe.ID'))
Reihennummer: Mapped[Optional[str]] Reihennummer: Mapped[Optional[str]]
Erscheinungsdatum: Mapped[Optional[str]] Erscheinungsdatum: Mapped[Optional[str]]
ISBN_13: Mapped[Optional[str]] ISBN_13: Mapped[Optional[str]]
ISBN_10: Mapped[Optional[str]] ISBN_10: Mapped[Optional[str]]
ISSN: Mapped[Optional[str]] ISSN: Mapped[Optional[str]]
Preis: Mapped[Optional[str]] Preis: Mapped[Optional[str]]
Titelbild: Mapped[Optional[int]] = mapped_column('Titelbild', ForeignKey('Titelbild.ID'))
Klappentext: Mapped[Optional[str]] Klappentext: Mapped[Optional[str]]
Anmerkungen: Mapped[Optional[str]] Anmerkungen: Mapped[Optional[str]]
genre: Mapped[List['Genre']] = relationship('Genre', secondary='Werk_Genre', back_populates='werk') # many-to-one
herausgeber: Mapped[List['Herausgeber']] = relationship('Herausgeber', secondary='Werk_Herausgeber', back_populates='werk') Reihe: Mapped[Optional[int]] = mapped_column(ForeignKey('Reihe.ID'))
reihe: Mapped[Optional['Reihe']] = relationship('Reihe', back_populates='werk') reihe: Mapped[Optional['Reihe']] = relationship(back_populates='werk')
titelbild: Mapped[Optional['Titelbild']] = relationship('Titelbild', back_populates='werk') Titelbild: Mapped[Optional[int]] = mapped_column(ForeignKey('Titelbild.ID'))
verlag: Mapped[Optional['Verlag']] = relationship('Verlag', back_populates='werk') titelbild: Mapped[Optional['Titelbild']] = relationship(back_populates='werk')
werksform: Mapped[Optional['Werksform']] = relationship('Werksform', back_populates='werk') Verlag: Mapped[Optional[int]] = mapped_column(ForeignKey('Verlag.ID'))
veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship('Veroeffentlichung', back_populates='werk') verlag: Mapped[Optional['Verlag']] = relationship(back_populates='werk')
Werksform: Mapped[int] = mapped_column(ForeignKey('Werksform.ID'))
werksform: Mapped['Werksform'] = relationship(back_populates='werk')
# one-to-many
veroeffentlichung: Mapped[List['Veroeffentlichung']] = relationship(back_populates='werk')
# many-to-many
genres: Mapped[List['Werk_Genre']] = relationship(back_populates='werk', cascade='all, delete-orphan')
genre_ids: AssociationProxy[List["Genre"]] = association_proxy("genres", "Genre", creator=lambda genre_id: Werk_Genre(Genre=genre_id))
herausgeber: Mapped[List['Werk_Herausgeber']] = relationship(back_populates='werk', cascade="all, delete-orphan")
herausgeber_ids: AssociationProxy[List['Herausgeber']] = association_proxy("herausgeber", "Herausgeber", creator=lambda hrsg_id: Werk_Herausgeber(Herausgeber=hrsg_id))
class Veroeffentlichung(Base): class Veroeffentlichung(Base):
__tablename__ = 'Veroeffentlichung' __tablename__ = 'Veroeffentlichung'
# regular columns
ID: Mapped[int] = mapped_column(primary_key=True) ID: Mapped[int] = mapped_column(primary_key=True)
Text: Mapped[int] = mapped_column('Text', ForeignKey('Text.ID'))
Werk: Mapped[int] = mapped_column('Werk', ForeignKey('Werk.ID'))
Pseudonym: Mapped[int] = mapped_column('Pseudonym', ForeignKey('Pseudonym.ID'))
AltTitel: Mapped[Optional[str]] AltTitel: Mapped[Optional[str]]
AltUntertitel: Mapped[Optional[str]] AltUntertitel: Mapped[Optional[str]]
pseudonym: Mapped['Pseudonym'] = relationship('Pseudonym', back_populates='veroeffentlichung') # many-to-one
text: Mapped['Text'] = relationship('Text', back_populates='veroeffentlichung') Pseudonym: Mapped[int] = mapped_column(ForeignKey('Pseudonym.ID'))
werk: Mapped['Werk'] = relationship('Werk', back_populates='veroeffentlichung') pseudonym: Mapped['Pseudonym'] = relationship(back_populates='veroeffentlichung')
Text: Mapped[int] = mapped_column(ForeignKey('Text.ID'))
text: Mapped['Text'] = relationship(back_populates='veroeffentlichung')
Werk: Mapped[int] = mapped_column(ForeignKey('Werk.ID'))
werk: Mapped['Werk'] = relationship(back_populates='veroeffentlichung')
t_Text_Genre = Table( class Text_Genre(Base):
'Text_Genre', __tablename__ = 'Text_Genre'
Base.metadata,
Column('Text', ForeignKey('Text.ID'), primary_key=True), Text: Mapped[int] = mapped_column(ForeignKey("Text.ID"), primary_key=True)
Column('Genre', ForeignKey('Genre.ID'), primary_key=True) Genre: Mapped[int] = mapped_column(ForeignKey("Genre.ID"), primary_key=True)
)
text: Mapped['Text'] = relationship(back_populates="genres")
genre: Mapped['Genre'] = relationship(back_populates="texte")
t_Werk_Genre = Table( class Werk_Genre(Base):
'Werk_Genre', __tablename__ = 'Werk_Genre'
Base.metadata,
Column('Werk', ForeignKey('Werk.ID'), primary_key=True), Werk: Mapped[int] = mapped_column(ForeignKey('Werk.ID'), primary_key=True)
Column('Genre', ForeignKey('Genre.ID'), primary_key=True) Genre: Mapped[int] = mapped_column(ForeignKey("Genre.ID"), primary_key=True)
)
werk: Mapped['Werk'] = relationship(back_populates="genres")
genre: Mapped['Genre'] = relationship(back_populates="werke")
t_Werk_Herausgeber = Table( class Werk_Herausgeber(Base):
'Werk_Herausgeber', __tablename__ = 'Werk_Herausgeber'
Base.metadata,
Column('Herausgeber', ForeignKey('Herausgeber.ID'), primary_key=True), Werk: Mapped[int] = mapped_column(ForeignKey('Werk.ID'), primary_key=True)
Column('Werk', ForeignKey('Werk.ID'), primary_key=True) Herausgeber: Mapped[int] = mapped_column(ForeignKey("Herausgeber.ID"), primary_key=True)
)
werk: Mapped['Werk'] = relationship(back_populates="herausgeber")
herausgeber: Mapped['Herausgeber'] = relationship(back_populates="werke")

View File

@ -1,7 +1,7 @@
from flask import Blueprint, render_template, request, redirect, flash, url_for from flask import Blueprint, render_template, request, redirect, flash, url_for
from sqlalchemy import select, insert, update, delete from sqlalchemy import select
from the_works.database import db from the_works.database import db
from the_works.models import Text, Reihe, Sprache, Textform, t_Text_Genre, Genre from the_works.models import Text, Reihe, Sprache, Textform, Genre
bp = Blueprint("text", __name__) bp = Blueprint("text", __name__)
@ -23,8 +23,7 @@ def all():
"tf_id": row.Text.Textform, "tf_id": row.Text.Textform,
"Sprache": row.Sprache.Sprache, "Sprache": row.Sprache.Sprache,
"s_id": row.Text.Sprache, "s_id": row.Text.Sprache,
"Genre_list": [tg.genre.Genre for tg in row.Text.text_genre], "Genre_list": [tg.genre.Genre for tg in row.Text.genres]
"g_id_list": row.Text.genres
}) })
return render_template("views/text.html", texte=texte) return render_template("views/text.html", texte=texte)
@ -35,15 +34,11 @@ def read(id):
return render_template("views/text_detail.html", text={"ID": 0}, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)), genres=db.session.scalars(select(Genre))) return render_template("views/text_detail.html", text={"ID": 0}, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)), genres=db.session.scalars(select(Genre)))
# all other ids -> update existing entry # all other ids -> update existing entry
t = db.session.get(Text, id) t = db.session.get(Text, id)
text = { if not t:
"ID": t.ID, raise ValueError(f"Text with ID {id} not found")
"Titel": t.Titel, text = t.asdict()
"Untertitel": t.Untertitel or "", text["Genres"] = t.genre_ids
"Reihe": t.Reihe or "",
"Textform": t.Textform,
"Sprache": t.Sprache,
"Genres": t.genres
}
return render_template("views/text_detail.html", text=text, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)), genres=db.session.scalars(select(Genre))) return render_template("views/text_detail.html", text=text, reihen=db.session.scalars(select(Reihe)), textformen=db.session.scalars(select(Textform)), sprachen=db.session.scalars(select(Sprache)), genres=db.session.scalars(select(Genre)))
@bp.route("/text/create", methods=["POST"]) @bp.route("/text/create", methods=["POST"])
@ -56,7 +51,7 @@ def create():
Sprache = request.form["form_Sprache"] Sprache = request.form["form_Sprache"]
) )
for g in request.form.getlist("form_Genres"): for g in request.form.getlist("form_Genres"):
text.genres.append(g) text.genre_ids.append(int(g))
db.session.add(text) db.session.add(text)
db.session.commit() db.session.commit()
flash("Eintrag erfolgreich hinzugefügt") flash("Eintrag erfolgreich hinzugefügt")
@ -75,11 +70,11 @@ def update(id):
text.Sprache = request.form["form_Sprache"] text.Sprache = request.form["form_Sprache"]
# update genre list by removing genres not in form selection and adding selected ones not currently in list # update genre list by removing genres not in form selection and adding selected ones not currently in list
form_set = set(map(lambda g: int(g), request.form.getlist("form_Genre"))) form_set = set(map(int, request.form.getlist("form_Genre")))
for g in set(text.genres) - form_set: for g in set(text.genre_ids) - form_set:
text.genres.remove(g) text.genre_ids.remove(g)
for g in form_set - set(text.genres): for g in form_set - set(text.genre_ids):
text.genres.append(g) text.genre_ids.append(g)
# commit changes # commit changes
db.session.commit() db.session.commit()

View File

@ -1,8 +1,7 @@
from flask import Blueprint, render_template, request, redirect, flash, url_for from flask import Blueprint, render_template, request, redirect, flash, url_for
from sqlalchemy import select, insert, update, delete from sqlalchemy import select
from the_works.database import db from the_works.database import db
from the_works.models import Werk, Reihe, Verlag, Werksform, t_Werk_Genre, Genre, t_Werk_Herausgeber, Herausgeber, Titelbild from the_works.models import Werk, Reihe, Verlag, Werksform, Genre, Herausgeber, Titelbild
from the_works.views import titelbild as tb
bp = Blueprint("werk", __name__) bp = Blueprint("werk", __name__)
@ -29,11 +28,11 @@ def all():
"ISSN": row.Werk.ISSN or "", "ISSN": row.Werk.ISSN or "",
"Preis": row.Werk.Preis or "", "Preis": row.Werk.Preis or "",
# "Titelbild": url_for("titelbild.thumbnail", id=row.Werk.Titelbild) if row.Werk.Titelbild else "", # "Titelbild": url_for("titelbild.thumbnail", id=row.Werk.Titelbild) if row.Werk.Titelbild else "",
"Titelbild": db.session.get(Titelbild, row.Werk.Titelbild)._asdict_with_urls() if row.Werk.Titelbild else "", "Titelbild": db.session.get(Titelbild, row.Werk.Titelbild).asdict_with_urls() if row.Werk.Titelbild else "",
"Klappentext": row.Werk.Klappentext or "", "Klappentext": row.Werk.Klappentext or "",
"Anmerkungen": row.Werk.Anmerkungen or "", "Anmerkungen": row.Werk.Anmerkungen or "",
"Herausgeber_list": [wh.herausgeber.Name for wh in row.Werk.werk_herausgeber], "Herausgeber_list": [wh.herausgeber.Name for wh in row.Werk.herausgeber],
"Genre_list": [wg.genre.Genre for wg in row.Werk.werk_genre], "Genre_list": [wg.genre.Genre for wg in row.Werk.genres],
}) })
return render_template("views/werk.html", werke=werke) return render_template("views/werk.html", werke=werke)
@ -41,17 +40,19 @@ def all():
@bp.route("/werk/read/<int:id>") @bp.route("/werk/read/<int:id>")
def read(id): def read(id):
# prepare Titelbilder as dict including URLs for thumbnail and full pic # prepare Titelbilder as dict including URLs for thumbnail and full pic
titelbilder = map(lambda t: t._asdict_with_urls(), db.session.scalars(select(Titelbild))) titelbilder = map(lambda t: t.asdict_with_urls(), db.session.scalars(select(Titelbild)))
# id of zero -> return empty data # id of zero -> return empty data
if id == 0: if id == 0:
return render_template("views/werk_detail.html", werk={"ID": 0, "Erscheinungsdatum": ""}, reihen=db.session.scalars(select(Reihe)), verlage=db.session.scalars(select(Verlag)), werksformen=db.session.scalars(select(Werksform)), genres=db.session.scalars(select(Genre)), hrsg=db.session.scalars(select(Herausgeber)), titelbilder=titelbilder) return render_template("views/werk_detail.html", werk={"ID": 0, "Erscheinungsdatum": ""}, reihen=db.session.scalars(select(Reihe)), verlage=db.session.scalars(select(Verlag)), werksformen=db.session.scalars(select(Werksform)), genres=db.session.scalars(select(Genre)), hrsg=db.session.scalars(select(Herausgeber)), titelbilder=titelbilder)
# all other ids -> read existing entry from DB and return as dict # all other ids -> read existing entry from DB and return as dict
werk = db.session.get(Werk, id) w = db.session.get(Werk, id)
if not werk: if not w:
raise ValueError(f"Werk with ID {id} not found") raise ValueError(f"Werk with ID {id} not found")
werk = werk._asdict() werk = w.asdict()
werk["Genres"] = w.genre_ids
werk["Herausgeber"] = w.herausgeber_ids
return render_template("views/werk_detail.html", werk=werk, reihen=db.session.scalars(select(Reihe)), verlage=db.session.scalars(select(Verlag)), werksformen=db.session.scalars(select(Werksform)), genres=db.session.scalars(select(Genre)), hrsg=db.session.scalars(select(Herausgeber)), titelbilder=titelbilder) return render_template("views/werk_detail.html", werk=werk, reihen=db.session.scalars(select(Reihe)), verlage=db.session.scalars(select(Verlag)), werksformen=db.session.scalars(select(Werksform)), genres=db.session.scalars(select(Genre)), hrsg=db.session.scalars(select(Herausgeber)), titelbilder=titelbilder)
@ -75,9 +76,9 @@ def create():
Anmerkungen = request.form["form_Anmerkungen"] or None Anmerkungen = request.form["form_Anmerkungen"] or None
) )
for g in request.form.getlist("form_Genre"): for g in request.form.getlist("form_Genre"):
werk.genres.append(g) werk.genre_ids.append(g)
for h in request.form.getlist("form_Herausgeber"): for h in request.form.getlist("form_Herausgeber"):
werk.herausgeber.append(h) werk.herausgeber_ids.append(h)
db.session.add(werk) db.session.add(werk)
db.session.commit() db.session.commit()
flash("Eintrag erfolgreich hinzugefügt") flash("Eintrag erfolgreich hinzugefügt")
@ -106,18 +107,18 @@ def update(id):
werk.Anmerkungen = request.form["form_Anmerkungen"] or None werk.Anmerkungen = request.form["form_Anmerkungen"] or None
# update associated values: Genre # update associated values: Genre
form_set = set(map(lambda g: int(g), request.form.getlist("form_Genre"))) form_set = set(map(int, request.form.getlist("form_Genre")))
for g in set(werk.genres) - form_set: for g in set(werk.genre_ids) - form_set:
werk.genres.remove(g) werk.genre_ids.remove(g)
for g in form_set - set(werk.genres): for g in form_set - set(werk.genre_ids):
werk.genres.append(g) werk.genre_ids.append(g)
# update associated values: Herausgeber # update associated values: Herausgeber
form_set = set(map(lambda h: int(h), request.form.getlist("form_Herausgeber"))) form_set = set(map(int, request.form.getlist("form_Herausgeber")))
for h in set(werk.herausgeber) - form_set: for h in set(werk.herausgeber_ids) - form_set:
werk.herausgeber.remove(h) werk.herausgeber_ids.remove(h)
for h in form_set - set(werk.herausgeber): for h in form_set - set(werk.herausgeber_ids):
werk.herausgeber.append(h) werk.herausgeber_ids.append(h)
# commit changes # commit changes
db.session.commit() db.session.commit()