160 lines
5.9 KiB
Python
160 lines
5.9 KiB
Python
from django.contrib import messages
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.db import IntegrityError
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from django.views import View
|
|
from django.views.generic import ListView, TemplateView, UpdateView
|
|
|
|
from .forms import SavedSearchForm
|
|
from .models import FavoritePlayer, SavedSearch
|
|
from .services.saved_searches import extract_filters_from_params, saved_search_to_querystring
|
|
|
|
|
|
class ScoutingHomeView(LoginRequiredMixin, TemplateView):
|
|
template_name = "scouting/index.html"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context["saved_searches"] = SavedSearch.objects.filter(user=self.request.user).order_by("-updated_at")
|
|
context["favorites"] = (
|
|
FavoritePlayer.objects.filter(user=self.request.user)
|
|
.select_related("player", "player__nationality", "player__nominal_position", "player__inferred_role")
|
|
.order_by("-created_at")
|
|
)
|
|
return context
|
|
|
|
|
|
class SavedSearchCreateView(LoginRequiredMixin, View):
|
|
def post(self, request, *args, **kwargs):
|
|
form = SavedSearchForm(request.POST)
|
|
if not form.is_valid():
|
|
if request.headers.get("HX-Request") == "true":
|
|
return render(
|
|
request,
|
|
"scouting/partials/save_search_feedback.html",
|
|
{"ok": False, "message": "Invalid name or visibility values."},
|
|
)
|
|
messages.error(request, "Could not save search.")
|
|
return redirect("players:index")
|
|
|
|
filters = extract_filters_from_params(request.POST)
|
|
if not filters:
|
|
message = "No valid filters to save from current search."
|
|
if request.headers.get("HX-Request") == "true":
|
|
return render(
|
|
request,
|
|
"scouting/partials/save_search_feedback.html",
|
|
{"ok": False, "message": message},
|
|
)
|
|
messages.error(request, message)
|
|
return redirect("players:index")
|
|
|
|
saved_search = form.save(commit=False)
|
|
saved_search.user = request.user
|
|
saved_search.filters = filters
|
|
try:
|
|
saved_search.save()
|
|
except IntegrityError:
|
|
message = "A saved search with this name already exists."
|
|
if request.headers.get("HX-Request") == "true":
|
|
return render(
|
|
request,
|
|
"scouting/partials/save_search_feedback.html",
|
|
{"ok": False, "message": message},
|
|
)
|
|
messages.error(request, message)
|
|
return redirect("players:index")
|
|
|
|
message = f"Saved search '{saved_search.name}' created."
|
|
if request.headers.get("HX-Request") == "true":
|
|
return render(
|
|
request,
|
|
"scouting/partials/save_search_feedback.html",
|
|
{"ok": True, "message": message},
|
|
)
|
|
|
|
messages.success(request, message)
|
|
return redirect("scouting:index")
|
|
|
|
|
|
class SavedSearchUpdateView(LoginRequiredMixin, UpdateView):
|
|
model = SavedSearch
|
|
form_class = SavedSearchForm
|
|
template_name = "scouting/saved_search_edit.html"
|
|
|
|
def get_queryset(self):
|
|
return SavedSearch.objects.filter(user=self.request.user)
|
|
|
|
def get_success_url(self):
|
|
messages.success(self.request, "Saved search updated.")
|
|
return reverse("scouting:index")
|
|
|
|
|
|
class SavedSearchDeleteView(LoginRequiredMixin, View):
|
|
def post(self, request, pk, *args, **kwargs):
|
|
saved_search = get_object_or_404(SavedSearch, pk=pk, user=request.user)
|
|
saved_search.delete()
|
|
messages.success(request, "Saved search deleted.")
|
|
return redirect("scouting:index")
|
|
|
|
|
|
class SavedSearchRunView(LoginRequiredMixin, View):
|
|
def get(self, request, pk, *args, **kwargs):
|
|
saved_search = get_object_or_404(SavedSearch, pk=pk, user=request.user)
|
|
query = saved_search_to_querystring(saved_search.filters)
|
|
saved_search.last_run_at = timezone.now()
|
|
saved_search.save(update_fields=["last_run_at"])
|
|
target = reverse("players:index")
|
|
return redirect(f"{target}?{query}" if query else target)
|
|
|
|
|
|
class WatchlistView(LoginRequiredMixin, ListView):
|
|
model = FavoritePlayer
|
|
context_object_name = "favorites"
|
|
template_name = "scouting/watchlist.html"
|
|
|
|
def get_queryset(self):
|
|
return (
|
|
FavoritePlayer.objects.filter(user=self.request.user)
|
|
.select_related("player", "player__nationality", "player__nominal_position", "player__inferred_role")
|
|
.order_by("-created_at")
|
|
)
|
|
|
|
|
|
class FavoriteToggleView(LoginRequiredMixin, View):
|
|
def post(self, request, player_id, *args, **kwargs):
|
|
from apps.players.models import Player
|
|
|
|
player = get_object_or_404(Player, pk=player_id)
|
|
next_url = request.POST.get("next") or request.META.get("HTTP_REFERER") or reverse("players:index")
|
|
|
|
favorite, created = FavoritePlayer.objects.get_or_create(user=request.user, player=player)
|
|
if not created:
|
|
favorite.delete()
|
|
|
|
is_favorite = created
|
|
|
|
if request.headers.get("HX-Request") == "true":
|
|
return render(
|
|
request,
|
|
"scouting/partials/favorite_button.html",
|
|
{
|
|
"player": player,
|
|
"is_favorite": is_favorite,
|
|
"next_url": next_url,
|
|
},
|
|
)
|
|
|
|
return redirect(next_url)
|
|
|
|
|
|
class SavedSearchListView(LoginRequiredMixin, ListView):
|
|
model = SavedSearch
|
|
context_object_name = "saved_searches"
|
|
template_name = "scouting/saved_search_list.html"
|
|
|
|
def get_queryset(self):
|
|
return SavedSearch.objects.filter(user=self.request.user).order_by("-updated_at")
|