【问题标题】:How to create union of two different django-models?如何创建两个不同 django 模型的联合?
【发布时间】:2019-04-28 23:16:00
【问题描述】:

我有两个 django 模型

class ModelA(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_a')
    other_column = models.CharField(/*...*/ db_column='other_column_a')


class ModelB(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_b')
    other_column = None 

然后我想用union合并这个模型的两个查询集

ModelA.objects.all().union(ModelB.objects.all())

但在查询中我看到

(SELECT
`model_a`.`title`,
`model_a`.`text_a`,
`model_a`.`other_column`
FROM `model_a`)

UNION
(SELECT
`model_b`.`title`,
`model_b`.`text_b`
FROM `model_b`)

当然我得到了例外The used SELECT statements have a different number of columns

如何创建别名和假列以使用联合查询?

【问题讨论】:

    标签: mysql django django-models union


    【解决方案1】:

    您可以注释最后一列以弥补列号不匹配。

    a = ModelA.objects.values_list('text_a', 'title', 'other_column')
    b = ModelB.objects.values_list('text_a', 'title')
            .annotate(other_column=Value("Placeholder", CharField()))
    
    # for a list of tuples
    a.union(b)
    
    # or if you want list of dict
    # (this has to be the values of the base query, in this case a)
    
    a.union(b).values('text_a', 'title', 'other_column')
    
    

    【讨论】:

      【解决方案2】:

      在SQL查询中,我们可以使用NULL来定义剩余的列/别名

      (SELECT
      `model_a`.`title`,
      `model_a`.`text_a`,
      `model_a`.`other_column`
       FROM `model_a`)
      
      UNION
      
      (SELECT
      `model_b`.`title`,
      `model_b`.`text_b`, 
       NULL
       FROM `model_b`)
      

      【讨论】:

      【解决方案3】:

      在 Django 中,联合操作需要具有相同的列,因此对于 values_list,您只能像这样使用那些特定的列:

      qsa = ModelA.objects.all().values('text_a', 'title')
      qsb = ModelB.objects.all().values('text_a', 'title')
      
      qsa.union(qsb)
      

      但是没有办法(据我所知)在 Django 的联合中模仿 NULL。所以这里有两种方法可以继续。

      第一个,在模型中添加一个名为 other_column 的额外字段。您可以像这样将值留空:

      other_column = models.CharField(max_length=255, null=True, default=None)
      

      并使用 here 中描述的 Django 查询集联合操作。

      最后一个,方法有点pythonic。试试这样:

      a = ModelA.objects.values_list('text_a', 'title', 'other_column')
      b = ModelB.objects.values_list('text_a', 'title')
      
      union_list = list()
      
      for i in range(0, len(a)):
           if b[i] not in a[i]:
               union_list.append(b[i])
           union_list.append(a[i])
      

      希望对你有帮助!!

      【讨论】:

        猜你喜欢
        • 2015-10-13
        • 2017-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-19
        • 2015-12-24
        • 1970-01-01
        相关资源
        最近更新 更多