【发布时间】:2021-07-19 21:36:10
【问题描述】:
我不知道如何调试它。我有这个 Django 模型:
from django.db import models
from django.utils.translation import ugettext_lazy as _
# ...
class AbstractPhrase(models.Model):
term2_past_tense = models.TextField(_('term 2 past tense'))
# ... other simple fields and methods
class Meta:
abstract = True
class CommentPhrase(AbstractPhrase, models.Model):
"""A phrase that comprises part of a report card comment"""
skill = models.ForeignKey(Skill, null=True, on_delete=models.SET_NULL)
question = models.ForeignKey(
Question,
null=True,
on_delete=models.SET_NULL,
related_name='phrases')
old_id = models.CharField(
_('old ID'),
max_length=10,
blank=True,
null=True)
# ... Other simple fields
class Meta:
ordering = ('skill', 'question_number')
verbose_name = _('comment phrase')
verbose_name_plural = _('comment phrases')
管理员报告无法在 Django 管理员中更新模型。保存后,Django 管理员会报告模型更新成功,但是当他们刷新页面时,数据仍然过期。
我打开了一个 Django shell 并进行了调查:
In [3]: cp = CommentPhrase.objects.get(pk=10280)
In [4]: cp
Out[4]: <CommentPhrase: lorem ipsum>
In [5]: cp.term2_past_tense
Out[5]: ''
In [6]: cp.term2_past_tense = "Test"
In [7]: cp.save()
In [8]: cp.term2_past_tense
Out[8]: 'Test'
In [9]: cp.refresh_from_db()
In [10]: cp.term2_past_tense
Out[10]: ''
我进一步尝试执行查询集更新(),结果相同。
当我查看数据库时,它变得更奇怪了。事实证明,该值实际上已在 postgres shell 中成功更新。我可以使用以下语法查看更新的值:
In [7]: CommentPhrase.objects.filter(pk=10280).first().term2_past_tense
Out[7]: 'Test'
但不是这样:
In [12]: CommentPhrase.objects.get(pk=10280).term2_past_tense
Out[12]: ''
计数返回 1:
In [2]: CommentPhrase.objects.filter(pk=10280).count()
Out[2]: 1
那么到底为什么 filter(pk=x).first() 会返回与 get(pk=x) 不同的东西???
我可以在原始数据库中看到该值存在,但它没有显示在 get 中,也没有显示在 Django 管理员中。
多年来,数据库中有数百个实例通过导入和导出以及 Django 管理员进行维护和更新。它最近刚刚停止工作。我已经确认迁移是最新的并且在生产和本地之间是一致的,并且从手动检查来看,数据库架构看起来不错。
在我的本地机器上一切正常。该错误仅出现在生产中。我正在使用
- Python 3.9.0
- Django 3.1.3
- psycopg2-二进制 2.8.6
我的本地机器正在使用 psql (PostgreSQL) 12.6 (Ubuntu 12.6-0ubuntu0.20.04.1) 生产在 AWS RDS 上使用 psql(11.6(Ubuntu 11.6-1.pgdg18.04+1),服务器 10.15)
这是我的缓存配置:
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': '{0}/{1}'.format(env('REDIS_URL', default='redis://127.0.0.1:6379'), 0),
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'IGNORE_EXCEPTIONS': True, # mimics memcache behavior.
# http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior
}
}
}
【问题讨论】:
-
可能涉及到一些数据库缓存。您使用
get()检索初始 Python 对象,并且在同一事务期间可能仍会返回该结果。尝试在更新后关闭/重新启动 shell (save())。 -
@schwobaseggl 我已经关闭/重新启动了 shell,并完成了
refresh_from_db()。 get 仍然没有返回,并且 filter/first 仍然返回结果 -
更新问题以显示缓存配置
标签: python django filter model django-queryset