【问题标题】:Django filter().first() returning different result than get()Django filter().first() 返回与 get() 不同的结果
【发布时间】: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


【解决方案1】:

已解决。我的 redis 缓存服务根本不工作,我需要重新启动该服务。缓存基础设施工作后,一切都很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多