避免多次调用django数据库

6ovsh4lw  于 2021-07-26  发布在  Java
关注(0)|答案(3)|浏览(296)

我想查询我的django数据库一次,然后返回一个queryset(分配了名称“codes”),我可以迭代这个queryset来获得每个示例的“internal\u code”属性,而无需进一步调用数据库。这是我的代码,但我不确定每次在queryset上使用“get”时是否都在查询数据库,以及如何避免这种情况:

codes = models.RecordType.objects.all()

permanent = sorted([
    (
        codes.get(
            industry_code=category.value
        ).internal_code,
        self.labels.get(category, category.name)
    )
    for category in enums.Category
])
lsmd5eda

lsmd5eda1#

如果要强制对queryset进行求值,可以执行以下操作: codes = list(models.RecordType.objects.all())

k0pti3hp

k0pti3hp2#

你写的大概就是这样,但你不应该打电话 get() 一直在上面。每次这样做都是在进行一个单独的db查询。
django从数据库中懒洋洋地获取结果,当您指示需要结果时。例如


# first enable some logging to see the database queries

import logging.config
logging.config.dictConfig({
    'version': 1,
    'formatters': {
        'simple': {'format': '%(levelname)s %(message)s'},
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
        },
    },
    'root': {
        'level': 'WARNING',
        'handlers': ['console'],
    },
    'loggers': {
        'django.db.backends': {'level': 'DEBUG',},
    },
})

# No query made

codes = RecordType.objects.filter(
    industry_code__in=[cat.value for cat in enums.Category]
)

# show the query that will be made (roughly)

print(str(codes.query))

# force the queryset to be executed and return all the results.

# the queryset is executed when you iterate over it.

codes_by_industry_code = {
    code.industry_code: code
    for code in codes
}

# now you can set up your list:

permanent = [
    (
        codes_by_industry_code[category.value].internal_code,
        self.labels.get(category, category.name)
    )
    for category in enums.Category
]

现在,如果您想确保查询只发生在正确的位置,您应该使用测试工具(如本问题中所述)来测试您的代码。这是确保代码在db查询方面做了它应该做的事情的唯一方法。

lpwwtiir

lpwwtiir3#

使用\uuu-in运算符 filter 所有的 RecordTypeindustry_code 出现在 Category 枚举:

codes = (
    RecordType.objects
    .filter(industry_code__in=[c.value for c in Category])
    .only('industry_code', 'internal_code')
)
category_labels = {c.value: self.labels.get(c, c.name) for c in Category}

permanent = sorted([
    (code.internal_code, category_labels[code.industry_code])
    for code in codes
])

使用。仅在情况下使用 RecordType 有很多你不需要的字段。
但我不确定是否每次在queryset上使用get时都在查询数据库
对。你可以锁链 .filter() , .exclude() ,以及其他返回查询集而不运行查询集的方法;与 .get() queryset会立即(每次)求值,并返回一个示例。

相关问题