Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panthers- Group 7: Aisha, Ashanti, Lourdes, Michelle #38

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e0a5e24
backend setup- board and card models updated to sql database
lzara388 Dec 23, 2022
e8cb17b
added autoincrement to board and card model
chemtecher Jan 4, 2023
3c2df90
updated models, and recreated migration folder
lzara388 Jan 4, 2023
c313221
deleted migrations folder
chemtecher Jan 4, 2023
3afeef3
added comment to push
chemtecher Jan 4, 2023
e936bea
added route files for each model. Created and registered blueprint fo…
lzara388 Jan 4, 2023
e0fdc65
resolving merge conflict
lzara388 Jan 4, 2023
90543c4
added POST route for board model
chemtecher Jan 4, 2023
16ce850
changed board POST route to return new board dict
chemtecher Jan 4, 2023
57deaef
added get all boards route
chemtecher Jan 4, 2023
46507d6
added read one board endpoint and validate board helper function
chemtecher Jan 4, 2023
4071710
created and registered card Blueprint
chemtecher Jan 4, 2023
383ed02
created delete route for board and create new card route
chemtecher Jan 4, 2023
318ddc9
added validate card helper function and read one card route
chemtecher Jan 5, 2023
1e4b28a
created DELETE card route
chemtecher Jan 5, 2023
ca6bf3d
added a PUT route for updating card likes
chemtecher Jan 5, 2023
c963af2
updated models to reflect one to many relationship
chemtecher Jan 5, 2023
17e01f8
corrected spelling error and repeated function name
chemtecher Jan 5, 2023
0e210a5
migrations folder
chemtecher Jan 5, 2023
ecbc18f
migrations folder redo
chemtecher Jan 5, 2023
214e578
created nested route to create new card to a board
chemtecher Jan 5, 2023
a99384f
added nested route to GET all cards by board
chemtecher Jan 5, 2023
b12ede3
refactored validate helper function to validate_model
chemtecher Jan 6, 2023
43ef675
refactored requests and responses by creating functions in each model
lzara388 Jan 6, 2023
f61f75e
Merge pull request #1 from chemille/refactoring-request-and-response
lzara388 Jan 6, 2023
2d4fb51
refactored code
chemtecher Jan 6, 2023
3839627
commented model columns
chemtecher Jan 6, 2023
18ae382
model comments for migration push
chemtecher Jan 6, 2023
45e15b8
added Procfile and new migrations folder
chemtecher Jan 6, 2023
157a038
removed comments from code
chemtecher Jan 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,20 @@ def create_app():
# Import models here for Alembic setup
# from app.models.ExampleModel import ExampleModel

from app.models.board import Board
from app.models.card import Card

db.init_app(app)
migrate.init_app(app, db)

# Register Blueprints here
# from .routes import example_bp
# app.register_blueprint(example_bp)
from .routes.board_routes import boards_bp
app.register_blueprint(boards_bp)

from .routes.card_routes import cards_bp
app.register_blueprint(cards_bp)

CORS(app)
return app
4 changes: 4 additions & 0 deletions app/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@




21 changes: 21 additions & 0 deletions app/models/board.py
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
from app import db

# Parent Model
class Board(db.Model):
board_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String)
owner = db.Column(db.String)
cards = db.relationship("Card", back_populates="board")

def to_dict(self):
return {
"id": self.board_id,
"title": self.title,
"owner": self.owner
}

@classmethod
def from_dict(cls, request_body):
return cls (
title= request_body["title"],
owner= request_body["owner"]
)
29 changes: 29 additions & 0 deletions app/models/card.py
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
from app import db
from flask import abort, make_response

# Child model
class Card(db.Model):
card_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
message = db.Column(db.String)
likes_count = db.Column(db.Integer)
board_id = db.Column(db.Integer, db.ForeignKey('board.board_id'))
board= db.relationship("Board", back_populates="cards")


def to_dict(self):
return {
"id": self.card_id,
"message": self.message,
"likes_count": self.likes_count,
"board_id": self.board_id
}

@classmethod

def from_dict(cls, request_body):
return cls(

message= request_body["message"],
likes_count= request_body["likes_count"],
board_id= request_body["board_id"]
)

