可搜索字段的 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 种方法可以修复您的具体示例:
- 将您的 DataObjects 数据库字段重命名为
Name
或 Title
- 覆盖 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;
}
我使用 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 种方法可以修复您的具体示例:
- 将您的 DataObjects 数据库字段重命名为
Name
或Title
- 覆盖 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;
}