Пользовательский запрос в представлениях?

24

В какой-то момент я обнаружил необходимость изменить запрос SQL, сгенерированный представлениями, в конце я переопределил views_pre_executeи изменил запрос для этого конкретного представления.

Это похоже на уродливый хак для меня, и мне интересно, есть ли более элегантный и удобный способ сделать это. Идеальный вариант - это способ, позволяющий мне напрямую изменять запрос из пользовательского интерфейса Views.

Сумасшедший ученый
источник
1
Это зависит от того, как вы хотели изменить этот запрос. Что именно вы пытались достичь?
Джейсон Смит
@ Джейсон Я отправил вопрос в SO в то время: stackoverflow.com/questions/3147916/… Но эта проблема решена сейчас, я просто ищу элегантный способ изменить любой запрос Views, если мне нужно.
Безумный ученый
Я не уверен, что вы не можете выполнить то, что пытались сделать в другом потоке, просто используя представления. Тем не менее, есть гораздо больше, чем один способ снять шкуру с этой кошкой.
Джейсон Смит
Если какой-либо из приведенных ниже ответов является тем, что вы искали, вам следует принять его (нажмите на галочку под счетчиком голосов)
Чолки
hook_views_pre_execute может быть не самым элегантным, но у него есть место для сложных переопределений запросов (см. Пользовательские представления 3 запросов в Drupal 7 )
mrP

Ответы:

25

Вы также можете использовать hook_views_query_alter()для изменения запроса перед его выполнением. Я думаю, что это похоже на hook_views_pre_execute, но облегчает изменение запроса. Вы в основном получаете доступ к каждой части запроса через массив ключей. Я не нашел много официальной документации, но есть хороший пример на https://www.appnovation.com/blog/using-hook-views-query-alter . Это также подход, который я должен был использовать, чтобы исправить ошибку даты в модуле Календарь.

Chaulky
источник
Будет ли это работать и с Views-3?
Маркдорисон
@markdorison Я верю в это, но не подтвердил это
Чолки
3
Я подтвердил, что это работает в Views-3.
Markdorison
1
@Fabian, ты должен принять этот ответ, если он был полезен для тебя, или прокомментировать, почему это не так, чтобы мы могли сделать его лучше
Чолки
Еще один пример ссылки для пользовательских представлений 3 запросов в Drupal 7 с использованием 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'
     );
   }
 }
Cyclonecode
источник
1

Я не знаю, можете ли вы напрямую изменить sql, но вы можете написать свой собственный обработчик полей и создать свой собственный запрос.

EricSchaefer
источник