如果only()方法中没有提供字段名,如何防止访问QuerySet对象的字段



让我们假设我有这个Django模型:

class Person(models.Model)
name = models.CharField()
age = models.IntegerField()

然后我对模型进行查询:

queryset = Person.objects.filter(name="Joe").only("name") # Notice that I want to only select the name field.
object_list = list(queryset) # Purposefully triggered the database hit by calling list on it.

我如何阻止这样做?:

object_list[0].age # Accessing a field that I did not include in the "only" method triggers an additional hit to the database.

我希望它引发一个异常,或者什么都不做,而不是第二次访问数据库。

更新:我已经回答了自己的问题,但我希望其他人发布他们的答案,看看他们是否有更好的解决方案。

安装并使用名为django-seal的第三方软件包。

覆盖模型的refresh_from_db方法,并在调用时引发AttributeError。

class Person(models.Model):
name = models.CharField(max_length=50)
age = models.IntegerField()
def refresh_from_db(self, using=None, fields=None):
"""
This method was overwritten because of the issues addressed in these tickets:
https://code.djangoproject.com/ticket/26481
https://code.djangoproject.com/ticket/22492
https://code.djangoproject.com/ticket/30874
"""
raise AttributeError(
f'Cannot access {self.__class__.__name__}.{fields[0]} because the '
'fieldname was not provided as an argument in the QuerySet.only() '
'method.'
)

最新更新