<p>我花了一段时间想办法建一个好工厂,但我遇到了很多问题。</p>
<p>我能给你的建议是把你的遗产连锁起来。它不是很通用的,所以我不确定它有多有用,但你要做的就是:</p>
<pre><code>class GlobalMixin(DeleteMixin):
is_global = models.BooleanField(default=True)
objects = GlobalManager()
class Meta:
abstract = True
class GlobalManager(DeleteManager):
def globals(self):
return self.get_query_set().filter(is_global=1)
</code></pre>
<p>如果你想要更通用的东西,我能想到的最好方法是定义一个基<code>Mixin</code>和<code>Manager</code>来重新定义<code>get_query_set()</code>(我假设你只想这样做一次;否则事情会变得非常复杂),然后通过<code>Mixin</code>传递一个要添加的字段列表</p>
<p>它看起来像这样(根本没有经过测试):</p>
<pre><code>class DeleteMixin(models.Model):
deleted = models.BooleanField(default=False)
class Meta:
abstract = True
def create_mixin(base_mixin, **kwargs):
class wrapper(base_mixin):
class Meta:
abstract = True
for k in kwargs.keys():
setattr(wrapper, k, kwargs[k])
return wrapper
class DeleteManager(models.Manager):
def get_query_set(self):
return super(DeleteManager, self).get_query_set().filter(deleted=False)
def create_manager(base_manager, **kwargs):
class wrapper(base_manager):
pass
for k in kwargs.keys():
setattr(wrapper, k, kwargs[k])
return wrapper
</code></pre>
<p>好吧,这很难看,但你觉得怎么样?从本质上说,这是相同的解决方案,但更具活力,也更干燥,尽管阅读起来更复杂。</p>
<p>首先,动态创建管理器:</p>
<pre><code>def globals(inst):
return inst.get_query_set().filter(is_global=1)
GlobalDeleteManager = create_manager(DeleteManager, globals=globals)
</code></pre>
<p>这将创建一个新的管理器,它是<code>DeleteManager</code>的子类,并且有一个名为<code>globals</code>的方法。</p>
<p>接下来,创建mixin模型:</p>
<pre><code>GlobalDeleteMixin = create_mixin(DeleteMixin,
is_global=models.BooleanField(default=False),
objects = GlobalDeleteManager())
</code></pre>
<p>就像我说的,很难看。但这意味着你不必重新定义<code>globals()</code>。如果您希望不同类型的管理器具有<code>globals()</code>,只需使用不同的基再次调用<code>create_manager</code>。你可以添加任意多的新方法。同样对于管理器,您只需不断添加新函数,这些函数将返回不同的queryset。</p>
<p>那么,这真的实用吗?也许不是。这个答案更多的是(ab)使用Python的灵活性。我没有尝试过使用它,尽管我确实使用了一些动态扩展类的基本原理,以使访问更容易。</p>
<p>如果有什么不清楚的地方请告诉我,我会更新答案。</p>