如何获取股票数据并添加至Django模型?实现金融网站运行时Stock模型IntField价格自动更新
Hey there! Let's tackle your two main needs: getting stock data into your Django Stock model and making that price field update automatically while your site runs. Here's a step-by-step breakdown tailored to your setup:
1. 获取股票数据并写入Django模型
First, let's make sure your Stock model is set up correctly (I'll stick with your IntField requirement, but I'll note a better alternative for financial data later):
# your_app/models.py from django.db import models class Stock(models.Model): ticker = models.CharField(max_length=10, unique=True) # 比如AAPL、GOOGL这类股票代码 price = models.IntegerField() # 如果需要小数精度,可以把价格转成分存储(比如$150.25存为15025) last_updated = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.ticker} - ${self.price / 100:.2f}" # 展示时转回美元格式
用yfinance获取数据(免费易用)
我们用yfinance库拉取实时股票数据,先安装它:
pip install yfinance
接下来创建一个Django自定义管理命令,用来拉取并保存数据——这样你既可以手动运行更新,也能后续自动化:
# your_app/management/commands/fetch_stock_prices.py from django.core.management.base import BaseCommand import yfinance as yf from your_app.models import Stock class Command(BaseCommand): help = "拉取最新股票价格并更新Stock模型" def handle(self, *args, **options): # 你要跟踪的股票列表(后续也可以改成从数据库读取) target_tickers = ["AAPL", "GOOGL", "MSFT", "TSLA"] for ticker in target_tickers: # 获取股票数据 stock_data = yf.Ticker(ticker) latest_close = stock_data.history(period="1d")["Close"].iloc[-1] # 转成整数(比如$150.25 → 15025分) price_int = int(round(latest_close * 100)) # 更新或创建股票记录 stock, created = Stock.objects.update_or_create( ticker=ticker, defaults={"price": price_int} ) if created: self.stdout.write(self.style.SUCCESS(f"创建新股票条目:{ticker}")) else: self.stdout.write(self.style.SUCCESS(f"更新{sticker}价格至${latest_close:.2f}"))
手动运行命令测试:
python manage.py fetch_stock_prices
注意:如果不想用分来存储价格,建议把
IntField换成DecimalField(max_digits=10, decimal_places=2)——这对金融数据来说精度更合适,只需去掉代码里的*100转换即可。
2. 实现价格字段自动更新
现在让价格在网站运行期间自动更新,有两种靠谱方案:
方案1:系统级定时任务(简单,无需额外依赖)
如果你用Linux/macOS,用cron来定时运行管理命令;Windows则用任务计划程序。
示例cron任务(每个工作日9:30开盘后运行):
- 打开crontab编辑:
crontab -e
- 添加以下内容(替换成你的虚拟环境和项目路径):
30 9 * * 1-5 /path/to/your/venv/bin/python /path/to/your/project/manage.py fetch_stock_prices
方案2:Django Celery Beat(灵活,适合高频更新)
如果需要更精细的控制(比如每5分钟更新一次),可以用django-celery-beat配合Celery和Redis(或RabbitMQ):
- 安装依赖:
pip install celery django-celery-beat redis
- 更新
settings.py:
INSTALLED_APPS = [ # ... 你已有的app "django_celery_beat", ] CELERY_BROKER_URL = "redis://localhost:6379/0" CELERY_RESULT_BACKEND = "redis://localhost:6379/0" CELERY_TIMEZONE = "America/New_York" # 换成你的时区,比如"Asia/Shanghai"
- 运行迁移创建Celery所需的数据库表:
python manage.py migrate
- 在
your_app/tasks.py创建Celery任务:
from celery import shared_task import yfinance as yf from your_app.models import Stock @shared_task def update_stock_prices(): # 从数据库读取所有跟踪的股票,不再硬编码 tickers = Stock.objects.values_list("ticker", flat=True) for ticker in tickers: stock_data = yf.Ticker(ticker) latest_close = stock_data.history(period="1d")["Close"].iloc[-1] price_int = int(round(latest_close * 100)) Stock.objects.filter(ticker=ticker).update(price=price_int) return f"成功更新{len(tickers)}只股票价格"
- 在Django后台设置定时任务:
- 启动Django服务器,登录后台管理
- 进入「Periodic Tasks」→「Add Periodic Task」
- 命名任务,从下拉菜单选择
update_stock_prices任务 - 设置执行周期(比如「每5分钟」或「工作日9:30」)
- 保存后,Celery就会自动执行更新了!
实用小贴士
- 如果yfinance触发了请求限制,可以换成付费API比如Alpha Vantage,只需替换掉yfinance的代码块即可。
- 在拉取/更新代码里加入错误处理(比如try/except捕获网络问题),避免程序崩溃。
- 只在股市开盘时间更新价格,节省API调用次数,避免获取 stale 数据。
内容的提问来源于stack exchange,提问作者Finance




