mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 13:51:09 -05:00
138 lines
4.6 KiB
Python
138 lines
4.6 KiB
Python
"""
|
|
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>
|
|
"""
|