Django与queryset-values不同的queryset

时间:2019-02-07 16:48:46

标签: python django django-queryset distinct

我有一个User,可以有多个Account。每个Unit上可以有多个Account。 我建立了一个过滤字典并获得了相关单位:

units = Unit.objects.filter(**unit_filter)

但是,我也想吸引不同的用户。我可以轻松获得他们的ID:

user_dicts = units.values('account__user').distinct()

或更准确地说:

user_ids = [rec.get('account__user') for rec in 
            units.values('account__user').distinct()]

因此,我可以使用User.objects.filter(id__in=user_ids)过滤用户。 (我也可以使用生成器表达式代替列表理解,但这不是重点。)

我不确定,但是评估id in在我看来不是很有效。是否有更好的方法来从过滤后的单元中获取唯一身份用户?


编辑:

我添加了SQL查询(没有对其进行测试,可能是错误的),以使我在Django ORM中尝试执行的操作显而易见。实际上,我正在尝试使用JOIN而不是WHERE子句。

我希望如此:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id
  JOIN unit ut ON ut.account=a.id 
  JOIN selected_units s ON s.id=ut.id;

但是有了id_in,我得到了:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id 
  JOIN unit ut ON ut.account_id=a.id 
WHERE ut.id IN (SELECT id FROM selected_units);

1 个答案:

答案 0 :(得分:0)

我认为您可以使用子查询来完成此操作,例如:

let serviceBusConnectionArray = [];
let executed = false;
let serviceBusService;
let count = 0;
let MAX_CONNECTIONS = 5;

class ServiceBus {

  static createConnections(){
    if(!executed){
      for(let i=0; i< MAX_CONNECTIONS; i++){
        serviceBusConnectionArray.push(azure.createServiceBusService(SERVICEBUS_CONNECTION_STRING).withFilter(new azure.ExponentialRetryPolicyFilter()));
      }
      executed = true;
    }
  }
  static getConnectionString(){
    ServiceBus.createConnections();
    if(count < MAX_CONNECTIONS){
      return serviceBusConnectionArray[count++];
    }else{
      count = 0;
      return serviceBusConnectionArray[count];
    }
  }

  static putMessageToServiceBus(topicName, message) {
    return new Promise((resolve, reject) => {
      serviceBusService = ServiceBus.getConnectionString();
      serviceBusService.sendTopicMessage(topicName, message, function (error) {
        if (error) {
          log.error('Error in putting message to service bus, message: %s', error.stack);
          reject(error);
        }
        resolve('Message added');
      });
    });
  }

}

或更漂亮:

User.objects.filter(account__unit__in=units)