#!/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' ordering = ['name'] def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) print(context) context['place_map_center'] = Place.average_latlon(self.get_queryset()) return context class PlaceDetailView(IsAuthenticated, View): def get(self, request, pk): place = Place.objects.get(pk=pk) context = { 'place': place, 'place_list': [ place ], 'place_map_center': [ place.latitude, place.longitude ] } 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(place_list) 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)