lostplaces-backend/lostplaces/lostplaces_app/views.py

149 lines
4.8 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
''' Django views. '''
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic import ListView
from django.views import View
from django.http import Http404
from django.contrib import messages
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from .forms import (
ExplorerCreationForm,
PlaceForm,
PlaceImageCreateForm
)
from .models import Place, PlaceImage, Voucher
# Create your views here.
# BaseView that checks if user is logged in.
class IsAuthenticated(LoginRequiredMixin, View):
redirect_field_name = 'redirect_to'
# BaseView that checks if logged in user is submitter of place.
class IsSubmitter(UserPassesTestMixin, View):
def test_func(self):
""" Check if user is eligible to modify place. """
if self.request.user.is_superuser:
return True
# Check if currently logged in user was the submitter
place_obj = self.get_object()
if self.request.user == place_obj.submitted_by:
return True
messages.error(
self.request, 'You do not have permission to do this.')
return False
class SignUpView(SuccessMessageMixin, CreateView):
form_class = ExplorerCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
success_message = 'User created.'
class PlaceListView(IsAuthenticated, ListView):
paginate_by = 5
model = Place
template_name = 'place/place_list.html'
class PlaceDetailView(IsAuthenticated, View):
def get(self, request, pk):
context = {
'place': Place.objects.get(pk=pk)
}
return render(request, 'place/place_detail.html', context)
class HomeView(View):
def get(self, request, *args, **kwargs):
place_list = Place.objects.all().order_by('-submitted_when')[:10]
place_map_center = Place.average_latlon()
context = {
'place_list': place_list,
'place_map_center': place_map_center
}
return render(request, 'home.html', context)
class PlaceUpdateView(IsAuthenticated, IsSubmitter, SuccessMessageMixin, UpdateView):
template_name = 'place/place_update.html'
model = Place
form_class = PlaceForm
success_message = 'Successfully updated place.'
def get_success_url(self):
return reverse_lazy('place_detail', kwargs={'pk':self.get_object().pk})
class PlaceCreateView(IsAuthenticated, View):
def get(self, request, *args, **kwargs):
place_image_form = PlaceImageCreateForm()
place_form = PlaceForm()
context = {
'place_form': place_form,
'place_image_form': place_image_form
}
return render(request, 'place/place_create.html', context)
def post(self, request, *args, **kwargs):
place_form = PlaceForm(request.POST)
if place_form.is_valid():
submitter = request.user
place = place_form.save(commit=False)
# Save logged in user as "submitted_by"
place.submitted_by = submitter
place.save()
if request.FILES:
self._apply_multipart_image_upload(
files=request.FILES.getlist('filename'),
place=place,
submitter=submitter
)
kwargs_to_pass = {
'pk': place.pk
}
messages.success(
self.request, 'Successfully created place.')
return redirect(reverse_lazy('place_detail', kwargs=kwargs_to_pass))
else:
context = {
'form': form_place
}
# Usually the browser should have checked the form before sending.
messages.error(
self.request, 'Please fill in all required fields.')
return render(request, 'place/place_create.html', context)
def _apply_multipart_image_upload(self, files, place, submitter):
for image in files:
place_image = PlaceImage.objects.create(
filename=image,
place=place,
submitted_by=submitter
)
place_image.save()
class PlaceDeleteView(IsAuthenticated, IsSubmitter, DeleteView):
template_name = 'place/place_delete.html'
model = Place
success_message = 'Successfully deleted place.'
success_url = reverse_lazy('place_list')
success_message = 'Place deleted'
def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message)
return super().delete(request, *args, **kwargs)