如何修改EmberJS代码适配Django REST API的复选框筛选参数格式?
Problem Statement
I'm using EmberJS to interface with a Django REST API, implementing data filtering via checkboxes. Here's my template code:
<label>Certificate</label> <div> <div> <div class="form-group-checkbox"> {{input type="checkbox" checked=certA id="certificate_A"}} <label for="certificate_A">A</label> </div> <div class="form-group-checkbox"> {{input type="checkbox" checked=certB id="certificate_B"}} <label for="certificate_B">B</label> </div> <div class="form-group-checkbox"> {{input type="checkbox" checked=certC id="certificate_C"}} <label for="certificate_C">C</label> </div> </div> </div>
Right now, the API request generates a query string like:.../Search?certificate_A=true&certificate_B=true
But the Django REST API expects parameters in a string array format:../Search?certification=certificate_A&certification=certificate_B
Solution
I've tackled this exact mismatch before—Ember's default checkbox binding doesn't play nice with Django's expected array-style params, but we can fix it with a few straightforward steps:
1. Track Selected Certifications with a Computed Property
First, in your controller or component, create a computed property that collects the IDs of checked certificates. This keeps the selected list in sync with checkbox states automatically.
// app/controllers/your-search-controller.js import Controller from '@ember/controller'; import { computed } from '@ember/object'; export default class YourSearchController extends Controller { // Initialize default checkbox states certA = false; certB = false; certC = false; // Build the list of selected certification IDs @computed('certA', 'certB', 'certC') get selectedCertifications() { const selected = []; if (this.certA) selected.push('certificate_A'); if (this.certB) selected.push('certificate_B'); if (this.certC) selected.push('certificate_C'); return selected; } }
2. Pass the Array as Query Parameters to the API
When making your API request, use the selectedCertifications array as the value for the certification parameter. Ember handles converting arrays into multiple instances of the same query param—exactly what Django expects.
Option A: Using Ember Data
If you're using Ember Data to fetch records, pass the array directly in the query options:
// In your controller or route this.store.query('your-model-name', { certification: this.selectedCertifications }).then(results => { // Handle the returned data });
Option B: Using Raw Fetch/Ajax
If you're using a raw fetch call, construct the query params manually with URLSearchParams:
const params = new URLSearchParams(); this.selectedCertifications.forEach(cert => { params.append('certification', cert); }); fetch(`/Search?${params.toString()}`) .then(response => response.json()) .then(data => { // Process the response data });
3. (Optional) Sync with Route Query Params
If you want checkbox selections to persist in the URL and trigger model refreshes automatically, set up route query params:
Route File:
// app/routes/your-search-route.js import Route from '@ember/routing/route'; export default class YourSearchRoute extends Route { queryParams = { certification: { refreshModel: true, // Refresh the model when params change as: 'certification' } }; model(params) { // Fetch data using the query params return this.store.query('your-model-name', params); } }
Controller File (Updated):
// app/controllers/your-search-controller.js import Controller from '@ember/controller'; import { computed } from '@ember/object'; export default class YourSearchController extends Controller { queryParams = ['certification']; certification = []; // Bind to the route's query param // Map query param array to checkbox states @computed('certification.[]') get certA() { return this.certification.includes('certificate_A'); } @computed('certification.[]') get certB() { return this.certification.includes('certificate_B'); } @computed('certification.[]') get certC() { return this.certification.includes('certificate_C'); } }
Why This Works
Django REST API automatically parses multiple instances of the same query parameter into a list. When you send certification=certificate_A&certification=certificate_B, you can retrieve the array in your Django view using request.query_params.getlist('certification'), which returns ['certificate_A', 'certificate_B']—perfectly matching the API's requirements.
内容的提问来源于stack exchange,提问作者Rohan

