【发布时间】:2016-07-23 22:49:24
【问题描述】:
所以我的 Django 应用程序中有以下模型结构:-
class SuperModel(models.Model):
f1 = models.CharField()
f2 = models.CharField()
class Model(SuperModel):
f3 = models.CharField()
class OverrideModel(models.Model):
fpk = models.OneToOneField(Model, primary_key=True)
f1 = models.CharField()
f2 = models.CharField()
基本上,在我的应用程序中,Model 表中的字段f1 和f2 包含我输入的用户信息。用户可以覆盖此信息,并且他/她对数据所做的任何更改都存储在OverrideModel 表中(因为我不想丢失我首先输入的信息)。把它想象成我之前创建用户配置文件,而现在我希望用户能够编辑他/她自己的配置文件而不会丢失我输入的关于他们的信息。
现在,由于我的应用程序的其余部分(视图/模板等)使用 Model 类中的字段名称,我想要创建一个获取字段 @ 的数据的 视图从覆盖表中提取 987654326@(如果存在),否则它应该从之前使用的表中提取 f1而不诉诸原始查询集。
我将描述到目前为止我所考虑的所有内容,以便我正在处理的其他一些限制变得清晰:-
-
Model.objects.annotate(f1=Case(When(overridemodel__f1__isnull=True, then=F('f1')), default=F('overridemodel__f1'))).这会抛出注释别名与表中已有字段冲突的错误。
-
Model.objects.defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...).无法应用此方法,因为我无法找到使用 extra 应用外连接的方法。覆盖模型可能没有对应于每个模型行的行。在
tables子句中指定覆盖表会执行一个叉积运算,该运算与 where 可用于执行内连接,而不是外连接(尽管我很高兴被证明是错误的)。编辑:我已经意识到 select_related 可能能够解决上述问题,但是如果我在字段
f1上过滤由Model.objects.select_related('overridemodel').defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...)生成的查询集,比如qs.filter(f1='Random stuff')where 子句对于过滤器查询,使用Model.f1字段而不是额外生成的f1字段。所以这种做法也是徒劳的。 -
使用
Model.objects.raw()获取原始查询集。这是一个非首发,因为 Django ORM 在使用
raw后变得无用,我需要能够过滤/排序模型对象作为应用程序的一部分。 -
在
Model类上定义方法/属性。同样,我将无法在此处使用相同的字段名称,这涉及在代码中寻找所有用法并进行更改。
-
在数据库中创建一个视图以提供我想要的内容,并创建一个非托管模型以从该视图中读取数据。
这可能是解决我的问题的最佳解决方案,但我之前从未使用过非托管模型,我不知道该怎么做或者我可能会遇到什么陷阱。我能想到的一个问题是,我的视图必须始终与模型保持同步,但与搜索代码库并进行更改然后进行测试相比,这似乎是一个很小的代价。什么都坏了。
所以,你有它。与往常一样,任何帮助/指针将不胜感激。我试图提供尽可能少的例子;所以如果需要更多信息,我很乐意提供。
另外,我正在使用 Django 1.8 和 MySQL。
【问题讨论】:
标签: mysql django-1.8