lostplaces-backend/django_lostplaces/lostplaces/views/place_views.py

247 lines
8.8 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import timedelta
from django.db.models.functions import Lower
from django.views import View
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.utils.translation import gettext as _
from django.utils import timezone
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy, reverse
from lostplaces.models import (
Place,
PlaceImage,
PlaceVoting,
PLACE_LEVELS
)
from lostplaces.views.base_views import (
IsAuthenticatedMixin,
IsPlaceSubmitterMixin,
LevelCapPlaceListView,
IsEligibleToSeePlaceMixin
)
from lostplaces.views.place_image_views import MultiplePlaceImageUploadMixin
from lostplaces.forms import PlaceForm, PlaceImageForm, TagSubmitForm
from lostplaces.common import redirect_referer_or
from taggit.models import Tag
class PlaceListView(IsAuthenticatedMixin, LevelCapPlaceListView):
paginate_by = 18
template_name = 'place/place_list.html'
ordering = [Lower('name')]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['mapping_config'] = {
'all_points': context['place_list'],
'map_center': Place.average_latlon(context['place_list'])
}
return context
class PlaceDetailView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
not_eligible_to_see_message = _('You\'r not allowed to see this place')
def get_place(self):
return get_object_or_404(Place, pk=self.kwargs['pk'])
def get(self, request, pk):
place = self.get_place()
place.calculate_place_level()
explorer = request.user.explorer
if place.mode == 'draft':
messages.info(
self.request,
_('This place is still in draft mode and only visible to the submitter and superusers')
)
elif place.mode == 'imported':
messages.info(
self.request,
_('This place was imported and not reviewed & correted yet. This place is visbible for superusers only and does not appear in the list views.')
)
context = {
'place': place,
'mapping_config': {
'all_points': [ place ],
'map_center': {'latitude': place.latitude, 'longitude': place.longitude},
},
'tagging_config': {
'all_tags': Tag.objects.all(),
'submit_form': TagSubmitForm(),
'tagged_item': place,
'submit_url': reverse('place_tag_submit', kwargs={'tagged_id': place.id}),
'delete_url_name': 'place_tag_delete'
},
'placevoting': {
'users_vote': PlaceVoting.objects.filter(place=place, submitted_by=explorer).first(),
'all_choices': reversed(PLACE_LEVELS),
'accuracy': place.calculate_voting_accuracy()
}
}
return render(request, 'place/place_detail.html', context)
class PlaceUpdateView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, SuccessMessageMixin, UpdateView):
template_name = 'place/place_update.html'
model = Place
form_class = PlaceForm
success_message = _('Successfully updated place')
place_submitter_error_message = _('You are not allowed to edit this place')
def get_success_url(self):
return reverse_lazy('place_detail', kwargs={'pk':self.get_object().pk})
def get_place(self):
return self.get_object()
class PlaceCreateView(MultiplePlaceImageUploadMixin, IsAuthenticatedMixin, View):
def get(self, request, *args, **kwargs):
place_image_form = PlaceImageForm()
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.explorer
place = place_form.save(commit=False)
# Save logged in user as "submitted_by"
place.submitted_by = submitter
if place_form.cleaned_data['draft']:
place.mode = 'draft';
place.save()
self.handle_place_images(request, place)
messages.success(
self.request,
_('Successfully created place')
)
return redirect(reverse_lazy('place_detail', kwargs={'pk': place.pk}))
else:
# Usually the browser should have checked the form before sending.
messages.error(
self.request,
_('Please fill in all required fields.')
)
return render(
request=request,
template_name='place/place_create.html',
context={
'place_form': place_form,
'place_image_form': PlaceImageForm()
},
status=400
)
class PlaceDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, DeleteView):
template_name = 'place/place_delete.html'
model = Place
success_message = _('Successfully deleted place')
success_url = reverse_lazy('place_list')
place_submitter_error_message = _('You are not allowed to delete this place')
def delete(self, request, *args, **kwargs):
messages.success(self.request, self.success_message)
return super().delete(request, *args, **kwargs)
def get_place(self):
return self.get_object()
class PlaceFavoriteView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
not_eligible_to_see_message = _('You\'r not allowed to favorite this place')
def get_place(self):
return get_object_or_404(Place, pk=self.kwargs['place_id'])
def get(self, request, place_id):
place = self.get_place()
if request.user is not None:
request.user.explorer.favorite_places.add(place)
request.user.explorer.save()
return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
def get(self, request, place_id):
place = get_object_or_404(Place, id=place_id)
if request.user is not None:
request.user.explorer.favorite_places.remove(place)
request.user.explorer.save()
return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
class PlaceVisitCreateView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
not_eligible_to_see_message = _('You\'r not allowed to visit this place :P (Now please stop trying out URL\'s)')
def get_place(self):
return get_object_or_404(Place, pk=self.kwargs['place_id'])
def get(self, request, place_id):
place = self.get_place()
if request.user is not None:
request.user.explorer.visited_places.add(place)
request.user.explorer.save()
return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
class PlaceVisitDeleteView(IsAuthenticatedMixin, View):
def get(self, request, place_id):
place = get_object_or_404(Place, id=place_id)
if request.user is not None:
request.user.explorer.visited_places.remove(place)
request.user.explorer.save()
return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
class PlaceVoteView(IsEligibleToSeePlaceMixin, View):
delta = timedelta(weeks=24)
def get_place(self):
return get_object_or_404(Place, pk=self.kwargs['place_id'])
def get(self, request, place_id, vote):
place = self.get_place()
explorer = request.user.explorer
voting = PlaceVoting.objects.filter(
submitted_by=explorer,
place=place
).first()
if voting is None:
voting = PlaceVoting.objects.create(
submitted_by=explorer,
place=place,
vote=vote
)
messages.success(self.request, _('Vote submitted'))
else:
voting.submitted_when = timezone.now()
voting.vote = vote
messages.success(self.request, _('Your vote has been update'))
voting.save()
return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))