Sonata DataGridFilter:Doctrine ORM Model类型自定义过滤值查询咨询
在Sonata DataGridFilter中自定义doctrine_orm_model的过滤选项
当然可以!我之前在项目里也遇到过类似需求——不想让doctrine_orm_model过滤器加载对应实体的全部数据,下面给你两种实用的实现方式:
方法一:直接在Filter配置中传入自定义QueryBuilder
这是最直接的方式,你可以在Admin类的configureDatagridFilters方法里,给ModelFilter的field_options传入自定义的query_builder闭包,以此来限制下拉框的可选值:
use Sonata\DoctrineORMAdminBundle\Filter\ModelFilter; use App\Entity\RelatedEntity; use Doctrine\ORM\EntityRepository; protected function configureDatagridFilters(DatagridMapper $datagridMapper): void { $datagridMapper ->add('relatedEntity', ModelFilter::class, [ 'label' => '关联实体', 'field_options' => [ 'class' => RelatedEntity::class, 'query_builder' => function (EntityRepository $repo) { // 这里写你的自定义查询逻辑,比如只返回启用状态的实体 return $repo->createQueryBuilder('re') ->where('re.isEnabled = :enabled') ->setParameter('enabled', true) ->orderBy('re.name', 'ASC'); }, ], ]); }
这个闭包会接收对应实体的Repository实例,你可以在这里构建任意符合需求的QueryBuilder,最终下拉框只会显示符合条件的实体数据。
方法二:自定义Filter类型实现复用逻辑
如果这个自定义过滤逻辑需要在多个Admin类中复用,或者逻辑比较复杂,你可以创建一个自定义的Filter类,继承自ModelFilter,然后重写相关方法来注入自定义查询:
use Sonata\DoctrineORMAdminBundle\Filter\ModelFilter; use Doctrine\ORM\EntityRepository; class EnabledEntityFilter extends ModelFilter { protected function getFormOptions(): array { $options = parent::getFormOptions(); // 注入统一的自定义QueryBuilder逻辑 $options['query_builder'] = function (EntityRepository $repo) { return $repo->createQueryBuilder('e') ->where('e.isEnabled = :enabled') ->setParameter('enabled', true) ->orderBy('e.name', 'ASC'); }; return $options; } }
然后在Admin类中使用这个自定义Filter:
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void { $datagridMapper ->add('relatedEntity', EnabledEntityFilter::class, [ 'label' => '关联实体', 'field_options' => [ 'class' => RelatedEntity::class, ], ]); }
小提示
如果你的自定义查询需要依赖其他服务(比如参数容器、其他Repository),可以在自定义Filter的构造函数里注入这些服务,这样就能实现更复杂的业务逻辑啦~
内容的提问来源于stack exchange,提问作者Henne Van Och
相关产品推荐
相关产品推荐

