可搜索字段的 ModelAdmin 自定义

ModelAdmin Customization of Searchable fields

我使用 Silverstripes 的 ORM 在产品和类别之间建立了多对多关系。一切正常,除了当我尝试为产品添加类别时,类别的选择由用户 ID 而不是类别名称显示。我试图将 ID 映射到名称,但没有成功。以下是我尝试过的,我错过了什么?

class Product extends DataObject {

  private static $db = array(
    'ProductName' => 'Varchar(32)',
    );

  private static $many_many = array (
    'Category' => 'Category'
  );
}


class Category extends DataObject {

  private static $db = array(
    'Category' => 'Varchar(32)',
    );

  public function searchableFields() {
    return array (
      'Category' => array (
        'filter' => 'ExactMatchFilter',
        'title' => 'Category',
        'field' => 'TextField'->setSource(
                        $this::get()->map('ID','Category')
                    )
      )   
    );
  }

  private static $belongs_many_many = array (
    'Product' => 'Product'
  );
}

当 Silverstripe 需要为 DataObject 显示 shorthand 时,它将调用该 DataObject 的 getTitle() 方法。

getTitle() 将首先检查 DataObject 是否有 Title 字段,如果有则 return 该值。

如果您的 DataObject 没有 Title 字段,它将尝试搜索 Name 字段。

如果它也找不到 Name 字段,它将默认 returning 您的 DataObject 的 ID,这可能就是您正在发生的情况。

如何修复您的具体示例

有 2 种方法可以修复您的具体示例:

  1. 将您的 DataObjects 数据库字段重命名为 NameTitle
  2. 覆盖 2 个数据对象的 getTitle() 方法

解决方案 #1

class Product extends DataObject {

  private static $db = array(
    'Name' => 'Varchar(32)',
    );

  private static $many_many = array (
    'Category' => 'Category'
  );
}


class Category extends DataObject {

  private static $db = array(
    'Name' => 'Varchar(32)',
    );

  public function searchableFields() {
    return array (
      'Category' => array (
        'filter' => 'ExactMatchFilter',
        'title' => 'Category',
        'field' => 'TextField'->setSource(
                        $this::get()->map('ID','Category')
                    )
      )   
    );
  }

  private static $belongs_many_many = array (
    'Product' => 'Product'
  );
}

解决方案#2

class Product extends DataObject {

  private static $db = array(
    'ProductName' => 'Varchar(32)',
    );

  private static $many_many = array (
    'Category' => 'Category'   );

  public function getTitle() {
    return $this->ProductName;   
  }
}


class Category extends DataObject {

  private static $db = array(
    'Category' => 'Varchar(32)',
    );

  public function searchableFields() {
    return array (
      'Category' => array (
        'filter' => 'ExactMatchFilter',
        'title' => 'Category',
        'field' => 'TextField'->setSource(
                        $this::get()->map('ID','Category')
                    )
      )   
    );   }

  private static $belongs_many_many = array (
    'Product' => 'Product'   );

  public function getTitle() {
    return $this->Category;
  }

}

哪种解决方案最好?

在您的具体情况下,我会选择解决方案 #1,因为您的数据库字段在功能上是 name/title 个字段。

如果我的 DataObject 的标题需要使用很多字段,我会使用解决方案 #2。假设您有 Person 个具有名字和姓氏的数据对象:

public function getTitle() {
  return $this->FirstName . ' ' . $this->LastName;
}