first commit
This commit is contained in:
186
calorie_tracker_app/models.py
Normal file
186
calorie_tracker_app/models.py
Normal file
@@ -0,0 +1,186 @@
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_login import UserMixin
|
||||
from datetime import datetime, date
|
||||
|
||||
db = SQLAlchemy()
|
||||
|
||||
class User(UserMixin, db.Model):
|
||||
__tablename__ = 'users'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
username = db.Column(db.String(80), unique=True, nullable=False)
|
||||
password = db.Column(db.String(200), nullable=False)
|
||||
name = db.Column(db.String(100))
|
||||
age = db.Column(db.Integer)
|
||||
gender = db.Column(db.String(10))
|
||||
height_cm = db.Column(db.Float)
|
||||
weight_kg = db.Column(db.Float)
|
||||
activity_level = db.Column(db.String(20), default='moderate')
|
||||
target_daily_calories = db.Column(db.Integer, default=2000)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
# Relationships
|
||||
meals = db.relationship('Meal', backref='user', lazy=True, cascade='all, delete-orphan')
|
||||
weight_logs = db.relationship('WeightLog', backref='user', lazy=True, cascade='all, delete-orphan')
|
||||
water_logs = db.relationship('WaterLog', backref='user', lazy=True, cascade='all, delete-orphan')
|
||||
meal_plans = db.relationship('MealPlan', backref='user', lazy=True, cascade='all, delete-orphan')
|
||||
goals = db.relationship('UserGoal', backref='user', uselist=False, cascade='all, delete-orphan')
|
||||
|
||||
class FoodItem(db.Model):
|
||||
__tablename__ = 'food_items'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(200), nullable=False)
|
||||
name_tagalog = db.Column(db.String(200))
|
||||
category = db.Column(db.String(50))
|
||||
calories = db.Column(db.Float, nullable=False)
|
||||
protein_g = db.Column(db.Float, default=0)
|
||||
carbs_g = db.Column(db.Float, default=0)
|
||||
fat_g = db.Column(db.Float, default=0)
|
||||
fiber_g = db.Column(db.Float, default=0)
|
||||
sugar_g = db.Column(db.Float, default=0)
|
||||
sodium_mg = db.Column(db.Float, default=0)
|
||||
serving_size_g = db.Column(db.Float, default=100)
|
||||
serving_description = db.Column(db.String(100))
|
||||
source = db.Column(db.String(20), default='manual') # 'manual', 'api', 'filipino'
|
||||
is_filipino = db.Column(db.Boolean, default=False)
|
||||
is_favorite = db.Column(db.Boolean, default=False)
|
||||
api_data = db.Column(db.Text)
|
||||
last_updated = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
# Relationships
|
||||
meal_foods = db.relationship('MealFood', backref='food', lazy=True)
|
||||
planned_foods = db.relationship('PlannedFood', backref='food', lazy=True)
|
||||
|
||||
class Meal(db.Model):
|
||||
__tablename__ = 'meals'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
date = db.Column(db.Date, nullable=False, default=date.today)
|
||||
meal_type = db.Column(db.String(20), nullable=False) # breakfast, lunch, dinner, snack
|
||||
time = db.Column(db.Time)
|
||||
notes = db.Column(db.Text)
|
||||
|
||||
# Relationships
|
||||
foods = db.relationship('MealFood', backref='meal', lazy=True, cascade='all, delete-orphan')
|
||||
|
||||
def calculate_totals(self):
|
||||
"""Calculate total nutrition for this meal"""
|
||||
totals = {
|
||||
'calories': 0,
|
||||
'protein': 0,
|
||||
'carbs': 0,
|
||||
'fat': 0
|
||||
}
|
||||
for mf in self.foods:
|
||||
totals['calories'] += mf.calories_consumed
|
||||
totals['protein'] += mf.protein_consumed
|
||||
totals['carbs'] += mf.carbs_consumed
|
||||
totals['fat'] += mf.fat_consumed
|
||||
return totals
|
||||
|
||||
class MealFood(db.Model):
|
||||
__tablename__ = 'meal_foods'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
meal_id = db.Column(db.Integer, db.ForeignKey('meals.id'), nullable=False)
|
||||
food_id = db.Column(db.Integer, db.ForeignKey('food_items.id'), nullable=False)
|
||||
quantity = db.Column(db.Float, nullable=False, default=1.0) # servings
|
||||
quantity_grams = db.Column(db.Float)
|
||||
calories_consumed = db.Column(db.Float)
|
||||
protein_consumed = db.Column(db.Float)
|
||||
carbs_consumed = db.Column(db.Float)
|
||||
fat_consumed = db.Column(db.Float)
|
||||
|
||||
def calculate_nutrition(self):
|
||||
"""Calculate nutrition based on quantity"""
|
||||
self.calories_consumed = self.food.calories * self.quantity
|
||||
self.protein_consumed = self.food.protein_g * self.quantity
|
||||
self.carbs_consumed = self.food.carbs_g * self.quantity
|
||||
self.fat_consumed = self.food.fat_g * self.quantity
|
||||
if self.food.serving_size_g:
|
||||
self.quantity_grams = self.food.serving_size_g * self.quantity
|
||||
|
||||
class WaterLog(db.Model):
|
||||
__tablename__ = 'water_logs'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
date = db.Column(db.Date, nullable=False, default=date.today)
|
||||
amount_ml = db.Column(db.Integer, nullable=False)
|
||||
time = db.Column(db.Time, default=datetime.now().time)
|
||||
|
||||
class WeightLog(db.Model):
|
||||
__tablename__ = 'weight_logs'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
date = db.Column(db.Date, nullable=False, unique=True, default=date.today)
|
||||
weight_kg = db.Column(db.Float, nullable=False)
|
||||
body_fat_percentage = db.Column(db.Float)
|
||||
notes = db.Column(db.Text)
|
||||
time = db.Column(db.Time, default=datetime.now().time)
|
||||
|
||||
class MealPlan(db.Model):
|
||||
__tablename__ = 'meal_plans'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
date = db.Column(db.Date, nullable=False)
|
||||
meal_type = db.Column(db.String(20), nullable=False)
|
||||
is_completed = db.Column(db.Boolean, default=False)
|
||||
notes = db.Column(db.Text)
|
||||
|
||||
# Relationships
|
||||
foods = db.relationship('PlannedFood', backref='meal_plan', lazy=True, cascade='all, delete-orphan')
|
||||
|
||||
def calculate_totals(self):
|
||||
"""Calculate total nutrition for this planned meal"""
|
||||
totals = {
|
||||
'calories': 0,
|
||||
'protein': 0,
|
||||
'carbs': 0,
|
||||
'fat': 0
|
||||
}
|
||||
for pf in self.foods:
|
||||
totals['calories'] += pf.food.calories * pf.quantity
|
||||
totals['protein'] += pf.food.protein_g * pf.quantity
|
||||
totals['carbs'] += pf.food.carbs_g * pf.quantity
|
||||
totals['fat'] += pf.food.fat_g * pf.quantity
|
||||
return totals
|
||||
|
||||
class PlannedFood(db.Model):
|
||||
__tablename__ = 'planned_foods'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
meal_plan_id = db.Column(db.Integer, db.ForeignKey('meal_plans.id'), nullable=False)
|
||||
food_id = db.Column(db.Integer, db.ForeignKey('food_items.id'), nullable=False)
|
||||
quantity = db.Column(db.Float, nullable=False, default=1.0)
|
||||
|
||||
class UserGoal(db.Model):
|
||||
__tablename__ = 'user_goals'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, unique=True)
|
||||
goal_type = db.Column(db.String(20), default='recomp') # weight_loss, muscle_gain, recomp
|
||||
target_weight_kg = db.Column(db.Float)
|
||||
weekly_goal_kg = db.Column(db.Float, default=0.5)
|
||||
target_protein_g = db.Column(db.Integer, default=150)
|
||||
target_carbs_g = db.Column(db.Integer, default=200)
|
||||
target_fat_g = db.Column(db.Integer, default=60)
|
||||
target_water_ml = db.Column(db.Integer, default=2000)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
class DailySummary(db.Model):
|
||||
__tablename__ = 'daily_summary'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
date = db.Column(db.Date, nullable=False, unique=True)
|
||||
total_calories = db.Column(db.Float, default=0)
|
||||
total_protein_g = db.Column(db.Float, default=0)
|
||||
total_carbs_g = db.Column(db.Float, default=0)
|
||||
total_fat_g = db.Column(db.Float, default=0)
|
||||
total_water_ml = db.Column(db.Integer, default=0)
|
||||
calories_remaining = db.Column(db.Float)
|
||||
weight_kg = db.Column(db.Float)
|
||||
notes = db.Column(db.Text)
|
||||
|
||||
class APICache(db.Model):
|
||||
__tablename__ = 'api_cache'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
query = db.Column(db.String(200), nullable=False, unique=True)
|
||||
api_source = db.Column(db.String(50))
|
||||
response_json = db.Column(db.Text)
|
||||
cached_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
Reference in New Issue
Block a user