【发布时间】:2021-01-17 23:19:49
【问题描述】:
假设我有一个像这样的 django 模型:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
创建此一对一字段后,可以通过user_instance.profile访问配置文件对象
我为 ORM 启用了日志记录,以便在我的 settings.py 文件中查看发送到数据库的查询:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
'propagate': False,
},
},
}
然后我使用python3 manage.py shell 打开外壳并执行以下操作:
firstuser = User.objects.first()
这导致以下查询被注销:
SELECT "users_user"."id", "users_user"."password", "users_user"."last_login", "users_user"."is_superuser", "users_user"."username", "users_user"."is_staff", "users_user"."is_active", "users_user"."date_joined", "users_user"."name", "users_user"."email", "users_user"."join_date", "users_user"."date_of_birth" FROM "users_user" ORDER BY "users_user"."id" ASC LIMIT 1; args=()
我还做了:
firstuser.profile
并已注销此查询:
SELECT "users_profile"."id", "users_profile"."user_id", "users_profile"."status", "users_profile"."institute" FROM "users_profile" WHERE "users_profile"."user_id" = 1 LIMIT 21; args=(1,)
那么,当我请求相关对象时,django 如何执行查询无需在我自己的代码中调用任何函数。
是否有 python 方法来覆盖如何读取类中的属性的行为?
提前致谢!
【问题讨论】:
-
我想知道 django 是如何在不调用我的代码中的任何函数的情况下进行这些惰性求值的
-
“django 如何进行这些惰性求值”和“在我的代码中不调用任何函数”是什么意思?你的问题是什么?你想知道 django 是如何做这些事情的吗?不调用任何函数是什么意思?
-
python中的底层机制称为Descriptor Protocol
-
@NavidZarepak 在我上面提到的代码中,我读取了属性
user.profile,当我访问它时,我会延迟加载配置文件对象。在我的代码中,我不调用任何类似get_profile -
@Wombatz 正是我想知道的,非常感谢 Wombatz!
标签: python python-3.x django django-orm