mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 17:11:09 -05:00
Add search app configuration, views, and templates for advanced filtering functionality
This commit is contained in:
137
search/examples.py
Normal file
137
search/examples.py
Normal file
@@ -0,0 +1,137 @@
|
||||
"""
|
||||
Examples of how to use the search/filter system in different contexts.
|
||||
These are example implementations - DO NOT import or use this file directly.
|
||||
"""
|
||||
|
||||
from django.views.generic import ListView
|
||||
from django_filters import CharFilter, ChoiceFilter, NumberFilter, DateFromToRangeFilter
|
||||
from django.db.models import Q
|
||||
|
||||
from .mixins import HTMXFilterableMixin
|
||||
from .filters import LocationFilterMixin, RatingFilterMixin, DateRangeFilterMixin, create_model_filter
|
||||
|
||||
# Example 1: Basic List View with Filtering
|
||||
"""
|
||||
class RideListView(HTMXFilterableMixin, ListView):
|
||||
model = Ride
|
||||
template_name = "rides/ride_list.html"
|
||||
paginate_by = 20
|
||||
|
||||
# Define search fields for text search
|
||||
search_fields = ['name', 'description', 'manufacturer__name']
|
||||
|
||||
# Add any model-specific filters
|
||||
additional_filters = {
|
||||
'category': ChoiceFilter(choices=Ride.CATEGORY_CHOICES),
|
||||
'manufacturer': ModelChoiceFilter(queryset=Manufacturer.objects.all()),
|
||||
'status': ChoiceFilter(choices=Ride.STATUS_CHOICES),
|
||||
}
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().select_related('park', 'manufacturer')
|
||||
"""
|
||||
|
||||
# Example 2: Using create_model_filter for Dynamic Filter Creation
|
||||
"""
|
||||
# Create a filter for Company model
|
||||
CompanyFilter = create_model_filter(
|
||||
model=Company,
|
||||
search_fields=['name', 'description', 'headquarters'],
|
||||
mixins=[LocationFilterMixin, DateRangeFilterMixin],
|
||||
additional_filters={
|
||||
'min_parks': NumberFilter(
|
||||
field_name='parks__count',
|
||||
lookup_expr='gte',
|
||||
label='Minimum Parks'
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
class CompanyListView(HTMXFilterableMixin, ListView):
|
||||
model = Company
|
||||
filter_class = CompanyFilter
|
||||
template_name = "companies/company_list.html"
|
||||
"""
|
||||
|
||||
# Example 3: Custom Filter Implementation
|
||||
"""
|
||||
class ManufacturerFilter(FilterSet):
|
||||
search = CharFilter(method='filter_search')
|
||||
country = ChoiceFilter(choices=COUNTRY_CHOICES)
|
||||
founded_date = DateFromToRangeFilter()
|
||||
min_rides = NumberFilter(field_name='rides__count', lookup_expr='gte')
|
||||
|
||||
class Meta:
|
||||
model = Manufacturer
|
||||
fields = {
|
||||
'status': ['exact'],
|
||||
'type': ['exact', 'in'],
|
||||
}
|
||||
|
||||
def filter_search(self, queryset, name, value):
|
||||
if not value:
|
||||
return queryset
|
||||
return queryset.filter(
|
||||
Q(name__icontains=value) |
|
||||
Q(description__icontains=value) |
|
||||
Q(rides__name__icontains=value)
|
||||
).distinct()
|
||||
"""
|
||||
|
||||
# Example 4: Custom Template Implementation
|
||||
"""
|
||||
{# templates/search/partials/ride_results.html #}
|
||||
<div class="divide-y">
|
||||
{% for ride in object_list %}
|
||||
<div class="p-4 flex items-start space-x-4">
|
||||
{% if ride.photos.exists %}
|
||||
<img src="{{ ride.photos.first.image.url }}"
|
||||
alt="{{ ride.name }}"
|
||||
class="w-24 h-24 object-cover rounded-lg">
|
||||
{% endif %}
|
||||
|
||||
<div class="flex-1">
|
||||
<h3 class="text-lg font-semibold">
|
||||
<a href="{{ ride.get_absolute_url }}">{{ ride.name }}</a>
|
||||
</h3>
|
||||
|
||||
<div class="mt-1 text-sm text-gray-500">
|
||||
{{ ride.get_category_display }} at
|
||||
<a href="{{ ride.park.get_absolute_url }}"
|
||||
class="text-blue-600 hover:underline">
|
||||
{{ ride.park.name }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if ride.manufacturer %}
|
||||
<div class="mt-1 text-sm">
|
||||
Built by {{ ride.manufacturer.name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ ride.get_status_color }}">
|
||||
{{ ride.get_status_display }}
|
||||
</span>
|
||||
|
||||
{% if ride.opening_date %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
|
||||
Opened {{ ride.opening_date|date:"Y" }}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% if ride.average_rating %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
||||
{{ ride.average_rating }} ★
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="p-8 text-center text-gray-500">
|
||||
No rides found matching your criteria
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
"""
|
||||
Reference in New Issue
Block a user