diff --git a/Pipfile b/Pipfile index d275152..7ece21a 100644 --- a/Pipfile +++ b/Pipfile @@ -12,6 +12,7 @@ easy-thumbnails = "*" image = "*" django-widget-tweaks = "*" django-svg-icons = "*" +django-taggit = "*" # Commented out to not explicitly specify Python 3 subversion. # [requires] diff --git a/lostplaces/lostplaces/settings.py b/lostplaces/lostplaces/settings.py index 3e53bc4..b6d5dd9 100644 --- a/lostplaces/lostplaces/settings.py +++ b/lostplaces/lostplaces/settings.py @@ -43,7 +43,8 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'easy_thumbnails', - 'widget_tweaks' + 'widget_tweaks', + 'taggit' ] MIDDLEWARE = [ diff --git a/lostplaces/lostplaces_app/forms.py b/lostplaces/lostplaces_app/forms.py index d88d090..f08e771 100644 --- a/lostplaces/lostplaces_app/forms.py +++ b/lostplaces/lostplaces_app/forms.py @@ -48,3 +48,7 @@ class PlaceImageCreateForm(forms.ModelForm): super().__init__(*args, **kwargs) self.fields['filename'].required = False + + +class TagSubmitForm(forms.Form): + tag_list = forms.CharField(max_length=500) \ No newline at end of file diff --git a/lostplaces/lostplaces_app/models.py b/lostplaces/lostplaces_app/models.py index d513bb0..cf625a2 100644 --- a/lostplaces/lostplaces_app/models.py +++ b/lostplaces/lostplaces_app/models.py @@ -10,6 +10,7 @@ from django.db import models from django.dispatch import receiver from django.contrib.auth.models import AbstractUser from easy_thumbnails.fields import ThumbnailerImageField +from taggit.managers import TaggableManager # Create your models here. @@ -55,6 +56,7 @@ class Place (models.Model): longitude = models.FloatField() description = models.TextField() + tags = TaggableManager(blank=True) # Get center position of LP-geocoordinates. def average_latlon(place_list): @@ -145,21 +147,21 @@ def auto_delete_file_on_change(sender, instance, **kwargs): class ExternalLink(models.Model): - url = models.URLField(max_length=200) - label = models.CharField(max_length=100) - submitted_by = models.ForeignKey( + url = models.URLField(max_length=200) + label = models.CharField(max_length=100) + submitted_by = models.ForeignKey( Explorer, on_delete=models.SET_NULL, null=True, blank=True, related_name='external_links' ) - submitted_when = models.DateTimeField(auto_now_add=True, null=True) + submitted_when = models.DateTimeField(auto_now_add=True, null=True) class PhotoAlbum(ExternalLink): - place = models.ForeignKey( + place = models.ForeignKey( Place, on_delete=models.CASCADE, related_name='photo_albums', - null=True + null=True ) \ No newline at end of file diff --git a/lostplaces/lostplaces_app/templates/place/place_detail.html b/lostplaces/lostplaces_app/templates/place/place_detail.html index ce6d90c..3c48536 100644 --- a/lostplaces/lostplaces_app/templates/place/place_detail.html +++ b/lostplaces/lostplaces_app/templates/place/place_detail.html @@ -17,109 +17,127 @@ {% block title %}{{place.name}}{% endblock %} {% block additional_menu_items %} -
  • Edit place
  • -
  • Delete place
  • +
  • Edit place
  • +
  • Delete place
  • {% endblock additional_menu_items %} {% block maincontent %}
    -
    -

    {{ place.name }}

    - {% if place.images.first.filename.hero.url %} -
    - -
    - {% endif %} -
    +
    +

    {{ place.name }}

    + {% if place.images.first.filename.hero.url %} +
    + +
    + {% endif %} +
    -
    -

    {{ place.description }}

    -
    +
    +

    {{ place.description }}

    +
    -
    -

    Map-Links

    - {% include 'partials/osm_map.html' %} - -
    +
    + - // initialize Tagify on the above input node reference - new Tagify(input, { - 'whitelist': ['wurstwasser'] - }) - -
    +
    + +
    -
    -

    Photoalben

    -
    + +
    +

    Map-Links

    + {% include 'partials/osm_map.html' %} +
    +
    + +
    +

    Photoalben

    + -
    + + + Fotoalbum hinzufügen + + + + + + -
    -

    Bilder

    -
    -
      - {% for place_image in place.images.all %} -
    • - -
    • - {% endfor %} -
    -
    -
    +
    +

    Bilder

    +
    +
      + {% for place_image in place.images.all %} +
    • + +
    • + {% endfor %} +
    +
    +
    {% endblock maincontent %} \ No newline at end of file diff --git a/lostplaces/lostplaces_app/urls.py b/lostplaces/lostplaces_app/urls.py index b319793..d5d7b15 100644 --- a/lostplaces/lostplaces_app/urls.py +++ b/lostplaces/lostplaces_app/urls.py @@ -8,7 +8,8 @@ from .views import ( PlaceUpdateView, PlaceDeleteView, PhotoAlbumCreateView, - PhotoAlbumDeleteView + PhotoAlbumDeleteView, + PlaceTagSubmitView ) urlpatterns = [ @@ -20,5 +21,6 @@ urlpatterns = [ path('photo_album/delete/', PhotoAlbumDeleteView.as_view(), name='photo_album_delete'), path('place/update//', PlaceUpdateView.as_view(), name='place_edit'), path('place/delete//', PlaceDeleteView.as_view(), name='place_delete'), - path('place/', PlaceListView.as_view(), name='place_list') + path('place/', PlaceListView.as_view(), name='place_list'), + path('place/tag/', PlaceTagSubmitView.as_view(), name='place_tag_submit'), ] diff --git a/lostplaces/lostplaces_app/views/place_views.py b/lostplaces/lostplaces_app/views/place_views.py index f407d71..1e5bc67 100644 --- a/lostplaces/lostplaces_app/views/place_views.py +++ b/lostplaces/lostplaces_app/views/place_views.py @@ -11,7 +11,7 @@ from django.urls import reverse_lazy from lostplaces_app.models import Place, PlaceImage from lostplaces_app.views import IsAuthenticated, IsPlaceSubmitter -from lostplaces_app.forms import PlaceForm, PlaceImageCreateForm +from lostplaces_app.forms import PlaceForm, PlaceImageCreateForm, TagSubmitForm class PlaceListView(IsAuthenticated, ListView): paginate_by = 5 @@ -30,7 +30,8 @@ class PlaceDetailView(IsAuthenticated, View): context = { 'place': place, 'place_list': [ place ], - 'place_map_center': [ place.latitude, place.longitude ] + 'place_map_center': [ place.latitude, place.longitude ], + 'tagging_form': TagSubmitForm() } return render(request, 'place/place_detail.html', context) diff --git a/lostplaces/lostplaces_app/views/views.py b/lostplaces/lostplaces_app/views/views.py index 28f7f25..5725b58 100644 --- a/lostplaces/lostplaces_app/views/views.py +++ b/lostplaces/lostplaces_app/views/views.py @@ -6,8 +6,9 @@ from django.contrib import messages from django.urls import reverse_lazy from django.shortcuts import render, redirect -from lostplaces_app.forms import ExplorerCreationForm +from lostplaces_app.forms import ExplorerCreationForm, TagSubmitForm from lostplaces_app.models import Place, PhotoAlbum +from lostplaces_app.views.base_views import IsAuthenticated from lostplaces_app.views.base_views import ( PlaceAssetCreateView, @@ -39,4 +40,19 @@ class PhotoAlbumDeleteView(PlaceAssetDeleteView): model = PhotoAlbum pk_url_kwarg = 'pk' success_message = 'Photo Album deleted' - permission_denied_messsage = 'You do not have permissions to alter this photo album' \ No newline at end of file + permission_denied_messsage = 'You do not have permissions to alter this photo album' + +class PlaceTagSubmitView(IsAuthenticated, View): + def post(self, request, place_id, *args, **kwargs): + place = Place.objects.get(pk=place_id) + form = TagSubmitForm(request.POST) + if form.is_valid(): + tag_list_raw = form.cleaned_data['tag_list'] + tag_list_raw = tag_list_raw.strip().split(',') + tag_list = [] + for tag in tag_list_raw: + tag_list.append(tag.strip()) + place.tags.add(*tag_list) + place.save() + + return redirect(reverse_lazy('place_detail', kwargs={'pk': place.id}))