Skip to content

Conversation

@Shirley425
Copy link

No description provided.

Copy link

@mikellewade mikellewade left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work on your Task List API, Qiaoqiao!

Comment on lines +4 to +5
from .routes.task_routes import tasks_bp
from .routes.goal_routes import goals_bp

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget that Flask convention is to name your Blueprints bp and then inside of our __init__.py file we can import with as.

Comment on lines +7 to +8
from dotenv import load_dotenv
load_dotenv()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, using load_dotenv to ensure that your environmental variables are loaded before being accessed.

Comment on lines +26 to +27
app.register_blueprint(tasks_bp)
app.register_blueprint(goals_bp)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭐️


class Goal(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
title: Mapped[str]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this! This is the pattern that we showed you in class! Leveraging the Declarative Mapping Annotation to declare this column as a non-nullable string.

class Goal(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
title: Mapped[str]
tasks: Mapped[list["Task"]] = relationship(back_populates="goal")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect! You are making a relationship attribute on the Goal model. This attribute is going to be a list of Task models. You then use relationship with back_populates to tell SQLAlchemy to sync this attribute with relationship attribute called goal on the Task model.

Comment on lines +19 to +37
title_param = request.args.get("title")
if title_param:
query = query.where(Task.title.ilike(f"%{title_param}%"))

sort_param = request.args.get("sort")
if sort_param:
if sort_param.lower() == "asc":
query = query.order_by(asc(Task.title))
elif sort_param.lower() == "desc":
query = query.order_by(desc(Task.title))

query = query.order_by(Task.id)

tasks = db.session.scalars(query)

tasks_response = []
for task in tasks:
tasks_response.append(task.to_dict())
return tasks_response

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could D.R.Y. this up as well with get_model_with_filters

def get_one_task(task_id):
task = validate_model(Task, task_id)

return {"task": task.to_dict()}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return {"task": task.to_dict()}
return { "task": task.to_dict() }

Comment on lines +52 to +53
task.title = request_body["title"]
task.description = request_body["description"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another opportunity to D.R.Y. up our code! Notice how in this route and the PUT route for goal_routes.py we follow the pattern of:

object.ATTRIBUTE = request_body["ATTRIBUTE"]

We use hasattr and setattr to make a helper function to update our Task and Goal model. It would look like this:

def update_model(obj, data):
    for attr, value in data.items():
        if hasattr(obj, attr):
            setattr(obj, attr, value)
    
    db.session.commit()

    return Response(status=204, mimetype="application/json")

This refactor not only makes our code D.R.Y but shows that we recognize logic that has higher level usability while handling cases of keys not being found!


# Assert
assert response.status_code == 404
assert response_body == {'message': 'Task 1 not found'}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⭐️

Comment on lines +92 to +93
query = db.select(Goal).where(Goal.id == 1)
goal = db.session.scalar(query)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work checking the database!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants