我有两个Django模型类,其结构类似于以下内容:
class Build(models.Model):
project = models.CharField(max_length=100)
...
class CustomBuild(Build):
custom_type = ...
...
我想从具有特定项目属性的数据库中选择所有Builds and CustomBuilds(每个CustomBuild与Build具有一对一的关系) .
我相信Build.objects.filter(project =“myproject”)将选择正确的对象,但其中许多将缺少CustomBuild对象提供的其他数据(如custom_type) . 另一方面,过滤CustomBuild.objects将排除那些不是CustomBuilds的对象 .
我怎么能做到这一点?谢谢 .
2 回答
您可以使用Build.objects.filter()获取Build对象,并在需要时访问子类:
您可以采用几种方法来处理执行此类查询时获得的"mixed models"的
QuerySet
. 很多都取决于你的最终目标 .我经常使用的"simple and dumb"方法是使用实用程序函数来管理结果 . 例如,如果您计划在模板中处理
Build.objects.filter(project="myproject")
的结果,则可以使用自定义模板标记或过滤器来执行特殊操作 . 假设在下面的代码中build_objects
包含filter()的结果:这里显而易见的问题是,如果你有许多子类,编写模板过滤器可能是不切实际的或变得乏味 . 但是,根据我的经验,我通常最多有六个子类,所以这并不总是一个问题 .
您也可以编写参数化过滤器,如下所示:
使用过滤器代码如下:
此过滤器仅检查参数是否存在于
build
对象上的属性(作为value
传入) . 参数字符串应该是您要检测的自动生成的OneToOneField
的名称,在本例中为custom_build
.对于视图代码,类似的辅助函数可以以相同的方式工作,但更简单,因为您不需要编写自定义过滤器或标记 .
这种方法在许多情况下都有效,但是有些更复杂的情况可能不实用 . 不幸的是,当您对基类执行操作时,Django本身无法为您提供包含子类实例的
QuerySet
(即真正包含"mixed models"的QuerySet
) . 在无法使用辅助函数处理结果的情况下,您可能需要这样做 .我个人完全避免这些情况,通常是通过重新思考我的模型设计 . 但如果那是不可能的,那么解决方案就有很多有趣的尝试,例如Inheritance MixIn . 关于这个主题还有几个Django片段 . 但请注意,几乎任何这样的解决方案都会受到性能限制 .