import datetime from crispy_forms.helper import FormHelper from crispy_forms.layout import Submit from django.forms import TextInput from django.forms.models import ModelForm from django.http import HttpResponse from django.shortcuts import redirect, render from django.views.generic.edit import CreateView, UpdateView from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from location_field.widgets import LocationWidget from .models import Event, EventParticipation from .serializers import ParticipationSerializer # ---------------------------------------- API --------------------------------------------------------- @api_view(["GET", "PUT"]) def event_api(request, username=None, eventId=None): try: participationQs = EventParticipation.objects.filter( event__date__gte=datetime.date.today() ) if username: participationQs = EventParticipation.objects.filter(user__username=username) if eventId: participationQs = participationQs.filter(event__pk=eventId) except EventParticipation.DoesNotExist: return HttpResponse(status=404) if request.method == "GET": serializer = ParticipationSerializer(participationQs, many=True) return Response(serializer.data) elif request.method == "PUT": serializer = ParticipationSerializer(data=request.data, many=True) if serializer.is_valid(): for item in serializer.validated_data: event = item.get("event") user_obj = item.get("user") if not ( EventParticipation.isMember(request.user) or EventParticipation.isAdmin(request.user) ): return Response( {"error": "Permission denied - not a member"}, status=status.HTTP_403_FORBIDDEN, ) # Allow users to update their own participation # Admins can update anyone's participation if user_obj.pk != request.user.pk: if not EventParticipation.isAdmin(request.user): return Response( {"error": "Permission denied - can only update own status"}, status=status.HTTP_403_FORBIDDEN, ) instances = serializer.save() # Re-serialize the saved instances to return proper data response_serializer = ParticipationSerializer(instances, many=True) return Response(response_serializer.data) else: import logging logger = logging.getLogger(__name__) logger.error(f"API validation errors: {serializer.errors}") logger.error(f"Request data: {request.data}") return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # ------------------------------------ Normal Views ---------------------------------------------------- def eventplanning(request): """ View for a specific user, to edit his events """ # non-members see the grid - but cannot edit anything if not EventParticipation.isMember(request.user): return events_grid(request) # All events in the future sorted by date all_future_events = list( Event.objects.filter(date__gte=datetime.date.today()).order_by("date") ) for e in all_future_events: e.participation = EventParticipation.get_or_create(event=e, user=request.user) context = {"events": all_future_events} return render(request, "eventplanner/eventplanning_view.html", context) def events_grid(request): usernames = [u.username for u in EventParticipation.members()] all_future_events = list( Event.objects.filter(date__gte=datetime.date.today()).order_by("date") ) for e in all_future_events: e.participation = [ EventParticipation.get_or_create(event=e, user=u) for u in EventParticipation.members() ] context = {"events": all_future_events, "usernames": usernames} return render(request, "eventplanner/events_grid.html", context) def deleteEvent(request, pk): Event.objects.get(pk=pk).delete() return redirect(events_grid) # ------------------------------------ Detail Views ---------------------------------------------------- class EventForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.form_class = "form-horizontal" self.helper.add_input(Submit("submit", "Speichern")) class Meta: model = Event fields = [ "type", "short_desc", "date", "end_date", "time", "meeting_time", "location", "map_location", "desc", ] widgets = { "location": TextInput(), "map_location": LocationWidget(), } class EventUpdate(UpdateView): form_class = EventForm model = Event template_name_suffix = "_update_form" success_url = "." def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["viewtype"] = "update" return context class EventCreate(CreateView): form_class = EventForm model = Event template_name_suffix = "_update_form" success_url = "." def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["viewtype"] = "create" return context