如何将所有字段定义从一个模型类复制到另一个模型类?

时间:2011-05-10 16:13:05

标签: sql django orm

我有一个模型( Patch ),它有一个作者字段,我需要生成几个报告,总是过滤掉作者不包含字符串'@ example.com'的行。鉴于Patch是在一个单独的django应用程序中定义的,我不想改变,我的想法是创建一个DB视图(比如, ExampleComPatch ,使用非托管模型类访问)过滤掉我不感兴趣的所有行,然后将报告方法放在新的模型类下。

为了避免代码重复,我让我的新模型类继承自Patch。只需要几个警告就可以了。

  1. 我的视图需要在Patch中定义所有列以及额外的'patch_ptr_id'列,因为django认为我也希望在DB中实现真正的继承
  2. 由于它是非托管模型类,因此使用该视图的测试需要手动创建
  3. 然而,由于django认为我想要真正的继承,每当我删除Patch的一个实例时,它最终会遍历所有子对象(例如,链接到它的ExampleComPatch中的行),这意味着没有关系的测试无论如何,如果需要从Patch表中删除()一行,ExampleComPatch现在可能需要手动创建DB视图。

    我认为继承可能不是最好的选择,但我真的想避免代码重复,所以我想知道是否有办法将所有字段定义从Patch复制到ExampleComPatch。或者甚至是一种完全不同的方法,允许我使用数据库视图(以减少我的报告方法的复杂性),使用在Patch之外定义的报告方法,因为它们在那里没有多大意义。

3 个答案:

答案 0 :(得分:1)

代理模型是你的票。像这样:

from somewhere import Patch

class FilteredPatchManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        return super(FilteredPatchManager, self).get_query_set().exclude(author__contains='@example.com')


class FilteredPatch(Patch)
    objects = FilteredPatchManager()

    class Meta:
        proxy = True

然后,使用FilteredPatch.objects代替Patch.objects进行查询。

答案 1 :(得分:0)

我认为你的事情比他们需要的要复杂得多。如果我理解正确,你想从某些标准获取查询中排除某些对象 - 如果是这种情况,你应该研究

Modifying initial Manager QuerySets

基本上,您可以自定义查询返回的内容,如下所示:

# First, define the Manager subclass.
class PatchManger(models.Manager):
    def get_query_set(self):
        return super(PatchManager, self).get_query_set().exclude(author__contains='@example.com')

# Then hook it into the Patch model explicitly.
class Patch(models.Model):
    author = models.CharField(max_length=100)

    objects = PatchManager() # The custom manager.

希望我能正确理解你的问题......

干杯,

马丁

答案 2 :(得分:0)

为什么你需要继承或复制代码?您可以将模型导入当前应用程序并在必要时进行过滤 - 如果您愿意,可以在应用程序中创建一个包装过滤器的函数,因此您只需调用该函数来返回过滤后的实例。