switched handling of all simple tables (ID and one other column) to generic class-based view and template
This commit is contained in:
parent
f0a162461d
commit
f4b0ec6045
@ -1,12 +1,10 @@
|
||||
from flask import Flask
|
||||
|
||||
# this import is not strictly necessary but it forces pipreqs-to include dotenv when generating `requirements.txt`
|
||||
import dotenv
|
||||
|
||||
import dotenv # this import is not strictly necessary but it forces pipreqs-to include dotenv when generating `requirements.txt`
|
||||
from the_works.database import init_db
|
||||
from the_works.views import home, text, werk, verlag, sprache, textform, werksform, genre, pseudonym, reihe, herausgeber, veroeffentlichung, titelbild
|
||||
from the_works.models import CLASSVIEWABLE_MODELS
|
||||
from the_works.views import home, text, werk, reihe, veroeffentlichung, titelbild
|
||||
from the_works.views.view import VIEWS, ViewAll, ViewCreate, ViewUpdate, ViewDelete
|
||||
|
||||
#from flask_debugtoolbar import DebugToolbarExtension
|
||||
|
||||
def create_app(config=None):
|
||||
app = Flask(__name__)
|
||||
@ -24,23 +22,28 @@ def create_app(config=None):
|
||||
|
||||
# some #DEBUG output
|
||||
print(f"Current Environment: {app.config['ENV'] if 'ENV' in app.config.keys() else 'ENV is not set'}") #DEBUG
|
||||
print(app.config) #DEBUG
|
||||
|
||||
# initialize database
|
||||
init_db(app)
|
||||
|
||||
# register blueprints
|
||||
app.register_blueprint(genre.bp)
|
||||
app.register_blueprint(herausgeber.bp)
|
||||
# add url rules for class-based views
|
||||
for m in CLASSVIEWABLE_MODELS:
|
||||
for v in VIEWS:
|
||||
route = f"/{m["name"]}/{v['name']}{v.get('route_params', '')}"
|
||||
class_ = globals()[f"View{v['name'].capitalize()}"]
|
||||
view_name = f"{m["name"]}.{v['name']}"
|
||||
kwargs = {key: value for key, value in m.items() if key is not "name"}
|
||||
app.add_url_rule(
|
||||
route,
|
||||
endpoint=view_name,
|
||||
view_func=class_.as_view(view_name, m["name"], **kwargs)
|
||||
)
|
||||
|
||||
# register blueprints for remaining views
|
||||
app.register_blueprint(home.bp)
|
||||
app.register_blueprint(pseudonym.bp)
|
||||
app.register_blueprint(reihe.bp)
|
||||
app.register_blueprint(sprache.bp)
|
||||
app.register_blueprint(text.bp)
|
||||
app.register_blueprint(textform.bp)
|
||||
app.register_blueprint(verlag.bp)
|
||||
app.register_blueprint(werk.bp)
|
||||
app.register_blueprint(werksform.bp)
|
||||
app.register_blueprint(veroeffentlichung.bp)
|
||||
app.register_blueprint(titelbild.bp)
|
||||
|
||||
|
||||
@ -1,11 +1,22 @@
|
||||
import sys
|
||||
from typing import List, Optional
|
||||
from sqlalchemy import ForeignKey, types, CheckConstraint
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, validates
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
||||
from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy
|
||||
from flask import url_for
|
||||
|
||||
|
||||
CLASSVIEWABLE_MODELS = [
|
||||
{"name": "genre", "title": "Genres"},
|
||||
{"name": "herausgeber", "title": "Herausgeber", "column": "Name"},
|
||||
{"name": "pseudonym", "title": "Pseudonyme"},
|
||||
{"name": "sprache", "title": "Sprachen"},
|
||||
{"name": "textform", "title": "Textformen"},
|
||||
{"name": "verlag", "title": "Verlage"},
|
||||
{"name": "werksform", "title": "Werksformen"}
|
||||
]
|
||||
|
||||
"""Base class for the_works' data models"""
|
||||
class Base(DeclarativeBase):
|
||||
def asdict(self) -> dict:
|
||||
d = {}
|
||||
@ -23,6 +34,8 @@ class Base(DeclarativeBase):
|
||||
return f"{type(self).__name__}({str(self.asdict())})"
|
||||
|
||||
|
||||
# Classes for models with a single column (plus ID) which can be handled by the generic class-based view
|
||||
|
||||
class Genre(Base):
|
||||
__tablename__ = 'Genre'
|
||||
|
||||
@ -69,6 +82,40 @@ class Textform(Base):
|
||||
text: Mapped[List['Text']] = relationship(back_populates='textform')
|
||||
|
||||
|
||||
class Verlag(Base):
|
||||
__tablename__ = 'Verlag'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Verlag: Mapped[str] = mapped_column(CheckConstraint('Verlag <> ""', name='VerlagNotEmptyConstraint'), unique=True)
|
||||
|
||||
reihe: Mapped[List['Reihe']] = relationship(back_populates='verlag')
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='verlag')
|
||||
|
||||
|
||||
class Werksform(Base):
|
||||
__tablename__ = 'Werksform'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Werksform: Mapped[str] = mapped_column(CheckConstraint('Werksform <> ""', name='WerksformNotEmptyConstraint'), unique=True)
|
||||
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='werksform')
|
||||
|
||||
|
||||
# Classes that have more than one column and need dedicated view functions
|
||||
|
||||
class Reihe(Base):
|
||||
__tablename__ = 'Reihe'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Titel: Mapped[str] = mapped_column(CheckConstraint('Titel <> ""', name='ReihentitelNotEmptyConstraint'))
|
||||
|
||||
Verlag: Mapped[Optional[str]] = mapped_column(ForeignKey('Verlag.ID'))
|
||||
verlag: Mapped['Verlag'] = relationship(back_populates='reihe')
|
||||
|
||||
text: Mapped[List['Text']] = relationship(back_populates='reihe')
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='reihe')
|
||||
|
||||
|
||||
class Titelbild(Base):
|
||||
__tablename__ = 'Titelbild'
|
||||
|
||||
@ -91,38 +138,6 @@ class Titelbild(Base):
|
||||
return tb
|
||||
|
||||
|
||||
class Verlag(Base):
|
||||
__tablename__ = 'Verlag'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Verlag: Mapped[str] = mapped_column(CheckConstraint('Verlag <> ""', name='VerlagNotEmptyConstraint'), unique=True)
|
||||
|
||||
reihe: Mapped[List['Reihe']] = relationship(back_populates='verlag')
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='verlag')
|
||||
|
||||
|
||||
class Werksform(Base):
|
||||
__tablename__ = 'Werksform'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Werksform: Mapped[str] = mapped_column(CheckConstraint('Werksform <> ""', name='WerksformNotEmptyConstraint'), unique=True)
|
||||
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='werksform')
|
||||
|
||||
|
||||
class Reihe(Base):
|
||||
__tablename__ = 'Reihe'
|
||||
|
||||
ID: Mapped[int] = mapped_column(primary_key=True)
|
||||
Titel: Mapped[str] = mapped_column(CheckConstraint('Titel <> ""', name='ReihentitelNotEmptyConstraint'))
|
||||
|
||||
Verlag: Mapped[Optional[str]] = mapped_column(ForeignKey('Verlag.ID'))
|
||||
verlag: Mapped['Verlag'] = relationship(back_populates='reihe')
|
||||
|
||||
text: Mapped[List['Text']] = relationship(back_populates='reihe')
|
||||
werk: Mapped[List['Werk']] = relationship(back_populates='reihe')
|
||||
|
||||
|
||||
class Text(Base):
|
||||
__tablename__ = 'Text'
|
||||
|
||||
@ -147,7 +162,6 @@ class Text(Base):
|
||||
genre_ids: AssociationProxy[List["Genre"]] = association_proxy("genres", "Genre", creator=lambda genre_id: Text_Genre(Genre=genre_id))
|
||||
|
||||
|
||||
|
||||
class Werk(Base):
|
||||
__tablename__ = 'Werk'
|
||||
|
||||
@ -201,6 +215,8 @@ class Veroeffentlichung(Base):
|
||||
werk: Mapped['Werk'] = relationship(back_populates='veroeffentlichung')
|
||||
|
||||
|
||||
# Additional tables for many-to-many-relationships within the DB
|
||||
|
||||
class Text_Genre(Base):
|
||||
__tablename__ = 'Text_Genre'
|
||||
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
from the_works.database import db
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from flask import url_for
|
||||
import sys
|
||||
|
||||
# add method to sqlalchemy.orm.decl_api.Model
|
||||
def _asdict(self):
|
||||
d = {}
|
||||
for col in self.__table__.c:
|
||||
if type(col.type) == db.types.BLOB:
|
||||
d[col.key] = "Blob (NULL)" if self.__getattribute__(col.key) == None else f"Blob ({sys.getsizeof(self.__getattribute__(col.key))} Bytes)"
|
||||
else:
|
||||
value = str(self.__getattribute__(col.key))
|
||||
d[col.key] = value[:50] + '...' if len(value) > 50 else value
|
||||
return d
|
||||
db.Model._asdict = _asdict
|
||||
|
||||
# override repr() method from sqlalchemy.orm.decl_api.Model
|
||||
def __repr__(self):
|
||||
return f"{type(self).__name__}({str(self._asdict())})"
|
||||
db.Model.__repr__ = __repr__
|
||||
|
||||
class Text(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Text']
|
||||
reihe = relationship("Reihe", back_populates="text")
|
||||
textform = relationship("Textform", back_populates="text")
|
||||
sprache = relationship("Sprache", back_populates="text")
|
||||
veroeffentlichung = relationship("Veroeffentlichung", back_populates="text")
|
||||
text_genre = relationship("Text_Genre", back_populates="text", cascade="save-update, merge, delete, delete-orphan")
|
||||
genres = association_proxy("text_genre", "Genre")
|
||||
|
||||
class Werk(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Werk']
|
||||
reihe = relationship("Reihe", back_populates="werk")
|
||||
verlag = relationship("Verlag", back_populates="werk")
|
||||
werksform = relationship("Werksform", back_populates="werk")
|
||||
veroeffentlichung = relationship("Veroeffentlichung", back_populates="werk")
|
||||
werk_genre = relationship("Werk_Genre", back_populates="werk", cascade="save-update, merge, delete, delete-orphan")
|
||||
# titelbild = relationship("Titelbild", back_populates="werk", cascade="all, delete-orphan", single_parent=True)
|
||||
titelbild = relationship("Titelbild", back_populates="werk")
|
||||
genres = association_proxy("werk_genre", "Genre")
|
||||
werk_herausgeber = relationship("Werk_Herausgeber", back_populates="werk", cascade="save-update, merge, delete, delete-orphan")
|
||||
herausgeber = association_proxy("werk_herausgeber", "Herausgeber")
|
||||
|
||||
class Veroeffentlichung(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Veroeffentlichung']
|
||||
text = relationship("Text", back_populates="veroeffentlichung")
|
||||
werk = relationship("Werk", back_populates="veroeffentlichung")
|
||||
pseudonym = relationship("Pseudonym", back_populates="veroeffentlichung")
|
||||
|
||||
class Reihe(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Reihe']
|
||||
text = relationship("Text", back_populates="reihe")
|
||||
werk = relationship("Werk", back_populates="reihe")
|
||||
verlag = relationship("Verlag", back_populates="reihe")
|
||||
|
||||
class Verlag(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Verlag']
|
||||
werk = relationship("Werk", back_populates="verlag")
|
||||
reihe = relationship("Reihe", back_populates="verlag")
|
||||
|
||||
class Sprache(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Sprache']
|
||||
text = relationship("Text", back_populates="sprache")
|
||||
|
||||
class Textform(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Textform']
|
||||
text = relationship("Text", back_populates="textform")
|
||||
|
||||
class Werksform(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Werksform']
|
||||
werk = relationship("Werk", back_populates="werksform")
|
||||
|
||||
class Genre(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Genre']
|
||||
text_genre = relationship("Text_Genre", back_populates="genre")
|
||||
werk_genre = relationship("Werk_Genre", back_populates="genre")
|
||||
|
||||
class Pseudonym(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Pseudonym']
|
||||
veroeffentlichung = relationship("Veroeffentlichung", back_populates="pseudonym")
|
||||
|
||||
class Herausgeber(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Herausgeber']
|
||||
werk_herausgeber = relationship("Werk_Herausgeber", back_populates="herausgeber")
|
||||
|
||||
class Titelbild(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Titelbild']
|
||||
werk = relationship("Werk", back_populates="titelbild")
|
||||
|
||||
def _asdict_with_urls(self):
|
||||
tb = self._asdict()
|
||||
tb["Bild"] = url_for("titelbild.image", id=self.ID)
|
||||
tb["Thumbnail"] = url_for("titelbild.thumbnail", id=self.ID)
|
||||
return tb
|
||||
|
||||
class Text_Genre(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Text_Genre']
|
||||
text = relationship("Text", back_populates="text_genre")
|
||||
genre = relationship("Genre", back_populates="text_genre")
|
||||
|
||||
def __init__(self, genre: int):
|
||||
self.Genre = genre
|
||||
|
||||
class Werk_Genre(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Werk_Genre']
|
||||
werk = relationship("Werk", back_populates="werk_genre")
|
||||
genre = relationship("Genre", back_populates="werk_genre")
|
||||
|
||||
def __init__(self, genre: int):
|
||||
self.Genre = genre
|
||||
|
||||
class Werk_Herausgeber(db.Model):
|
||||
__table__ = db.Model.metadata.tables['Werk_Herausgeber']
|
||||
werk = relationship("Werk", back_populates="werk_herausgeber")
|
||||
herausgeber = relationship("Herausgeber", back_populates="werk_herausgeber")
|
||||
|
||||
def __init__(self, hrsg: int):
|
||||
self.Herausgeber = hrsg
|
||||
|
||||
@ -1,125 +0,0 @@
|
||||
# this is the verbatim output of `sqlacodegen --generator tables sqlite:///path/to/the_works.sqlite`, run inside project root
|
||||
|
||||
from sqlalchemy import Column, ForeignKey, Integer, LargeBinary, MetaData, Table, Text
|
||||
|
||||
metadata = MetaData()
|
||||
|
||||
|
||||
t_Genre = Table(
|
||||
'Genre', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Genre', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Herausgeber = Table(
|
||||
'Herausgeber', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Name', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Pseudonym = Table(
|
||||
'Pseudonym', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Pseudonym', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Sprache = Table(
|
||||
'Sprache', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Sprache', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Textform = Table(
|
||||
'Textform', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Textform', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Titelbild = Table(
|
||||
'Titelbild', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Mimetype', Text, nullable=False),
|
||||
Column('Dateiname', Text, nullable=False),
|
||||
Column('Dateigroesse', Integer, nullable=False),
|
||||
Column('Breite', Integer, nullable=False),
|
||||
Column('Hoehe', Integer, nullable=False),
|
||||
Column('Bild', LargeBinary, nullable=False),
|
||||
Column('Thumbnail', LargeBinary, nullable=False),
|
||||
Column('sha256', Text, nullable=False, unique=True)
|
||||
)
|
||||
|
||||
t_Verlag = Table(
|
||||
'Verlag', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Verlag', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Werksform = Table(
|
||||
'Werksform', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Werksform', Text, nullable=False)
|
||||
)
|
||||
|
||||
t_Reihe = Table(
|
||||
'Reihe', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Titel', Text, nullable=False),
|
||||
Column('Verlag', ForeignKey('Verlag.ID'))
|
||||
)
|
||||
|
||||
t_Text = Table(
|
||||
'Text', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Titel', Text, nullable=False),
|
||||
Column('Untertitel', Text),
|
||||
Column('Reihe', ForeignKey('Reihe.ID')),
|
||||
Column('Textform', ForeignKey('Textform.ID')),
|
||||
Column('Sprache', ForeignKey('Sprache.ID'))
|
||||
)
|
||||
|
||||
t_Werk = Table(
|
||||
'Werk', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Titel', Text, nullable=False),
|
||||
Column('Untertitel', Text),
|
||||
Column('Werksform', ForeignKey('Werksform.ID')),
|
||||
Column('Verlag', ForeignKey('Verlag.ID')),
|
||||
Column('Reihe', ForeignKey('Reihe.ID')),
|
||||
Column('Reihennummer', Text),
|
||||
Column('Erscheinungsdatum', Text),
|
||||
Column('ISBN_13', Text),
|
||||
Column('ISBN_10', Text),
|
||||
Column('ISSN', Text),
|
||||
Column('Preis', Text),
|
||||
Column('Titelbild', ForeignKey('Titelbild.ID')),
|
||||
Column('Klappentext', Text),
|
||||
Column('Anmerkungen', Text)
|
||||
)
|
||||
|
||||
t_Text_Genre = Table(
|
||||
'Text_Genre', metadata,
|
||||
Column('Text', ForeignKey('Text.ID'), primary_key=True),
|
||||
Column('Genre', ForeignKey('Genre.ID'), primary_key=True)
|
||||
)
|
||||
|
||||
t_Veroeffentlichung = Table(
|
||||
'Veroeffentlichung', metadata,
|
||||
Column('ID', Integer, primary_key=True),
|
||||
Column('Text', ForeignKey('Text.ID'), nullable=False),
|
||||
Column('Werk', ForeignKey('Werk.ID'), nullable=False),
|
||||
Column('AltTitel', Text),
|
||||
Column('AltUntertitel', Text),
|
||||
Column('Pseudonym', ForeignKey('Pseudonym.ID'), nullable=False)
|
||||
)
|
||||
|
||||
t_Werk_Genre = Table(
|
||||
'Werk_Genre', metadata,
|
||||
Column('Werk', ForeignKey('Werk.ID'), primary_key=True),
|
||||
Column('Genre', ForeignKey('Genre.ID'), primary_key=True)
|
||||
)
|
||||
|
||||
t_Werk_Herausgeber = Table(
|
||||
'Werk_Herausgeber', metadata,
|
||||
Column('Herausgeber', ForeignKey('Herausgeber.ID'), primary_key=True),
|
||||
Column('Werk', ForeignKey('Werk.ID'), primary_key=True)
|
||||
)
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Genres{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Genres{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="genre-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Genre</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for genre in genres %}
|
||||
<tr id="genre-{{ genre['ID'] }}">
|
||||
<td title="Genre">{{ genre["Genre"] }}</td>
|
||||
<td class="action action-update" data-id="{{ genre['ID'] }}" data-genre="{{genre['Genre'] }}"><a href="#" title="Genre bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ genre['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('genre.delete', id=genre['ID']) }}" title="Genre löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="genre-modal">
|
||||
<article>
|
||||
<form id="genre_detail_form" method="post" action="{{ url_for('genre.create') }}">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" formmethod="dialog" formnovalidate rel="prev"></button>
|
||||
<h1 id="dialog-heading" />
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Genre</span>
|
||||
<input id="form_Genre" name="form_Genre" aria-Label="Genre" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('genre.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("genre-table");
|
||||
initCreateButton("genre-table", "Genre hinzufügen …");
|
||||
initModal("genre-modal", "form_Genre", ["Neues Genre", "Genre bearbeiten"], ["{{ url_for('genre.create') }}", "{{ url_for('genre.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Herausgeber:innen{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Herausgeber:innen{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="herausgeber-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for hrsg in herausgeber %}
|
||||
<tr id="hrsg-{{ hrsg['ID'] }}">
|
||||
<td title="Name">{{ hrsg["Name"] }}</td>
|
||||
<td class="action action-update" data-id="{{ hrsg['ID'] }}" data-name="{{hrsg['Name'] }}"><a href="#" title="Herausgeber:in bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ hrsg['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('herausgeber.delete', id=hrsg['ID']) }}" title="Herausgeber:in löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="herausgeber-modal">
|
||||
<article>
|
||||
<form id="herausgeber_detail_form" method="dialog">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Name</span>
|
||||
<input id="form_Name" name="form_Name" aria-Label="Name" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('herausgeber.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("herausgeber-table");
|
||||
initCreateButton("herausgeber-table", "Herausgeber:in hinzufügen …");
|
||||
initModal("herausgeber-modal", "form_Name", ["Neue:r Herausgeber:in", "Herausgeber:in bearbeiten"], ["{{ url_for('herausgeber.create') }}", "{{ url_for('herausgeber.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Pseudonyme{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Pseudonyme{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="pseudonym-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pseudonym</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for pseudonym in pseudonyme %}
|
||||
<tr id="pseudonym-{{ pseudonym['ID'] }}">
|
||||
<td title="Pseudonym">{{ pseudonym["Pseudonym"] }}</td>
|
||||
<td class="action action-update" data-id="{{ pseudonym['ID'] }}" data-pseudonym="{{pseudonym['Pseudonym'] }}"><a href="#" title="Pseudonym bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ pseudonym['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('pseudonym.delete', id=pseudonym['ID']) }}" title="Pseudonym löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="pseudonym-modal">
|
||||
<article>
|
||||
<form id="pseudonym_detail_form" method="dialog">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Pseudonym</span>
|
||||
<input id="form_Pseudonym" name="form_Pseudonym" aria-Label="Pseudonym" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('pseudonym.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("pseudonym-table");
|
||||
initCreateButton("pseudonym-table", "Pseudonym hinzufügen …");
|
||||
initModal("pseudonym-modal", "form_Pseudonym", ["Neues Pseudonym", "Pseudonym bearbeiten"], ["{{ url_for('pseudonym.create') }}", "{{ url_for('pseudonym.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
84
the_works/templates/views/simple_view.html
Normal file
84
the_works/templates/views/simple_view.html
Normal file
@ -0,0 +1,84 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}" />
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}{{ title }}{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="{{ model }}-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ model | capitalize }}</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in items %}
|
||||
<tr id="{{ model }}-{{ item['ID'] }}">
|
||||
<td title="{{ model | capitalize }}">{{ item[column] }}</td>
|
||||
<td class="action action-update" data-id="{{ item['ID'] }}" data-{{ column }}="{{item[column] }}">
|
||||
<a href="#" title="{{ model | capitalize }} bearbeiten">
|
||||
<svg viewbox="0 0 24 24"><use href="#update" /></svg>
|
||||
</a>
|
||||
</td>
|
||||
<td id="delete-{{ item['ID'] }}" class="action">
|
||||
<a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for(model+'.delete', id=item['ID']) }}" title="{{ model | capitalize }} löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="{{ model }}-modal">
|
||||
<article>
|
||||
<form id="{{ model }}_detail_form" method="post" action="{{ url_for(model + '.create') }}">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" formmethod="dialog" formnovalidate rel="prev"></button>
|
||||
<h1 id="dialog-heading"></h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">{{ model | capitalize }}</span>
|
||||
<input id="form_{{ column | capitalize }}" name="form_{{ column | capitalize }}" aria-Label="{{ column | capitalize }}" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for(model + '.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("{{ model }}-table");
|
||||
initCreateButton("{{ model }}-table", "{{ model | capitalize }} hinzufügen …");
|
||||
initModal(
|
||||
"{{ model }}-modal",
|
||||
"form_{{ column | capitalize }}",
|
||||
["Neues {{ model | capitalize }}", "{{ model | capitalize }} bearbeiten"],
|
||||
[
|
||||
"{{ url_for(model + '.create') }}",
|
||||
"{{ url_for(model + '.update', id=-1) }}",
|
||||
]
|
||||
);
|
||||
};
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Sprachen{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Sprachen{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="sprache-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Sprachen</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sprache in sprachen %}
|
||||
<tr id="sprache-{{ sprache['ID'] }}">
|
||||
<td title="Sprache">{{ sprache["Sprache"] }}</td>
|
||||
<td class="action action-update" data-id="{{ sprache['ID'] }}" data-sprache="{{sprache['Sprache'] }}"><a href="#" title="Sprache bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ sprache['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('sprache.delete', id=sprache['ID']) }}" title="Sprache löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="sprache-modal">
|
||||
<article>
|
||||
<form id="sprache_detail_form" method="dialog">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Sprache</span>
|
||||
<input id="form_Sprache" name="form_Sprache" aria-Label="Sprache" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('sprache.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("sprache-table");
|
||||
initCreateButton("sprache-table", "Sprache hinzufügen …");
|
||||
initModal("sprache-modal", "form_Sprache", ["Neue Sprache", "Sprache bearbeiten"], ["{{ url_for('sprache.create') }}", "{{ url_for('sprache.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Textformen{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Textformen{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="textform-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Textformen</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for textform in textformen %}
|
||||
<tr id="textform-{{ textform['ID'] }}">
|
||||
<td title="Textform">{{ textform["Textform"] }}</td>
|
||||
<td class="action action-update" data-id="{{ textform['ID'] }}" data-textform="{{textform['Textform'] }}"><a href="#" title="Textform bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ textform['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('textform.delete', id=textform['ID']) }}" title="Textform löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="textform-modal">
|
||||
<article>
|
||||
<form id="textform_detail_form" method="dialog">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Textform</span>
|
||||
<input id="form_Textform" name="form_Textform" aria-Label="Textform" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('textform.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("textform-table");
|
||||
initCreateButton("textform-table", "Textform hinzufügen …");
|
||||
initModal("textform-modal", "form_Textform", ["Neue Textform", "Textform bearbeiten"], ["{{ url_for('textform.create') }}", "{{ url_for('textform.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Verlage{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Verlage{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="verlag-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Verlag</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for verlag in verlage %}
|
||||
<tr id="verlag-{{ verlag['ID'] }}">
|
||||
<td title="Verlag">{{ verlag["Verlag"] }}</td>
|
||||
<td class="action action-update" data-id="{{ verlag['ID'] }}" data-verlag="{{verlag['Verlag'] }}"><a href="#" title="Verlag bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ verlag['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('verlag.delete', id=verlag['ID']) }}" title="Verlag löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="verlag-modal">
|
||||
<article>
|
||||
<form id="verlag_detail_form" method="dialog">
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Name des Verlags</span>
|
||||
<input id="form_Verlag" name="form_Verlag" aria-Label="Verlagsname" required autofocus />
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="{{ url_for('verlag.create') }}">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("verlag-table");
|
||||
initCreateButton("verlag-table", "Verlag hinzufügen …");
|
||||
initModal("verlag-modal", "form_Verlag", ["Neuer Verlag", "Verlag bearbeiten"], ["{{ url_for('verlag.create') }}", "{{ url_for('verlag.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,70 +0,0 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Werksformen{% endblock title %}
|
||||
|
||||
{% block head %}
|
||||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/datatables.css') }}">
|
||||
{% endblock head %}
|
||||
|
||||
{% block heading %}Werksformen{% endblock heading %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "_icons.svg" %}
|
||||
|
||||
<table id="werksform-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Werksformen</th>
|
||||
<th colspan="2">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for werksform in werksformen %}
|
||||
<tr id="werksform-{{ werksform['ID'] }}">
|
||||
<td title="Werksform">{{ werksform["Werksform"] }}</td>
|
||||
<td class="action action-update" data-id="{{ werksform['ID'] }}" data-werksform="{{werksform['Werksform'] }}"><a href="#" title="Werksform bearbeiten"><svg viewbox="0 0 24 24"><use href="#update" /></svg></a></td>
|
||||
<td id="delete-{{ werksform['ID'] }}" class="action"><a onclick="return confirm('Eintrag wirklich löschen?');" href="{{ url_for('werksform.delete', id=werksform['ID']) }}" title="Werksform löschen"><svg viewbox="0 0 24 24"><use href="#delete" /></svg></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<dialog aria-labelledby="dialog-heading" id="werksform-modal">
|
||||
<article>
|
||||
<form id="werksform_detail_form" method="dialog" >
|
||||
<header>
|
||||
<button class="modal-close" aria-label="close" rel="prev" formnovalidate></button>
|
||||
<h1 id="dialog-heading">#</h1>
|
||||
</header>
|
||||
|
||||
<fieldset>
|
||||
<article>
|
||||
<label>
|
||||
<span class="required">Werksform</span>
|
||||
<input id="form_Werksform" name="form_Werksform" aria-Label="Werksform" required autofocus/>
|
||||
</label>
|
||||
</article>
|
||||
</fieldset>
|
||||
|
||||
<footer class="grid">
|
||||
<button id="form_submit" type="submit" formmethod="post" formaction="#">OK</button>
|
||||
<button class="secondary" aria-label="close" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||||
</footer>
|
||||
</form>
|
||||
</article>
|
||||
</dialog>
|
||||
{% endblock content %}
|
||||
|
||||
{% block script %}
|
||||
<script src="{{ url_for('static', filename='js/datatables.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/init_dt.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/modal.js') }}"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
initDataTable("werksform-table");
|
||||
initCreateButton("werksform-table", "Werksform hinzufügen …");
|
||||
initModal("werksform-modal", "form_Werksform", ["Neue Werksform", "Werksform bearbeiten"], ["{{ url_for('werksform.create') }}", "{{ url_for('werksform.update', id=-1) }}"]);
|
||||
}
|
||||
</script>
|
||||
{% endblock script %}
|
||||
@ -1,38 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Genre
|
||||
|
||||
bp = Blueprint("genre", __name__)
|
||||
|
||||
@bp.route("/genre")
|
||||
@bp.route("/genre/all")
|
||||
def all():
|
||||
return render_template("views/genre.html", genres=db.session.scalars(select(Genre)))
|
||||
|
||||
@bp.route("/genre/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Genre(Genre=request.form.get("form_Genre", default=None)))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("genre.all"), code=303)
|
||||
|
||||
@bp.route("/genre/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
genre = db.session.get(Genre, id)
|
||||
if genre:
|
||||
genre.Genre = request.form.get("form_Genre", default=None)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
else:
|
||||
flash("Fehler beim Ändern: Eintrag nicht vorhanden")
|
||||
return redirect(url_for("genre.all"), code=303)
|
||||
|
||||
@bp.route("/genre/delete/<int:id>")
|
||||
def delete(id):
|
||||
genre = db.session.get(Genre, id)
|
||||
db.session.delete(genre)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("genre.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Herausgeber
|
||||
|
||||
bp = Blueprint("herausgeber", __name__)
|
||||
|
||||
@bp.route("/herausgeber")
|
||||
@bp.route("/herausgeber/all")
|
||||
def all():
|
||||
return render_template("views/herausgeber.html", herausgeber=db.session.scalars(select(Herausgeber)))
|
||||
|
||||
@bp.route("/herausgeber/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Herausgeber(Name = request.form["form_Name"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("herausgeber.all"), code=303)
|
||||
|
||||
@bp.route("/herausgeber/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
herausgeber = db.session.get(Herausgeber, id)
|
||||
herausgeber.Name = request.form["form_Name"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("herausgeber.all"), code=303)
|
||||
|
||||
@bp.route("/herausgeber/delete/<int:id>")
|
||||
def delete(id):
|
||||
herausgeber = db.session.get(Herausgeber, id)
|
||||
db.session.delete(herausgeber)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("herausgeber.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Pseudonym
|
||||
|
||||
bp = Blueprint("pseudonym", __name__)
|
||||
|
||||
@bp.route("/pseudonym")
|
||||
@bp.route("/pseudonym/all")
|
||||
def all():
|
||||
return render_template("views/pseudonym.html", pseudonyme=db.session.scalars(select(Pseudonym)))
|
||||
|
||||
@bp.route("/pseudonym/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Pseudonym(Pseudonym = request.form["form_Pseudonym"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("pseudonym.all"), code=303)
|
||||
|
||||
@bp.route("/pseudonym/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
pseudonym = db.session.get(Pseudonym, id)
|
||||
pseudonym.Pseudonym = request.form["form_Pseudonym"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("pseudonym.all"), code=303)
|
||||
|
||||
@bp.route("/pseudonym/delete/<int:id>")
|
||||
def delete(id):
|
||||
pseudonym = db.session.get(Pseudonym, id)
|
||||
db.session.delete(pseudonym)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("pseudonym.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Sprache
|
||||
|
||||
bp = Blueprint("sprache", __name__)
|
||||
|
||||
@bp.route("/sprache")
|
||||
@bp.route("/sprache/all")
|
||||
def all():
|
||||
return render_template("views/sprache.html", sprachen=db.session.scalars(select(Sprache)))
|
||||
|
||||
@bp.route("/sprache/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Sprache(Sprache = request.form["form_Sprache"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("sprache.all"), code=303)
|
||||
|
||||
@bp.route("/sprache/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
sprache = db.session.get(Sprache, id)
|
||||
sprache.Sprache = request.form["form_Sprache"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("sprache.all"), code=303)
|
||||
|
||||
@bp.route("/sprache/delete/<int:id>")
|
||||
def delete(id):
|
||||
sprache = db.session.get(Sprache, id)
|
||||
db.session.delete(sprache)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("sprache.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Textform
|
||||
|
||||
bp = Blueprint("textform", __name__)
|
||||
|
||||
@bp.route("/textform")
|
||||
@bp.route("/textform/all")
|
||||
def all():
|
||||
return render_template("views/textform.html", textformen=db.session.scalars(select(Textform)))
|
||||
|
||||
@bp.route("/textform/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Textform(Textform = request.form["form_Textform"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("textform.all"), code=303)
|
||||
|
||||
@bp.route("/textform/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
textform = db.session.get(Textform, id)
|
||||
textform.Textform = request.form["form_Textform"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("textform.all"), code=303)
|
||||
|
||||
@bp.route("/textform/delete/<int:id>")
|
||||
def delete(id):
|
||||
textform = db.session.get(Textform, id)
|
||||
db.session.delete(textform)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("textform.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Verlag
|
||||
|
||||
bp = Blueprint("verlag", __name__)
|
||||
|
||||
@bp.route("/verlag")
|
||||
@bp.route("/verlag/all")
|
||||
def all():
|
||||
return render_template("views/verlag.html", verlage=db.session.scalars(select(Verlag)))
|
||||
|
||||
@bp.route("/verlag/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Verlag(Verlag = request.form["form_Verlag"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("verlag.all"), code=303)
|
||||
|
||||
@bp.route("/verlag/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
verlag = db.session.get(Verlag, id)
|
||||
verlag.Verlag = request.form["form_Verlag"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("verlag.all"), code=303)
|
||||
|
||||
@bp.route("/verlag/delete/<int:id>")
|
||||
def delete(id):
|
||||
verlag = db.session.get(Verlag, id)
|
||||
db.session.delete(verlag)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("verlag.all"))
|
||||
|
||||
65
the_works/views/view.py
Normal file
65
the_works/views/view.py
Normal file
@ -0,0 +1,65 @@
|
||||
from abc import ABC
|
||||
from flask import render_template, request, redirect, flash, url_for
|
||||
from flask.views import View
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
|
||||
VIEWS = [
|
||||
{"name": "all"},
|
||||
{"name": "create"},
|
||||
{"name": "update", "route_params": "/<int:id>"},
|
||||
{"name": "delete", "route_params": "/<int:id>"}
|
||||
]
|
||||
|
||||
|
||||
class ViewBase(View, ABC):
|
||||
|
||||
init_every_request = False
|
||||
|
||||
def __init__(self, model, **kwargs):
|
||||
self.model = model.lower()
|
||||
self.Model = self.model.capitalize()
|
||||
module_ = __import__("the_works.models", fromlist=[self.Model])
|
||||
self.class_ = getattr(module_, self.Model)
|
||||
self.title = kwargs["title"]
|
||||
self.column = kwargs.get("column", self.Model)
|
||||
|
||||
|
||||
class ViewAll(ViewBase):
|
||||
methods = ["GET"]
|
||||
def dispatch_request(self):
|
||||
return render_template(f"views/classviewable.html", items=db.session.scalars(select(self.class_)), title=self.title, model=self.model, column=self.column)
|
||||
|
||||
|
||||
class ViewCreate(ViewBase):
|
||||
methods = ["POST"]
|
||||
def dispatch_request(self):
|
||||
kwargs = {self.column: request.form.get(f"form_{self.column}", default=None)}
|
||||
db.session.add(self.class_(**kwargs))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for(f"{self.model}.all"), code=303)
|
||||
|
||||
|
||||
class ViewUpdate(ViewBase):
|
||||
methods = ["POST"]
|
||||
def dispatch_request(self, id: int):
|
||||
record = db.session.get(self.class_, id)
|
||||
if record:
|
||||
setattr(record, self.column, request.form.get(f"form_{self.column}", default=None))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
else:
|
||||
flash("Fehler beim Ändern: Eintrag nicht vorhanden")
|
||||
return redirect(url_for(f"{self.model}.all"), code=303)
|
||||
|
||||
|
||||
class ViewDelete(ViewBase):
|
||||
methods = ["GET"]
|
||||
def dispatch_request(self, id: int):
|
||||
record = db.session.get(self.class_, id)
|
||||
db.session.delete(record)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for(f"{self.model}.all"))
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
from flask import Blueprint, render_template, request, redirect, flash, url_for
|
||||
from sqlalchemy import select
|
||||
from the_works.database import db
|
||||
from the_works.models import Werksform
|
||||
|
||||
bp = Blueprint("werksform", __name__)
|
||||
|
||||
@bp.route("/werksform")
|
||||
@bp.route("/werksform/all")
|
||||
def all():
|
||||
return render_template("views/werksform.html", werksformen=db.session.scalars(select(Werksform)))
|
||||
|
||||
@bp.route("/werksform/create", methods=["POST"])
|
||||
def create():
|
||||
db.session.add(Werksform(Werksform = request.form["form_Werksform"]))
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich hinzugefügt")
|
||||
return redirect(url_for("werksform.all"), code=303)
|
||||
|
||||
@bp.route("/werksform/update/<int:id>", methods=["POST"])
|
||||
def update(id):
|
||||
werksform = db.session.get(Werksform, id)
|
||||
werksform.Werksform = request.form["form_Werksform"]
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich geändert")
|
||||
return redirect(url_for("werksform.all"), code=303)
|
||||
|
||||
@bp.route("/werksform/delete/<int:id>")
|
||||
def delete(id):
|
||||
werksform = db.session.get(Werksform, id)
|
||||
db.session.delete(werksform)
|
||||
db.session.commit()
|
||||
flash("Eintrag erfolgreich gelöscht")
|
||||
return redirect(url_for("werksform.all"))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user