Adding tags is now possible

This commit is contained in:
reverend 2020-08-30 18:39:45 +02:00
parent 490a0e9f3e
commit 66581a9d2d
8 changed files with 149 additions and 104 deletions

View File

@ -12,6 +12,7 @@ easy-thumbnails = "*"
image = "*" image = "*"
django-widget-tweaks = "*" django-widget-tweaks = "*"
django-svg-icons = "*" django-svg-icons = "*"
django-taggit = "*"
# Commented out to not explicitly specify Python 3 subversion. # Commented out to not explicitly specify Python 3 subversion.
# [requires] # [requires]

View File

@ -43,7 +43,8 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'easy_thumbnails', 'easy_thumbnails',
'widget_tweaks' 'widget_tweaks',
'taggit'
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -48,3 +48,7 @@ class PlaceImageCreateForm(forms.ModelForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['filename'].required = False self.fields['filename'].required = False
class TagSubmitForm(forms.Form):
tag_list = forms.CharField(max_length=500)

View File

@ -10,6 +10,7 @@ from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from easy_thumbnails.fields import ThumbnailerImageField from easy_thumbnails.fields import ThumbnailerImageField
from taggit.managers import TaggableManager
# Create your models here. # Create your models here.
@ -55,6 +56,7 @@ class Place (models.Model):
longitude = models.FloatField() longitude = models.FloatField()
description = models.TextField() description = models.TextField()
tags = TaggableManager(blank=True)
# Get center position of LP-geocoordinates. # Get center position of LP-geocoordinates.
def average_latlon(place_list): def average_latlon(place_list):
@ -145,21 +147,21 @@ def auto_delete_file_on_change(sender, instance, **kwargs):
class ExternalLink(models.Model): class ExternalLink(models.Model):
url = models.URLField(max_length=200) url = models.URLField(max_length=200)
label = models.CharField(max_length=100) label = models.CharField(max_length=100)
submitted_by = models.ForeignKey( submitted_by = models.ForeignKey(
Explorer, Explorer,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
blank=True, blank=True,
related_name='external_links' 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): class PhotoAlbum(ExternalLink):
place = models.ForeignKey( place = models.ForeignKey(
Place, Place,
on_delete=models.CASCADE, on_delete=models.CASCADE,
related_name='photo_albums', related_name='photo_albums',
null=True null=True
) )

View File

@ -17,109 +17,127 @@
{% block title %}{{place.name}}{% endblock %} {% block title %}{{place.name}}{% endblock %}
{% block additional_menu_items %} {% block additional_menu_items %}
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_edit' pk=place.pk %}" class="LP-Link"><span <li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_edit' pk=place.pk %}" class="LP-Link"><span class="LP-Link__Text">Edit place</span></a></li>
class="LP-Link__Text">Edit place</span></a></li> <li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_delete' pk=place.pk %}" class="LP-Link"><span class="LP-Link__Text">Delete place</span></a></li>
<li class="LP-Menu__Item LP-Menu__Item--additional"><a href="{% url 'place_delete' pk=place.pk %}" class="LP-Link"><span
class="LP-Link__Text">Delete place</span></a></li>
{% endblock additional_menu_items %} {% endblock additional_menu_items %}
{% block maincontent %} {% block maincontent %}
<article class="LP-PlaceDetail"> <article class="LP-PlaceDetail">
<header class="LP-PlaceDetail__Header"> <header class="LP-PlaceDetail__Header">
<h1 class="LP-Headline">{{ place.name }}</h1> <h1 class="LP-Headline">{{ place.name }}</h1>
{% if place.images.first.filename.hero.url %} {% if place.images.first.filename.hero.url %}
<figure class="LP-PlaceDetail__Image"> <figure class="LP-PlaceDetail__Image">
<img src="{{ place.images.first.filename.hero.url }}" class="LP-Image" /> <img src="{{ place.images.first.filename.hero.url }}" class="LP-Image" />
</figure> </figure>
{% endif %} {% endif %}
</header> </header>
<div class="LP-PlaceDetail__Description"> <div class="LP-PlaceDetail__Description">
<p class="LP-Paragraph">{{ place.description }}</p> <p class="LP-Paragraph">{{ place.description }}</p>
</div> </div>
<section class="LP-Section"> <section class="LP-Section">
<h1 class="LP-Headline">Map-Links</h1> <!--
{% include 'partials/osm_map.html' %} <input name='basic' value='tag1, tag2'>
<div class="LP-LinkList"> <script>
<ul class="LP-LinkList__Container"> // The DOM element you wish to replace with Tagify
<li class="LP-LinkList__Item"><a target="_blank" var input = document.querySelector('input[name=basic]');
href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}"
class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank"
href="https://www.tim-online.nrw.de/tim-online2/?center={{place.latitude}},{{place.longitude}}&icon=true&bg=dop"
class="LP-Link"><span class="LP-Text">TIM Online</span></a></li>
<li class="LP-LinkList__Item"><a target="_blank"
href="http://www.openstreetmap.org/?mlat={{place.latitude}}&mlon={{place.longitude}}&zoom=16"
class="LP-Link"><span class="LP-Text">OSM</span></a></li>
</ul>
</div>
</section>
<section class="LP-Section"> // initialize Tagify on the above input node reference
<input name='basic' value='tag1, tag2'> new Tagify(input, {
<script> 'whitelist': ['wurstwasser']
// The DOM element you wish to replace with Tagify })
var input = document.querySelector('input[name=basic]'); </script>-->
// initialize Tagify on the above input node reference <div class="LP-TagList">
new Tagify(input, { <ul class="LP-TagList__List">
'whitelist': ['wurstwasser'] {% for tag in place.tags.all %}
}) <li class="LP-TagList__Item">
</script> <div class="LP-Tag">
</section> <p class="LP-Paragraph">{{tag}}</p>
</div>
</li>
{% endfor %}
</ul>
</div>
<section class="LP-Section"> <form class="LP-Form LP-Form--inline" method="POST" action="{% url 'place_tag_submit' place_id=place.id %}">
<h1 class="LP-Headline">Photoalben</h1> <fieldset class="LP-Form__Fieldset">
<div class="LP-LinkList"> <legend class="LP-Form__Legend">Tags hinzufügen</legend>
<ul class="LP-LinkList__Container"> {% csrf_token %}
{% for photo_album in place.photo_albums.all %} <div class="LP-Form__Composition LP-Form__Composition--breakable">
<li class="LP-LinkList__Item"> <div class="LP-Form__Field">
<a target="_blank" href="{{photo_album.url}}" class="LP-Link"> {% include 'partials/form/inputField.html' with field=tagging_form.tag_list %}
<span class="LP-Text">{{photo_album.label}}</span> </div>
</a> <div class="LP-Form__Field LP-Form__Button LP-Input">
{% if user == photo_album.submitted_by or user == place.submitted_by %} <button class="LP-Button">hinzufügen</button>
<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album"> </div>
<div class="RV-Iconized__Container RV-Iconized__Container--small"> </div>
{% icon 'trash' className="RV-Iconized__Icon" %} </fieldset>
</div>
</a> </form>
{% endif %} </section>
</li>
{% endfor %} <section class="LP-Section">
<li class="LP-LinkList__Item"> <h1 class="LP-Headline">Map-Links</h1>
<a href="{% url 'photo_album_create' place_id=place.id %}" class="LP-Link"> {% include 'partials/osm_map.html' %}
<div class="RV-Iconized__Container RV-Iconized__Container--small"> <div class="LP-LinkList">
<svg class="RV-Iconized__Icon" version="1.1" id="Capa_1" <ul class="LP-LinkList__Container">
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude}},{{place.longitude}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
x="0px" y="0px" viewBox="0 0 512 512" xml:space="preserve"> <li class="LP-LinkList__Item"><a target="_blank" href="https://www.tim-online.nrw.de/tim-online2/?center={{place.latitude}},{{place.longitude}}&icon=true&bg=dop" class="LP-Link"><span class="LP-Text">TIM Online</span></a></li>
<g> <li class="LP-LinkList__Item"><a target="_blank" href="http://www.openstreetmap.org/?mlat={{place.latitude}}&mlon={{place.longitude}}&zoom=16" class="LP-Link"><span class="LP-Text">OSM</span></a></li>
<path d="M492,236H276V20c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v216H20c-11.046,0-20,8.954-20,20s8.954,20,20,20h216 </ul>
</div>
</section>
<section class=" LP-Section">
<h1 class="LP-Headline">Photoalben</h1>
<div class="LP-LinkList">
<ul class="LP-LinkList__Container">
{% for photo_album in place.photo_albums.all %}
<li class="LP-LinkList__Item">
<a target="_blank" href="{{photo_album.url}}" class="LP-Link">
<span class="LP-Text">{{photo_album.label}}</span>
</a>
{% if user == photo_album.submitted_by or user == place.submitted_by %}
<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
<div class="RV-Iconized__Container RV-Iconized__Container--small">
{% icon 'trash' className="RV-Iconized__Icon" %}
</div>
</a>
{% endif %}
</li>
{% endfor %}
<li class="LP-LinkList__Item">
<a href="{% url 'photo_album_create' place_id=place.id %}" class="LP-Link">
<div class="RV-Iconized__Container RV-Iconized__Container--small">
<svg class="RV-Iconized__Icon" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" xml:space="preserve">
<g>
<path d="M492,236H276V20c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v216H20c-11.046,0-20,8.954-20,20s8.954,20,20,20h216
v216c0,11.046,8.954,20,20,20s20-8.954,20-20V276h216c11.046,0,20-8.954,20-20C512,244.954,503.046,236,492,236z" /> v216c0,11.046,8.954,20,20,20s20-8.954,20-20V276h216c11.046,0,20-8.954,20-20C512,244.954,503.046,236,492,236z" />
</g> </g>
</svg> </svg>
<span class="RV-Iconized__Text">Fotoalbum hinzufügen</span> <span class="RV-Iconized__Text">Fotoalbum hinzufügen</span>
</div> </div>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</section> </section>
<section class="LP-Section"> <section class="LP-Section">
<h1 class="LP-Headline">Bilder</h1> <h1 class="LP-Headline">Bilder</h1>
<div class="LP-ImageGrid"> <div class="LP-ImageGrid">
<ul class="LP-ImageGrid__Container"> <ul class="LP-ImageGrid__Container">
{% for place_image in place.images.all %} {% for place_image in place.images.all %}
<li class="LP-ImageGrid__Item"> <li class="LP-ImageGrid__Item">
<a href="{{ place_image.filename.large.url }}" class="LP-Link"><img class="LP-Image" <a href="{{ place_image.filename.large.url }}" class="LP-Link"><img class="LP-Image" src="{{ place_image.filename.thumbnail.url }}"></a>
src="{{ place_image.filename.thumbnail.url }}"></a> </li>
</li> {% endfor %}
{% endfor %} </ul>
</ul> </div>
</div> </section>
</section>
</article> </article>
{% endblock maincontent %} {% endblock maincontent %}

View File

@ -8,7 +8,8 @@ from .views import (
PlaceUpdateView, PlaceUpdateView,
PlaceDeleteView, PlaceDeleteView,
PhotoAlbumCreateView, PhotoAlbumCreateView,
PhotoAlbumDeleteView PhotoAlbumDeleteView,
PlaceTagSubmitView
) )
urlpatterns = [ urlpatterns = [
@ -20,5 +21,6 @@ urlpatterns = [
path('photo_album/delete/<int:pk>', PhotoAlbumDeleteView.as_view(), name='photo_album_delete'), path('photo_album/delete/<int:pk>', PhotoAlbumDeleteView.as_view(), name='photo_album_delete'),
path('place/update/<int:pk>/', PlaceUpdateView.as_view(), name='place_edit'), path('place/update/<int:pk>/', PlaceUpdateView.as_view(), name='place_edit'),
path('place/delete/<int:pk>/', PlaceDeleteView.as_view(), name='place_delete'), path('place/delete/<int:pk>/', 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/<int:place_id>', PlaceTagSubmitView.as_view(), name='place_tag_submit'),
] ]

View File

@ -11,7 +11,7 @@ from django.urls import reverse_lazy
from lostplaces_app.models import Place, PlaceImage from lostplaces_app.models import Place, PlaceImage
from lostplaces_app.views import IsAuthenticated, IsPlaceSubmitter 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): class PlaceListView(IsAuthenticated, ListView):
paginate_by = 5 paginate_by = 5
@ -30,7 +30,8 @@ class PlaceDetailView(IsAuthenticated, View):
context = { context = {
'place': place, 'place': place,
'place_list': [ 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) return render(request, 'place/place_detail.html', context)

View File

@ -6,8 +6,9 @@ from django.contrib import messages
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.shortcuts import render, redirect 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.models import Place, PhotoAlbum
from lostplaces_app.views.base_views import IsAuthenticated
from lostplaces_app.views.base_views import ( from lostplaces_app.views.base_views import (
PlaceAssetCreateView, PlaceAssetCreateView,
@ -39,4 +40,19 @@ class PhotoAlbumDeleteView(PlaceAssetDeleteView):
model = PhotoAlbum model = PhotoAlbum
pk_url_kwarg = 'pk' pk_url_kwarg = 'pk'
success_message = 'Photo Album deleted' success_message = 'Photo Album deleted'
permission_denied_messsage = 'You do not have permissions to alter this photo album' 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}))