使用Django 2.0与DRF 3.7.3时,API数据更新后未实时生效的解决方法
Django REST Framework API 未实时返回更新后的数据问题解决
看起来你遇到了DRF接口不实时反映数据变更的问题,我来帮你分析下可能的原因和解决方案:
首先看一下你的代码,PostListAPIView里的get_queryset方法每次请求都会重新获取当前时间并查询数据库,类属性的today = timezone.now()不会影响结果——因为你在方法里重新定义了变量,所以这个不是问题所在。
下面是几个最可能的原因和对应的解决办法:
1. 缓存机制导致旧数据被返回
这是最常见的原因,不管是DRF的视图缓存还是全局缓存中间件,都可能让接口返回缓存的旧数据:
- 如果你的视图使用了
cache_page装饰器,比如:
要么直接去掉这个装饰器(如果不需要缓存列表数据),要么在更新from django.views.decorators.cache import cache_page @method_decorator(cache_page(60*15), name='dispatch') class PostListAPIView(ListAPIView): # ...Article对象后主动清除对应缓存:from django.core.cache import cache # 替换成你的缓存键,通常和视图URL路径相关 cache.delete('views.decorators.cache.cache_page.xxxxxx') - 如果项目启用了全局缓存中间件(比如
django.middleware.cache.UpdateCacheMiddleware),可以给这个视图添加never_cache装饰器,禁止缓存它的响应:from django.views.decorators.cache import never_cache from django.utils.decorators import method_decorator @method_decorator(never_cache, name='dispatch') class PostListAPIView(ListAPIView): # 你的原有代码
2. 事务未提交导致更新未生效
如果你的publish_date更新操作是在一个未提交的事务中执行的,其他请求自然看不到变更:
- 检查更新代码是否用了
transaction.atomic(),确保事务正常提交:from django.db import transaction # 正确的更新方式,with块结束后自动提交事务 with transaction.atomic(): article = Article.objects.get(pk=your_article_id) article.publish_date = new_publish_date article.save() - 如果是手动管理事务,一定要记得调用
transaction.commit()完成提交。
3. 强制查询集重新获取数据
虽然Django的QuerySet默认是惰性求值且每次调用都会重新查询数据库,但偶尔会因为某些边界情况(比如之前的QuerySet被意外缓存)导致旧数据被复用。你可以稍微调整get_queryset的写法,强制从数据库拉取最新数据:
def get_queryset(self): today = timezone.now() # 先排序再过滤,确保每次都生成全新的查询集 return Article.objects.order_by('-publish_date').filter(publish_date__lte=today)[:30]
4. 数据库隔离级别问题
如果你的数据库使用了REPEATABLE READ隔离级别(比如MySQL默认的InnoDB隔离级别),虽然不同请求应该能看到已提交的变更,但可以确认下数据库的隔离级别是否设置正确。一般来说,Django默认适配的数据库隔离级别是没问题的,这个可以作为最后排查的选项。
按照上面的步骤逐一排查,应该就能解决接口不实时返回更新数据的问题了。
内容的提问来源于stack exchange,提问作者Santhosh
相关产品推荐
相关产品推荐