4 changes: 0 additions & 4 deletions app/routes.py

This file was deleted.

82 changes: 82 additions & 0 deletions app/routes/board_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from flask import Blueprint, request, jsonify, make_response, abort
from app import db
from app.models.board import Board
from app.models.card import Card
from app.routes.routes_helper import validate_model


boards_bp = Blueprint("boards", __name__, url_prefix="/boards")

@boards_bp.route("", methods=["POST"])
def create_board():
request_body = request.get_json()

try:
new_board = Board.from_dict(request_body)

except KeyError:
return {"details": "Missing Data"}, 400

db.session.add(new_board)
db.session.commit()

return jsonify(new_board.to_dict()), 201


# Get ALL Boards
@boards_bp.route("", methods=["GET"])
def read_all_boards():

boards = Board.query.all()
boards_response = [board.to_dict() for board in boards]

return jsonify(boards_response)

# Get ONE Board
@boards_bp.route("/<board_id>", methods=["GET"])
def read_one_board(board_id):
board = validate_model(Board, board_id)

return board.to_dict()


# Delete a Board
@boards_bp.route("/<board_id>", methods=["DELETE"])
def delete_board(board_id):
board = validate_model(Board, board_id)

db.session.delete(board)
db.session.commit()

return make_response({"details": f'{board.title} {board.board_id} successfully deleted'})

# --------------------------- NESTED ROUTES ------------------------------

# create a new card to a board by id
@boards_bp.route("/<board_id>/cards", methods=["POST"])
def create_card_to_board(board_id):
board = validate_model(Board, board_id)


request_body = request.get_json()
try:
new_card= Card.from_dict(request_body)

except KeyError:
return {"details": "Missing Data"}, 400

db.session.add(new_card)
db.session.commit()

return new_card.to_dict(), 201


# GET all cards by a specific board
@boards_bp.route("<board_id>/cards", methods=["GET"])
def read_all_cards_by_board(board_id):
board = validate_model(Board, board_id)


cards_response = [card.to_dict() for card in board.cards]

return jsonify(cards_response)
72 changes: 72 additions & 0 deletions app/routes/card_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from flask import Blueprint, request, jsonify, make_response, abort
from app import db
from app.models.card import Card
from app.routes.routes_helper import validate_model

cards_bp = Blueprint("cards", __name__, url_prefix="/cards")

# Create a New Card
@cards_bp.route("", methods=["POST"])
def create_card():
request_body = request.get_json()

try:
new_card = Card.from_dict(request_body)

except KeyError:
return {"details": "Missing Data"}, 400


db.session.add(new_card)
db.session.commit()

return jsonify(new_card.to_dict()), 201


# Get ALL cards
@cards_bp.route("", methods=["GET"])
def read_all_cards():

cards = Card.query.all()
cards_response = [card.to_dict() for card in cards]

return jsonify(cards_response)


# Get ONE Card
@cards_bp.route("/<card_id>", methods=["GET"])
def read_one_card(card_id):
card = validate_model(Card, card_id)


return card.to_dict()



# Delete a card
@cards_bp.route("/<card_id>", methods=["DELETE"])
def delete_card(card_id):
card = validate_model(Card, card_id)


db.session.delete(card)
db.session.commit()


return {
"details": f'Card {card.card_id} successfully deleted'
}

# Update likes
@cards_bp.route("/<card_id>/likes", methods=["PUT"])
def update_likes(card_id):
card = validate_model(Card, card_id)


request_body =request.get_json()
card.likes_count = request_body["likes_count"]
card.likes_count = int(card.likes_count) + 1
db.session.commit()

return card.to_dict()

13 changes: 13 additions & 0 deletions app/routes/routes_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from flask import make_response, abort

def validate_model(cls, model_id):
try:
model_id = int(model_id)
except:
abort(make_response({"message": f"{cls.__name__} {model_id} invalid, id must be a number"}, 400))

model = cls.query.get(model_id)
if not model:
abort(make_response({"message": f"There is no existing {cls.__name__} {model_id}"}, 404))

return model
1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
45 changes: 45 additions & 0 deletions migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# A generic, single database configuration.

[alembic]
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false


# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
Loading