str*_*pe7 12 django django-forms django-admin django-cache django-queryset
在Django表单中使用ModelChoiceField或ModelMultipleChoiceField时,有没有办法传入一组缓存的选项?目前,如果我通过queryset参数指定选项,则会导致数据库命中.
我想使用memcached缓存这些选项,并在显示具有此类字段的表单时防止对数据库的不必要的命中.
小智 13
您可以在QuerySet中覆盖"all"方法
from django.db import models
class AllMethodCachingQueryset(models.query.QuerySet):
def all(self, get_from_cache=True):
if get_from_cache:
return self
else:
return self._clone()
class AllMethodCachingManager(models.Manager):
def get_query_set(self):
return AllMethodCachingQueryset(self.model, using=self._db)
class YourModel(models.Model):
foo = models.ForeignKey(AnotherModel)
cache_all_method = AllMethodCachingManager()
Run Code Online (Sandbox Code Playgroud)
然后在使用表单之前更改字段的查询集(例如,当您使用表单集时)
form_class.base_fields['foo'].queryset = YourModel.cache_all_method.all()
Run Code Online (Sandbox Code Playgroud)
Nic*_*s78 12
ModelChoiceField特别是在生成选择时创建命中的原因- 无论QuerySet是否先前已填充 - 都在此行中
for obj in self.queryset.all():
Run Code Online (Sandbox Code Playgroud)
在django.forms.models.ModelChoiceIterator.关于QuerySets缓存的Django文档突出显示,
可调用属性每次都会导致数据库查找.
所以我更愿意使用
for obj in self.queryset:
Run Code Online (Sandbox Code Playgroud)
即使我不是100%肯定这一切的含义(我知道我之后没有对查询集的大计划,所以我认为没有副本.all()创建我很好).我很想在源代码中改变这个,但是因为我将在下次安装时忘记它(并且它开始时风格很糟糕)我最终编写了我的自定义ModelChoiceField:
class MyModelChoiceIterator(forms.models.ModelChoiceIterator):
"""note that only line with # *** in it is actually changed"""
def __init__(self, field):
forms.models.ModelChoiceIterator.__init__(self, field)
def __iter__(self):
if self.field.empty_label is not None:
yield (u"", self.field.empty_label)
if self.field.cache_choices:
if self.field.choice_cache is None:
self.field.choice_cache = [
self.choice(obj) for obj in self.queryset.all()
]
for choice in self.field.choice_cache:
yield choice
else:
for obj in self.queryset: # ***
yield self.choice(obj)
class MyModelChoiceField(forms.ModelChoiceField):
"""only purpose of this class is to call another ModelChoiceIterator"""
def __init__(*args, **kwargs):
forms.ModelChoiceField.__init__(*args, **kwargs)
def _get_choices(self):
if hasattr(self, '_choices'):
return self._choices
return MyModelChoiceIterator(self)
choices = property(_get_choices, forms.ModelChoiceField._set_choices)
Run Code Online (Sandbox Code Playgroud)
这并不能解决数据库缓存的一般问题,但是因为你ModelChoiceField特别询问这一点,这正是让我首先考虑缓存的原因,认为这可能会有所帮助.
| 归档时间: |
|
| 查看次数: |
4899 次 |
| 最近记录: |