Implemented basic models
This commit is contained in:
parent
6bceef1664
commit
3ba6099976
16 changed files with 257 additions and 24 deletions
1
.envrc
1
.envrc
|
|
@ -1 +1,2 @@
|
||||||
use flake
|
use flake
|
||||||
|
export FLASK_APP=app
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
||||||
.direnv
|
.direnv
|
||||||
|
__pycache__
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,9 @@ from flask import Flask
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
# Configuration of application, see configuration.py, choose one and uncomment.
|
|
||||||
# app.config.from_object('configuration.ProductionConfig')
|
|
||||||
app.config.from_object("app.configuration.DevelopmentConfig")
|
app.config.from_object("app.configuration.DevelopmentConfig")
|
||||||
# app.config.from_object('configuration.TestingConfig')
|
|
||||||
|
|
||||||
db = SQLAlchemy(app) # flask-sqlalchemy
|
db = SQLAlchemy(app) # flask-sqlalchemy
|
||||||
|
|
||||||
from app import views, models
|
from app import views, models
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -2,8 +2,7 @@ class Config(object):
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
TESTING = False
|
TESTING = False
|
||||||
SQLALCHEMY_DATABASE_URI = "sqlite:///application.db"
|
SQLALCHEMY_DATABASE_URI = "sqlite:///application.db"
|
||||||
BOOTSTRAP_FONTAWESOME = True
|
SECRET_KEY = "yessir"
|
||||||
SECRET_KEY = "MINHACHAVESECRETA"
|
|
||||||
CSRF_ENABLED = True
|
CSRF_ENABLED = True
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||||
|
|
||||||
|
|
@ -15,6 +14,5 @@ class Config(object):
|
||||||
class DevelopmentConfig(Config):
|
class DevelopmentConfig(Config):
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
|
|
||||||
class TestingConfig(Config):
|
class TestingConfig(Config):
|
||||||
TESTING = True
|
TESTING = True
|
||||||
|
|
|
||||||
30
app/forms.py
Normal file
30
app/forms.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import StringField, SubmitField, IntegerField, HiddenField
|
||||||
|
from wtforms.validators import DataRequired
|
||||||
|
|
||||||
|
class NewWishlist(FlaskForm):
|
||||||
|
title = StringField("Title:", validators=[DataRequired()])
|
||||||
|
description = StringField("Description:", validators=[DataRequired()])
|
||||||
|
submit = SubmitField("Submit")
|
||||||
|
|
||||||
|
# Each submit needs a different page fot it to work on the same page.
|
||||||
|
class DeleteWishlist(FlaskForm):
|
||||||
|
wl_del_submit = SubmitField("Delete wishlist")
|
||||||
|
|
||||||
|
class EditWishlistInfo(FlaskForm):
|
||||||
|
title = StringField("Title:", validators=[DataRequired()])
|
||||||
|
description = StringField("Description:", validators=[DataRequired()])
|
||||||
|
wl_edit_submit = SubmitField("Submit")
|
||||||
|
|
||||||
|
class ResetWishlistUrls(FlaskForm):
|
||||||
|
wl_reset_submit = SubmitField("Reset urls")
|
||||||
|
|
||||||
|
class NewItem(FlaskForm):
|
||||||
|
title = StringField("Title:", validators=[DataRequired()])
|
||||||
|
description = StringField("Description:", validators=[DataRequired()])
|
||||||
|
price = IntegerField("Price:", validators=[DataRequired()])
|
||||||
|
it_new_submit = SubmitField("Submit")
|
||||||
|
|
||||||
|
class DeleteItem(FlaskForm):
|
||||||
|
index = HiddenField()
|
||||||
|
it_del_submit = SubmitField("Delete item")
|
||||||
|
|
@ -1,20 +1,35 @@
|
||||||
|
from typing import List
|
||||||
from app import db
|
from app import db
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column, RelationshipProperty
|
||||||
|
from sqlalchemy import Uuid, String, Text
|
||||||
|
from uuid import uuid4 as uuid
|
||||||
|
|
||||||
class Item(db.Model):
|
class Item(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
def __init__(self, title: str, description: str, price: float):
|
||||||
title = db.Column(db.String(250))
|
self.wishlist_id = None
|
||||||
description = db.Column(db.Text)
|
self.title = title
|
||||||
price = db.Column(db.Float)
|
self.description = description
|
||||||
bought = db.Column(db.Boolean)
|
self.price = price
|
||||||
|
self.bought = False
|
||||||
|
|
||||||
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
|
wishlist_id: Mapped[int | None] = mapped_column(db.ForeignKey("wishlist.id"))
|
||||||
|
title: Mapped[str] = mapped_column(db.String(250))
|
||||||
|
description: Mapped[str] = mapped_column(db.Text)
|
||||||
|
price: Mapped[float] = mapped_column()
|
||||||
|
bought: Mapped[bool] = mapped_column()
|
||||||
|
|
||||||
class Wishlist(db.Model):
|
class Wishlist(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
def __init__(self, title: str, description: str):
|
||||||
editId = db.Column(db.Uuid)
|
self.editId = uuid()
|
||||||
viewId = db.Column(db.Uuid)
|
self.viewId = uuid()
|
||||||
title = db.Column(db.String(250))
|
self.title = title
|
||||||
description = db.Column(db.Text)
|
self.description = description
|
||||||
|
|
||||||
itemIds = db.Column(db.ARRAY(db.Integer)) # Store item IDs as an array
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
items = db.relationship("Item", primaryjoin="Wishlist.itemIds")
|
editId: Mapped[Uuid] = mapped_column(Uuid)
|
||||||
|
viewId: Mapped[Uuid] = mapped_column(Uuid)
|
||||||
|
title: Mapped[str] = mapped_column(String(250))
|
||||||
|
description: Mapped[str] = mapped_column(Text)
|
||||||
|
|
||||||
|
items: Mapped[List["Item"]] = db.relationship("Item", backref="post")
|
||||||
69
app/templates/edit.html
Normal file
69
app/templates/edit.html
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
{% set cpath = url_for("edit", id=wishlist.editId) %}
|
||||||
|
|
||||||
|
<h1>Change name</h1>
|
||||||
|
<form action="{{ cpath }}" method="POST">
|
||||||
|
{{ form_wl_editinfo.hidden_tag() }}
|
||||||
|
|
||||||
|
{{ form_wl_editinfo.title.label }}
|
||||||
|
{{ form_wl_editinfo.title() }}
|
||||||
|
|
||||||
|
{{ form_wl_editinfo.description.label }}
|
||||||
|
{{ form_wl_editinfo.description() }}
|
||||||
|
|
||||||
|
{{ form_wl_editinfo.wl_edit_submit() }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<h1>Reset urls</h1>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
View: {{ wishlist.viewId }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Edit: {{ wishlist.editId }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
<form action="{{ cpath }}" method="POST">
|
||||||
|
{{ form_wl_reseturls.hidden_tag() }}
|
||||||
|
{{ form_wl_reseturls.wl_reset_submit() }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<h1>Delete wishlist</h1>
|
||||||
|
<form action="{{ cpath }}" method="POST">
|
||||||
|
{{ form_wl_delete.hidden_tag() }}
|
||||||
|
{{ form_wl_delete.wl_del_submit() }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<h1>New item</h1>
|
||||||
|
<form action="{{ cpath }}" method="POST">
|
||||||
|
{{ form_it_new.hidden_tag() }}
|
||||||
|
|
||||||
|
{{ form_it_new.title.label }}
|
||||||
|
{{ form_it_new.title() }}
|
||||||
|
|
||||||
|
{{ form_it_new.description.label }}
|
||||||
|
{{ form_it_new.description() }}
|
||||||
|
|
||||||
|
{{ form_it_new.price.label }}
|
||||||
|
{{ form_it_new.price() }}
|
||||||
|
|
||||||
|
{{ form_it_new.it_new_submit() }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<h1>Delete items</h1>
|
||||||
|
<ul>
|
||||||
|
{% for value in wishlist.items %}
|
||||||
|
<li>
|
||||||
|
<form action="{{ cpath }}" method="POST">
|
||||||
|
{{ form_it_delete.hidden_tag() }}
|
||||||
|
{{ form_it_delete.index(value=loop.index) }}
|
||||||
|
{{ form_it_delete.it_del_submit() }}
|
||||||
|
</form>
|
||||||
|
{{ value.title }}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
11
app/templates/new.html
Normal file
11
app/templates/new.html
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<form action="/new" method="POST">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
|
{{ form.title.label }}
|
||||||
|
{{ form.title() }}
|
||||||
|
|
||||||
|
{{ form.description.label }}
|
||||||
|
{{ form.description() }}
|
||||||
|
|
||||||
|
{{ form.submit() }}
|
||||||
|
</form>
|
||||||
10
app/templates/view.html
Normal file
10
app/templates/view.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h1>{{wishlist.title}}</h1>
|
||||||
|
<sub>{{wishlist.description}}</sub>
|
||||||
|
|
||||||
|
<a href="{{url_for('edit', id=wishlist.editId)}}">edit</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for item in wishlist.items %}
|
||||||
|
<li><input type=checkbox {{ "checked" if item.bought }} {{ item.title }}: {{ item.description }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
105
app/views.py
105
app/views.py
|
|
@ -1,7 +1,108 @@
|
||||||
from flask import url_for, redirect, render_template, flash, g, session
|
from flask import url_for, redirect, render_template
|
||||||
from app import app
|
from app import app, db
|
||||||
|
from app.forms import (
|
||||||
|
NewWishlist,
|
||||||
|
DeleteWishlist,
|
||||||
|
EditWishlistInfo,
|
||||||
|
ResetWishlistUrls,
|
||||||
|
NewItem,
|
||||||
|
DeleteItem,
|
||||||
|
)
|
||||||
|
from app.models import Wishlist, Item
|
||||||
|
from uuid import UUID, uuid4 as uuid
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index():
|
def index():
|
||||||
return "hello"
|
return "hello"
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/new", methods=["GET", "POST"])
|
||||||
|
def new():
|
||||||
|
form = NewWishlist()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
wishlist = Wishlist(form.title.data, form.description.data)
|
||||||
|
db.session.add(wishlist)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("view", id=wishlist.viewId))
|
||||||
|
|
||||||
|
return render_template("new.html", form=form)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/edit/<id>", methods=["GET", "POST"])
|
||||||
|
def edit(id: str):
|
||||||
|
wishlist: Wishlist = db.one_or_404(
|
||||||
|
db.select(Wishlist).filter_by(editId=UUID(id)),
|
||||||
|
description="Failed to get wishlist. Are you sure this is the correct url?",
|
||||||
|
)
|
||||||
|
|
||||||
|
form_wl_delete = DeleteWishlist()
|
||||||
|
form_wl_editinfo = EditWishlistInfo()
|
||||||
|
form_wl_reseturls = ResetWishlistUrls()
|
||||||
|
form_it_new = NewItem()
|
||||||
|
form_it_delete = DeleteItem()
|
||||||
|
|
||||||
|
# Each submit needs a different page fot it to work on the same page.
|
||||||
|
if form_wl_delete.validate_on_submit() and form_wl_delete.wl_del_submit.data:
|
||||||
|
for i in wishlist.items:
|
||||||
|
db.session.delete(i)
|
||||||
|
db.session.delete(wishlist)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("index"))
|
||||||
|
elif form_wl_editinfo.validate_on_submit() and form_wl_editinfo.wl_edit_submit.data:
|
||||||
|
wishlist.title = form_wl_editinfo.title.data
|
||||||
|
wishlist.description = form_wl_editinfo.description.data
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("edit", id=id))
|
||||||
|
elif form_wl_reseturls.validate_on_submit() and form_wl_reseturls.wl_reset_submit.data:
|
||||||
|
wishlist.editId = uuid()
|
||||||
|
wishlist.viewId = uuid()
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("edit", id=wishlist.editId))
|
||||||
|
elif form_it_new.validate_on_submit() and form_it_new.it_new_submit.data:
|
||||||
|
f = form_it_new
|
||||||
|
item = Item(
|
||||||
|
f.title.data,
|
||||||
|
f.description.data,
|
||||||
|
f.price.data
|
||||||
|
)
|
||||||
|
wishlist.items.append(item)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("edit", id=id))
|
||||||
|
elif form_it_delete.validate_on_submit() and form_it_delete.it_del_submit.data:
|
||||||
|
print(form_it_delete.index.data)
|
||||||
|
data = form_it_delete.index.data
|
||||||
|
i = int(data) if data != None else 0
|
||||||
|
if i + 1 > len(wishlist.items):
|
||||||
|
return "Invalid item to delete", 400
|
||||||
|
|
||||||
|
wishlist.items.remove(wishlist.items[i])
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return redirect(url_for("edit", id=id))
|
||||||
|
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"edit.html",
|
||||||
|
wishlist=wishlist,
|
||||||
|
form_wl_delete=form_wl_delete,
|
||||||
|
form_wl_editinfo=form_wl_editinfo,
|
||||||
|
form_wl_reseturls=form_wl_reseturls,
|
||||||
|
form_it_new=form_it_new,
|
||||||
|
form_it_delete=form_it_delete,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/view/<id>")
|
||||||
|
def view(id: str):
|
||||||
|
wishlist = db.one_or_404(
|
||||||
|
db.select(Wishlist).filter_by(viewId=UUID(id)),
|
||||||
|
description="Failed to get wishlist. Are you sure this is the correct url?",
|
||||||
|
)
|
||||||
|
|
||||||
|
return render_template("view.html", wishlist=wishlist)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
{
|
{
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
(pkgs.python3.withPackages
|
(pkgs.python3.withPackages
|
||||||
(x: [x.flask x.flask-wtf x.wtforms x.flask-sqlalchemy]))
|
(x: [x.flask x.flask-wtf x.wtforms x.flask-sqlalchemy x.uuid]))
|
||||||
pkgs.entr
|
pkgs.entr
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
BIN
instance/application.db
Normal file
BIN
instance/application.db
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue