mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-23 02:11:08 -05:00
feat: Refactor rides app with unique constraints, mixins, and enhanced documentation
- Added migration to convert unique_together constraints to UniqueConstraint for RideModel. - Introduced RideFormMixin for handling entity suggestions in ride forms. - Created comprehensive code standards documentation outlining formatting, docstring requirements, complexity guidelines, and testing requirements. - Established error handling guidelines with a structured exception hierarchy and best practices for API and view error handling. - Documented view pattern guidelines, emphasizing the use of CBVs, FBVs, and ViewSets with examples. - Implemented a benchmarking script for query performance analysis and optimization. - Developed security documentation detailing measures, configurations, and a security checklist. - Compiled a database optimization guide covering indexing strategies, query optimization patterns, and computed fields.
This commit is contained in:
158
backend/docs/view_guidelines.md
Normal file
158
backend/docs/view_guidelines.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# View Pattern Guidelines
|
||||
|
||||
This document provides guidelines for implementing views in the ThrillWiki backend.
|
||||
|
||||
## When to Use CBVs
|
||||
|
||||
Use Class-Based Views for:
|
||||
- CRUD operations (CreateView, UpdateView, DetailView, ListView, DeleteView)
|
||||
- Complex views with multiple methods
|
||||
- Views that benefit from inheritance and mixins
|
||||
- Views with shared context or queryset logic
|
||||
|
||||
### CBV Examples
|
||||
|
||||
```python
|
||||
class ParkDetailView(OptimizedDetailView):
|
||||
"""Display park details with related data."""
|
||||
|
||||
model = Park
|
||||
template_name = "parks/park_detail.html"
|
||||
select_related_fields = ["location", "operator"]
|
||||
prefetch_related_fields = ["photos", "rides"]
|
||||
```
|
||||
|
||||
## When to Use FBVs
|
||||
|
||||
Use Function-Based Views for:
|
||||
- Simple HTMX partial renders
|
||||
- Single-purpose utility endpoints
|
||||
- Search/autocomplete endpoints
|
||||
- Status badge/action endpoints
|
||||
|
||||
### FBV Examples
|
||||
|
||||
```python
|
||||
def search_parks(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
HTMX endpoint for park search autocomplete.
|
||||
|
||||
View Type: FBV (HTMX Partial)
|
||||
URL Pattern: /parks/search/
|
||||
Returns: HTML partial
|
||||
"""
|
||||
query = request.GET.get("q", "").strip()
|
||||
parks = Park.objects.filter(name__icontains=query)[:10]
|
||||
return render(request, "parks/partials/search_results.html", {"parks": parks})
|
||||
```
|
||||
|
||||
## When to Use ViewSets
|
||||
|
||||
Use DRF ViewSets for:
|
||||
- REST API endpoints
|
||||
- Resources with standard CRUD operations
|
||||
- Resources requiring nested routing
|
||||
|
||||
### ViewSet Examples
|
||||
|
||||
```python
|
||||
class ParkPhotoViewSet(ModelViewSet):
|
||||
"""ViewSet for managing park photos via API."""
|
||||
|
||||
queryset = ParkPhoto.objects.all()
|
||||
serializer_class = ParkPhotoSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
```
|
||||
|
||||
## View Inventory
|
||||
|
||||
### Parks App
|
||||
- **CBVs**: ParkListView, ParkCreateView, ParkUpdateView, ParkDetailView, ParkAreaDetailView, OperatorListView
|
||||
- **FBVs**: geocode_location, reverse_geocode, search_parks, roadtrip_* (HTMX)
|
||||
|
||||
### Rides App
|
||||
- **CBVs**: RideDetailView, RideCreateView, RideUpdateView, RideListView, SingleCategoryListView, RideRankingsView, RideRankingDetailView, ManufacturerListView, DesignerListView
|
||||
- **FBVs**: show_coaster_fields, ride_status_actions, ride_header_badge, search_companies, search_ride_models, get_search_suggestions, ranking_history_chart, ranking_comparisons
|
||||
|
||||
### Accounts App
|
||||
- **CBVs**: ProfileView, SettingsView, CustomLoginView, CustomSignupView
|
||||
- **FBVs**: user_redirect_view, email_required, request_password_reset, reset_password
|
||||
|
||||
### Moderation App
|
||||
- **ViewSets**: ModerationReportViewSet, ModerationQueueViewSet, ModerationActionViewSet, BulkOperationViewSet, UserModerationViewSet
|
||||
|
||||
## View Type Indicators
|
||||
|
||||
Always include view type information in docstrings:
|
||||
|
||||
```python
|
||||
class ParkDetailView(DetailView):
|
||||
"""
|
||||
Display park details with related data.
|
||||
|
||||
View Type: CBV (DetailView)
|
||||
URL Pattern: /parks/<slug>/
|
||||
Template: parks/park_detail.html
|
||||
Permissions: Public
|
||||
"""
|
||||
|
||||
def search_parks(request: HttpRequest) -> HttpResponse:
|
||||
"""
|
||||
HTMX endpoint for park search autocomplete.
|
||||
|
||||
View Type: FBV (HTMX Partial)
|
||||
URL Pattern: /parks/search/
|
||||
Returns: HTML partial
|
||||
"""
|
||||
```
|
||||
|
||||
## Base Classes
|
||||
|
||||
### OptimizedListView
|
||||
|
||||
Automatically applies select_related and prefetch_related based on class attributes.
|
||||
|
||||
```python
|
||||
from apps.core.views.base import OptimizedListView
|
||||
|
||||
class RideListView(OptimizedListView):
|
||||
model = Ride
|
||||
select_related_fields = ['park', 'manufacturer']
|
||||
prefetch_related_fields = ['photos']
|
||||
```
|
||||
|
||||
### OptimizedDetailView
|
||||
|
||||
Automatically applies select_related and prefetch_related based on class attributes.
|
||||
|
||||
```python
|
||||
from apps.core.views.base import OptimizedDetailView
|
||||
|
||||
class RideDetailView(OptimizedDetailView):
|
||||
model = Ride
|
||||
select_related_fields = ['park', 'park__location', 'manufacturer']
|
||||
prefetch_related_fields = ['photos', 'coaster_stats']
|
||||
```
|
||||
|
||||
## Mixins
|
||||
|
||||
### RideFormMixin
|
||||
|
||||
Handles entity suggestions in ride forms (manufacturers, designers, models).
|
||||
|
||||
```python
|
||||
from apps.rides.mixins import RideFormMixin
|
||||
|
||||
class RideCreateView(RideFormMixin, CreateView):
|
||||
def form_valid(self, form):
|
||||
self.handle_entity_suggestions(form)
|
||||
return super().form_valid(form)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Prefer CBVs for CRUD** - Use Django's built-in generic views
|
||||
2. **Prefer FBVs for HTMX** - Simple endpoints are easier to understand as functions
|
||||
3. **Document view types** - Include View Type in all docstrings
|
||||
4. **Use mixins for shared logic** - Avoid code duplication
|
||||
5. **Use base classes for query optimization** - OptimizedListView, OptimizedDetailView
|
||||
Reference in New Issue
Block a user