Please check your agent type and version and read on or switch to the right documentation.
Smart Segments
What is a Smart Segment?
A Segment is a subset of a collection: it's basically a saved filter of your collection.
Segments are designed for those who want to systematically visualize data according to specific sets of filters. It allows you to save your filters configuration so you don’t have to compute the same actions every day.
A Smart Segments is useful when you want to use a complex filter, which you'll add as code in your backend.
Creating a Smart Segment
Sometimes, segment filters are complicated and closely tied to your business. Forest Admin allows you to code how the segment is computed.
On our Live Demo example, we’ve implemented a Smart Segment on the collection products to allow admin users to see the bestsellers at a glance.
You’re free to implement the business logic you need. The only requirement is to return a valid Sequelize condition. Most of the time, your Smart Segment should return something like { id: { in: [ 1,2,3,4,5 ] } }.
On our implementation, we use a raw SQL query to filter and sort the product that was sold the most.
/forest/products.js
const { collection } =require('forest-express-sequelize');constmodels=require('../models');const { Op,QueryTypes } =models.objectMapping;collection('products', { segments: [ { name:'Bestsellers',where: (product) => {returnmodels.connections.default.query(` SELECT products.id, COUNT(orders.*) FROM products JOIN orders ON orders.product_id = products.id GROUP BY products.id ORDER BY count DESC LIMIT 5; `, { type:QueryTypes.SELECT } ).then((products) => {let productIds =products.map((product) =>product.id);return { id: { [Op.in]: productIds } }; }); }, }, ],});
You’re free to implement the business logic you need. Your Smart Segment should return something like { _id: { $in: [ 1,2,3,4,5 ] } }.
from django.db.models import Qfrom django_forest.utils.collection import Collectionfrom app.models import ProductclassProductForest(Collection):defload(self): self.segments = [{'name':'Best sellers','where': self.best_sellers} ]defbest_sellers(self): products = Question.objects.raw('''SELECT app_product.id, COUNT(app_order.*) FROM app_product JOIN app_order ON app_order.product_id = app_product.id GROUP BY app_product.id ORDER BY count DESC LIMIT 5;''')returnQ(**{'id__in': [product.id for product in products]})Collection.register(ProductForest, Product)
Ensure the file app/forest/__init__.py exists and contains the import of the previous defined class :
app/forest/__init__.py
from app.forest.product import ProductForest
The 2nd parameter of the SmartSegment method is not required. If you don't fill it, the name of your SmartSegment will be the name of your method that wrap it.