视图中的自定义查询?


24

在某个时候,我发现有必要修改由Views生成的SQL查询,最后我覆盖views_pre_execute并更改了该特定View的查询。

这对我来说就像一个丑陋的骇客,我想知道是否有一种更优雅,更可维护的方式来做到这一点。理想的方法是允许我直接从Views UI修改查询。


1
这取决于您要如何修改该查询。您到底想完成什么?
杰森·史密斯

@Jason我当时在SO上发布了一个问题:stackoverflow.com/questions/3147916/…但是这个问题现在已经解决了,我只是在寻找一种优雅的方式来修改任何Views查询(如果需要)。
疯狂的科学家

我不相信您无法仅使用视图来完成您在其他线程中试图做的事情。也就是说,给这只猫剥皮的方法远远不止一种。
杰森·史密斯

如果以下是您想要的答案,则应接受一个答案(单击投票数下方的复选标记)
Chaulky 2011年

hook_views_pre_execute可能不是最优雅的,但是它确实可以用于复杂的查询覆盖(请参阅Drupal 7中的Custom Views 3查询
mrP

Answers:


25

您还可以hook_views_query_alter()在运行查询之前先对其进行更改。我认为这类似于hook_views_pre_execute,但是使修改查询更容易。您基本上可以通过键控数组访问查询的每个部分。我没有找到很多官方文档,但是在https://www.appnovation.com/blog/using-hook-views-query-alter上有一个很好的例子。这也是我用来修复“日历”模块中日期错误的方法。


这也可以与Views-3一起使用吗?
markdorison 2011年

@markdorison我相信,但尚未确认
Chaulky 2011年

3
我已经确认这可以在Views-3中使用。
markdorison 2011年

1
@Fabian,如果它对您有用,则应接受此答案,或者评论为什么它没有用,以便我们可以做得更好
Chaulky 2011年

在简单的自定义模块中使用的Drupal 7中有关Custom Views 3查询的另一个示例参考hook_views_pre_execute()
mrP

4

通常,这取决于您的用例。

如果您想要一个应该以某种方式运行的字段/过滤器/参数,建议为它编写一个处理程序。有关更多信息,请参见视图的高级帮助。

如果要更改查询的某些部分,还可以使用hook_views_query_alter()。不好的hook_views_query_alter()是,您不能真正在此处重用代码。

这是文档中显示的示例代码。它给出了钩子可以做什么的示例。

function mymodule_views_query_alter(&$view, &$query) {
  // (Example assuming a view with an exposed filter on node title.)
  // If the input for the title filter is a positive integer, filter against
  // node ID instead of node title.
  if ($view->name == 'my_view' && is_numeric($view->exposed_raw_input['title']) && $view->exposed_raw_input['title'] > 0) {
    // Traverse through the 'where' part of the query.
    foreach ($query->where as &$condition_group) {
      foreach ($condition_group['conditions'] as &$condition) {
        // If this is the part of the query filtering on title, chang the
        // condition to filter on node ID.
        if ($condition['field'] == 'node.title') {
          $condition = array(
            'field' => 'node.nid', 
            'value' => $view->exposed_raw_input['title'], 
            'operator' => '=',
          );
        }
      }
    }
  }
}

3

我曾经使用过hook_views_query_alter()更改视图mysql查询。以下示例在Drupal 7下使用进行了测试7.x-3.0,它ORDER BY为查询添加了一个自定义子句:

 function MYTHEME_views_query_alter(&$view, &$query) {
   // check so it's the correct view
   if($view->name == 'product_view') {
     // set a custom 'ORDER BY' clause in the query
     $query->orderby[0] = array(
       'field' => 'SUBSTR(taxonomy_term_data_name,3,4)',
       'direction' => 'ASC'
     );
     $query->orderby[1] = array(
       'field' => 'SUBSTR(taxonomy_term_data_name,1,2)',
       'direction' => 'ASC'
     );
   }
 }

1

我不知道您是否可以直接更改sql,但是您可以编写自己的字段处理程序并编写自己的查询。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.