From c9d83dfc2c06ff690e8097e3dbbfea866379726f Mon Sep 17 00:00:00 2001 From: Leonhard Strohmidel Date: Sat, 24 Sep 2022 12:10:19 +0200 Subject: [PATCH] #64 place mode and filtering of place modes in list views --- django_lostplaces/lostplaces/forms.py | 7 +++- django_lostplaces/lostplaces/models/models.py | 18 +++++++++- django_lostplaces/lostplaces/models/place.py | 15 ++++++++- .../templates/place/place_create.html | 2 ++ .../tests/views/test_place_views.py | 33 +++++++++++++++++++ .../lostplaces/views/base_views.py | 8 ++++- django_lostplaces/lostplaces/views/views.py | 24 +++++++------- 7 files changed, 92 insertions(+), 15 deletions(-) diff --git a/django_lostplaces/lostplaces/forms.py b/django_lostplaces/lostplaces/forms.py index c7389b2..baa2b11 100644 --- a/django_lostplaces/lostplaces/forms.py +++ b/django_lostplaces/lostplaces/forms.py @@ -69,7 +69,7 @@ class PlaceForm(forms.ModelForm): class Meta: model = Place fields = '__all__' - exclude = ['submitted_by', 'level'] + exclude = ['submitted_by', 'level', 'mode'] widgets = { 'hero': widgets.SelectContent() } @@ -88,6 +88,11 @@ class PlaceForm(forms.ModelForm): widget=forms.NumberInput(attrs={'min':-180,'max': 180,'type': 'number', 'step': 'any'}) ) + draft = forms.BooleanField( + label=_('Save Place as draft'), + required=False + ) + class PlaceImageForm(forms.ModelForm): class Meta: model = PlaceImage diff --git a/django_lostplaces/lostplaces/models/models.py b/django_lostplaces/lostplaces/models/models.py index 8fe99a6..8dd2f57 100644 --- a/django_lostplaces/lostplaces/models/models.py +++ b/django_lostplaces/lostplaces/models/models.py @@ -82,9 +82,25 @@ class Explorer(models.Model): choices=EXPLORER_LEVELS ) + def get_place_list_to_display(self): + ''' + Gets the list of places to show on the homepage + and the list views + ''' + if self.user.is_superuser: + return Place.objects.filter(mode='live') + + return Place.objects.filter( + level__lte=self.level, + mode='live' + ) | Place.objects.filter( + submitted_by=self, + mode='live' + ) + def get_places_eligible_to_see(self): if self.user.is_superuser: - return Place.objects.all() + return Place.objects.filter(mode='live') return Place.objects.all().filter(level__lte=self.level) | self.places.all() def is_eligible_to_see(self, place): diff --git a/django_lostplaces/lostplaces/models/place.py b/django_lostplaces/lostplaces/models/place.py index 879185f..f4aa7f9 100644 --- a/django_lostplaces/lostplaces/models/place.py +++ b/django_lostplaces/lostplaces/models/place.py @@ -23,6 +23,13 @@ PLACE_LEVELS = ( (5, 'Time Capsule') ) +PLACE_MODES = ( + ('live', 'live'), + ('draft', 'draft'), + ('review', 'review'), + ('archive', 'archive') +) + class Place(Submittable, Taggable, Mapable): """ Place defines a lost place (location, name, description etc.). @@ -40,7 +47,7 @@ class Place(Submittable, Taggable, Mapable): hero = models.ForeignKey( 'PlaceImage', on_delete=models.SET_NULL, - null=True, + null=True, blank=True, related_name='place_heros' ) @@ -50,6 +57,12 @@ class Place(Submittable, Taggable, Mapable): choices=PLACE_LEVELS ) + mode = models.TextField( + default='live', + choices=PLACE_MODES, + verbose_name=_('Mode of Place Editing') + ) + def get_hero_image(self): if self.hero: return self.hero diff --git a/django_lostplaces/lostplaces/templates/place/place_create.html b/django_lostplaces/lostplaces/templates/place/place_create.html index 1201202..9122a0d 100644 --- a/django_lostplaces/lostplaces/templates/place/place_create.html +++ b/django_lostplaces/lostplaces/templates/place/place_create.html @@ -39,8 +39,10 @@ + {% translate 'Create' as action %}
+ {% include 'partials/form/inputField.html' with field=place_form.draft %} {% include 'partials/form/submit.html' with referrer=request.META.HTTP_REFERER action=action %}
diff --git a/django_lostplaces/lostplaces/tests/views/test_place_views.py b/django_lostplaces/lostplaces/tests/views/test_place_views.py index de186d4..25fa3bf 100644 --- a/django_lostplaces/lostplaces/tests/views/test_place_views.py +++ b/django_lostplaces/lostplaces/tests/views/test_place_views.py @@ -13,6 +13,7 @@ from django.utils.translation import gettext as _ from lostplaces.models import Place +from lostplaces.models import PLACE_MODES from lostplaces.views import ( PlaceCreateView, PlaceListView, @@ -154,6 +155,38 @@ class TestPlaceListView(GlobalTemplateTestCaseMixin, ViewTestCase): 'Im a own place' in response.content.decode(), msg='Expecting the user to see places where their level is high enough' ) + + def test_place_mode_filter(self): + explorer = User.objects.get(username='testpeter').explorer + Place.objects.all().delete() + + for mode in PLACE_MODES: + place = Place.objects.create( + name='Im a place in mode %s' % mode[0], + submitted_when=timezone.now(), + submitted_by=explorer, + location='Test town', + latitude=50.5, + longitude=7.0, + description='This is just a test, do not worry %s' % mode[0], + level=3, + mode=mode[0] + ) + + self.client.login(username='testpeter', password='Develop123') + response = self.client.get(reverse('place_list')) + + for mode in PLACE_MODES: + if ('Im a place in mode %s' % mode[0]) in response.content.decode(): + self.assertTrue( + mode[0] == 'live', + msg='Expecting only places in mode \'live\' to be listed, saw a place in mode %s' % mode[0] + ) + elif mode[0] == 'live': + self.fail( + msg='Expecting at least one place in mode \'live\' to be listed' + ) + class TestPlaceCreateView(ViewTestCase): view = PlaceCreateView diff --git a/django_lostplaces/lostplaces/views/base_views.py b/django_lostplaces/lostplaces/views/base_views.py index 6065a7f..7490b56 100644 --- a/django_lostplaces/lostplaces/views/base_views.py +++ b/django_lostplaces/lostplaces/views/base_views.py @@ -138,4 +138,10 @@ class LevelCapPlaceListView(ListView): model = Place def get_queryset(self): - return self.request.user.explorer.get_places_eligible_to_see() \ No newline at end of file + return self.request.user.explorer.get_place_list_to_display() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['place_list'] = context.pop('object_list') + return context + \ No newline at end of file diff --git a/django_lostplaces/lostplaces/views/views.py b/django_lostplaces/lostplaces/views/views.py index a2ead40..7c40337 100644 --- a/django_lostplaces/lostplaces/views/views.py +++ b/django_lostplaces/lostplaces/views/views.py @@ -13,7 +13,7 @@ from django.utils.translation import gettext as _ from lostplaces.forms import SignupVoucherForm, TagSubmitForm from lostplaces.models import Place, PhotoAlbum -from lostplaces.views.base_views import IsAuthenticatedMixin +from lostplaces.views.base_views import IsAuthenticatedMixin, LevelCapPlaceListView from lostplaces.common import redirect_referer_or from lostplaces.views.base_views import ( @@ -29,17 +29,19 @@ class SignUpView(SuccessMessageMixin, CreateView): template_name = 'signup.html' success_message = _('User created') -class HomeView(IsAuthenticatedMixin, View): - def get(self, request, *args, **kwargs): - place_list = request.user.explorer.get_places_eligible_to_see() - context = { - 'place_list': place_list, - 'mapping_config': { - 'all_points': place_list, - 'map_center': Place.average_latlon(place_list) - } +class HomeView(IsAuthenticatedMixin, LevelCapPlaceListView, View): + template_name = 'home.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + place_list = context['place_list'] + + context['mapping_config'] = { + 'all_points': place_list, + 'map_center': Place.average_latlon(place_list) } - return render(request, 'home.html', context) + return context + def handle_no_permission(self): place_list = Place.objects.filter(level=1)[:5]