<p>我打赌你知道Django字段中提供的选项将自动具有显示功能。在</p>
<p>假设您有一个定义如下的字段:</p>
<pre><code>category = models.SmallIntegerField(choices=CHOICES)
</code></pre>
<p>您只需调用一个名为<code>get_category_display()</code>的函数来访问显示值。以下是此功能的Django源代码:</p>
<p><a href="https://github.com/django/django/blob/baff4dd37dabfef1ff939513fa45124382b57bf8/django/db/models/base.py#L962" rel="nofollow noreferrer">https://github.com/django/django/blob/baff4dd37dabfef1ff939513fa45124382b57bf8/django/db/models/base.py#L962</a></p>
<p><a href="https://github.com/django/django/blob/baff4dd37dabfef1ff939513fa45124382b57bf8/django/db/models/fields/__init__.py#L704" rel="nofollow noreferrer">https://github.com/django/django/blob/baff4dd37dabfef1ff939513fa45124382b57bf8/django/db/models/fields/<strong>init</strong>.py#L704</a></p>
<p>所以我们可以按照这个方法来实现我们的<code>dynamically set property</code>目标。在</p>
<p>这是我的设想,与你的有点不同,但到最后都是一样的:</p>
<p>我有两个类,<code>Course</code>和<code>Lesson</code>,类<code>Lesson</code>有一个ForeignKey字段<code>Course</code>,我想向类<code>cached_course</code>添加一个属性名<code>Lesson</code>,该类将首先从缓存中获取{<cd3>},如果缓存未命中,则回退到数据库:</p>
<p>下面是一个典型的解决方案:</p>
^{pr2}$
<p>原来我有这么多ForeignKey字段要缓存,所以下面的代码与Django get_FIELD_display特性类似:</p>
<pre><code>from django.db import models
from django.utils.functional import curry
class CachedForeignKeyField(models.ForeignKey):
def contribute_to_class(self, cls, name, **kwargs):
super(models.ForeignKey, self).contribute_to_class(cls, name, **kwargs)
setattr(cls, "cached_%s" % self.name,
property(curry(cls._cached_FIELD, field=self)))
class BaseModel(models.Model):
def _cached_FIELD(self, field):
value = getattr(self, field.attname)
Model = field.related_model
return cache.get_model(Model, pk=value)
class Meta:
abstract = True
class Course(BaseModel):
# some fields
class Lesson(BaseModel):
course = CachedForeignKeyField(Course)
</code></pre>
<p>通过定制<code>CachedForeignKeyField</code>,并用<code>_cached_FIELD</code>方法覆盖<code>contribute_to_class</code>方法以及<code>BaseModel</code>类,每个<code>CachedForeignKeyField</code>将自动相应地具有一个<code>cached_FIELD</code>属性。在</p>
<p>太好了,太棒了!在</p>