mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 10:31:09 -05:00
3.2 KiB
3.2 KiB
Search Functionality Improvement Plan
Technical Implementation Details
1. Database Optimization
# parks/models.py
from django.contrib.postgres.indexes import GinIndex
class Park(models.Model):
class Meta:
indexes = [
GinIndex(fields=['name', 'description'],
name='search_gin_idx',
opclasses=['gin_trgm_ops', 'gin_trgm_ops']),
Index(fields=['location__address_text'], name='location_addr_idx')
]
# search/services.py
from django.db.models import F, Func
from analytics.models import SearchMetric
class SearchEngine:
@classmethod
def execute_search(cls, request, filterset_class):
with timeit() as timer:
filterset = filterset_class(request.GET, queryset=cls.base_queryset())
qs = filterset.qs
results = qs.annotate(
search_rank=Func(F('name'), F('description'),
function='ts_rank')
).order_by('-search_rank')
SearchMetric.record(
query_params=dict(request.GET),
result_count=qs.count(),
duration=timer.elapsed
)
return results
2. Architectural Changes
# search/filters.py (simplified explicit filter)
class ParkFilter(SearchableFilterMixin, django_filters.FilterSet):
search_fields = ['name', 'description', 'location__address_text']
class Meta:
model = Park
fields = {
'ride_count': ['gte', 'lte'],
'coaster_count': ['gte', 'lte'],
'average_rating': ['gte', 'lte']
}
# search/views.py (updated)
class AdaptiveSearchView(TemplateView):
def get_queryset(self):
return SearchEngine.base_queryset()
def get_filterset(self):
return ParkFilter(self.request.GET, queryset=self.get_queryset())
3. Frontend Enhancements
// static/js/search.js
const searchInput = document.getElementById('search-input');
let timeoutId;
searchInput.addEventListener('input', () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fetchResults(searchInput.value);
}, 300);
});
async function fetchResults(query) {
try {
const response = await fetch(`/search/?search=${encodeURIComponent(query)}`);
if (!response.ok) throw new Error(response.statusText);
const html = await response.text();
updateResults(html);
} catch (error) {
showError(`Search failed: ${error.message}`);
}
}
Implementation Roadmap
- Database Migrations
uv run manage.py makemigrations parks --name add_search_indexes
uv run manage.py migrate
- Service Layer Integration
- Create search/services.py with query instrumentation
- Update all views to use SearchEngine class
- Frontend Updates
- Add debouncing to search inputs
- Implement error handling UI components
- Add loading spinner component
- Monitoring Setup
# analytics/models.py
class SearchMetric(models.Model):
query_params = models.JSONField()
result_count = models.IntegerField()
duration = models.FloatField()
created_at = models.DateTimeField(auto_now_add=True)
- Performance Testing
- Use django-debug-toolbar for query analysis
- Generate load tests with locust.io