当前位置: 首页 > 编程笔记 >

Drupal 8:在视图中创建子查询

商茂勋
2023-03-14
本文向大家介绍Drupal 8:在视图中创建子查询,包括了Drupal 8:在视图中创建子查询的使用技巧和注意事项,需要的朋友参考一下

您以前可能去过那里。您正在使用的Drupal View看起来很棒,并且具有您需要的所有数据和字段,但是当您仔细查看结果时,您会发现有些问题。查看生成的SQL查询后,您会发现其中一个联接存在问题,这会导致计数减少。最终,您需要删除此联接,但实际上您需要包含在结果中的数据。

创建子查询可以使您从特定字段中提取数据,而无需添加另一个导致结果不正确的联接。

前几天我在一个视图中遇到了这个问题,该视图合并了“下载计数”模块中的数据。此模块记录用户在您的站点上下载文件的操作。尽管确实提供了一些Views集成,但我添加了其他一些关系,这些关系导致下载计数不正确。经过一番调查后,我知道我需要创建一个子查询以将下载计数的值注入到View的输出中。

做到这一点的最佳方法是创建一个View字段处理程序,该处理程序将在字段设置中创建一个子查询。要创建字段处理程序插件,您需要在my_module / src / Plugin / views / field位置创建一个类。以下是一个名为FileDownloadCount的类,该类扩展了默认的NumericField Views字段。这是在类级别的注释,它使Views可以了解此字段,因此这一点非常重要。我的插件的完整文件路径为my_module / src / Plugin / views / field / FileDownloadCount.php。

<?php
 
namespace Drupal\my_module\Plugin\views\field;
 
use Drupal\views\Plugin\views\field\NumericField;
use Drupal\views\ResultRow;
 
/**
 * Field handler for search score.
 *
 * @ingroup views_field_handlers
 *
 * @ViewsField("file_download_count")
 */
class FileDownloadCount extends NumericField {
 
}

Views会自动拾取它,但是直到我们添加一些其他方法后它才做任何事情。

我们需要添加的第一件事是一种query()方法,以便Views知道子查询并将其添加到显示输出中。通过创建数据库查询的新实例,然后将其作为联接添加到主查询中来创建子查询,就好像它是真实表一样。此处的子查询(由于我要获取的数据)取决于file_managed表,因此这构成了我们创建的联接的基础。

这是完整的方法,带有注释以帮助分解发生的情况。

/**
 * {@inheritdoc}
 */
public function query() {
  // 将子查询添加到查询中,以找到下载计数。
  $subQuery = \Drupal::database()->select('download_count', 'download_count');
  $subQuery->addField('download_count', 'fid');
  $subQuery->addExpression("COUNT(fid)", 'file_download_count');
  $subQuery->groupBy("download_count.fid");
 
  // 将子查询添加为联接的组件。
  $joinDefinition = [
    'table formula' => $subQuery,
    'field' => 'fid',
    'left_table' => 'file_managed',
    'left_field' => 'fid',
    'adjust' => TRUE,
  ];
 
  // 创建一个连接对象,并在主查询和子查询之间创建一个关系。
  $join = \Drupal::service('plugin.manager.views.join')->createInstance('standard', $joinDefinition);
  $this->query->addRelationship('download_data', $join, 'file_managed');
 
  // 将字段添加到“视图”界面。
  $this->query->addField(NULL, 'file_download_count', 'file_download_count');
}

现在,我们已经有了子查询,并且在主查询中添加了字段,因此我们现在需要的数据将通过。最重要的是,查询的输出为null时的默认值。如果从未下载过文件,则将返回此值,因此在项目开始时会非常定期地进行,并且此功能也很难通过以前的测试。为了解决这个问题,我们只需要检测该值是否为null并使用render()方法将其重置为0 。

/**
 * {@inheritdoc}
 */
public function render(ResultRow $values) {
  if (is_null($values->file_download_count)) {
    // 确保将空值打印为0。
    $values->file_download_count = 0;
  }
  return parent::render($values);
}

当渲染输出时,Views会自动调用该渲染。

最后,最好还让您的新字段具有单击排序功能,这在创建表时尤为重要,因为允许对列进行排序是一个非常好的功能。为此,您需要创建一个名为的方法clickSort(),该addOderBy()方法在查询中调用该方法。当需要按字段对视图进行排序时,视图将自动调用此方法。

/**
 * {@inheritdoc}
 */
public function clickSort($order) {
  if (isset($this->field_alias)) {
    $params = $this->options['group_type'] != 'group' ? ['function' => $this->options['group_type']] : [];
    $this->query->addOrderBy(NULL, 'file_download_count', $order, $this->field_alias, $params);
  }
}

一切就绪后,我们只需要像普通字段一样将此字段添加到视图中即可。您还需要在“视图”表输出中配置排序,以使排序也能正常工作。

我在互联网上看到了几篇文章,展示了如何在Views中创建子查询,但是它们往往会遗漏将数据也添加到View输出中的关键项。上面的解决方案将添加子查询并将数据添加到您的视图中,以便您可以执行一些操作。

 类似资料:
  • 我想创建一个名为的视图,该视图显示个人的所有信息,除了他们的客户ID之外,还列出每个人在他/她的帐户中有多少余额。 我的疑问是: 现在,这个查询将创建视图,但当我想通过以下命令查看该视图中的信息时: 它将返回一个错误: 如何走出这个误区?

  • 问题内容: 我正在使用Jenkins和ClearCase进行自动构建,但是有问题。我编写了一个批处理脚本,以使用cleartool命令mkview在ClearCase中创建视图。 当我通过单击脚本执行脚本时,一切正常,该视图在ClearCase中创建。但是,当我通过Jenkins启动脚本时,出现以下错误: 我非常确定该错误来自访问权限问题。 但是我没有找到类似的选项来使用我的clearcase用户

  • 视图概述 视图作为MVC模式中的终端环节,在web编程中负责dom结构的展示。grace 使用 php作为“天然模板“,您不必再去学习枯燥无聊的模板语法,系统更不必浪费资源去完成复杂的解析工作! 视图文件创建及命名规则 视图文件命名 : 1、控制器名称_方法名称.php //此种命名系统会进行自动展示 2、视图名称.php //需要手动调用 视图文件位置 : /分组文件夹/views/对应视图文件

  • 问题内容: 我有一个包含子视图的视图控制器。在子视图类中,当满足某些条件时,我可能需要弹出警报。 从代码中可以看到,由于我的子视图不是控制器类,因此无法调用presentViewController函数来显示警报。我应该以某种方式在子视图内创建对父控制器的一周引用吗?实施此类参考的最佳实践是什么? 问题答案: 有几种方法可以使您抓住自己的生活。 您可以将任何视图控制器作为 委托 来显示警报; 您可

  • 我知道如何在MVC中创建视图。

  • 关于创建视频图像 Photoshop 可以创建具有各种长宽比的图像,以便它们能够在设备(如视频显示器)上正确显示。可以选择特定的视频选项(使用“新建”对话框)以便对将最终图像合并到视频中时进行的缩放提供补偿。 安全区域 “胶片和视频”预设还会创建带有非打印参考线的文档,参考线可画出图像的动作安全区域和标题安全区域的轮廓。使用“大小”菜单中的选项,可以生成用于特定视频系统(NTSC、PAL 或 HD