14 Commits

14 changed files with 213 additions and 53 deletions

View File

@@ -24,7 +24,7 @@ user.explorer
Currently the explorer profile is used by the abstract model 'Submittable' and has the following realated names/fiels:
- [places](###place) A list containing all (lost) places the user has submitted
- [placeimages](###placeimages) A list containing all images relating a place that a user has submitted
- [photoalbums](###photoalbums) A list of all photo albums a explorere has submitted
- [externallinks](###externallinks) A list of all photo albums a explorere has submitted
### Taggable
@@ -141,15 +141,3 @@ This model represents an URL to an external website. External Link is an PlaceAs
the URL to the target
`label`
the label that is shown on the website
### PhotoAlbum
Loacation: `lostplaces.models.external_link.PhototAlbum`
Import From: `lostplaces.models.PhotoAlbum`
#### Super Classes
- django's `models.Model`
- [lostplaces.models.Submittable](###submittable)
- [lostplaces.models.PlaceAsset](###placeasset)
- [lostplaces.models.ExternalLink](###externallink)
A photo album is a link to an external site that is meant to contain photos of the place it is referenced in. It
does not have any fields, just the ones inherited from it's super class [ExternalLink](###externallink).

View File

@@ -21,8 +21,8 @@ class VoucherAdmin(admin.ModelAdmin):
valid.boolean = True
class PhotoAlbumsAdmin(admin.ModelAdmin):
list_display = ('label', 'place', 'url' )
class ExternalLinksAdmin(admin.ModelAdmin):
list_display = ('label', 'place', 'url', 'linktype' )
class PlacesAdmin(admin.ModelAdmin):
list_display = ('name', 'submitted_by', 'submitted_when')
@@ -34,4 +34,4 @@ admin.site.register(Explorer)
admin.site.register(Voucher, VoucherAdmin)
admin.site.register(Place, PlacesAdmin)
admin.site.register(PlaceImage, PlaceImagesAdmin)
admin.site.register(PhotoAlbum, PhotoAlbumsAdmin)
admin.site.register(ExternalLink, ExternalLinksAdmin)

View File

@@ -0,0 +1,18 @@
# Generated by Django 3.2.7 on 2021-10-01 19:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lostplaces', '0007_auto_20211001_1925'),
]
operations = [
migrations.AddField(
model_name='photoalbum',
name='linktype',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='link type'),
),
]

View File

@@ -0,0 +1,37 @@
# Generated by Django 3.2.7 on 2021-10-01 20:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('lostplaces', '0008_photoalbum_linktype'),
]
operations = [
migrations.CreateModel(
name='ExternalLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('submitted_when', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Submission date')),
('subclass', models.IntegerField(default=-1)),
('subclassid', models.IntegerField(default=-1)),
('url', models.URLField(verbose_name='URL')),
('label', models.CharField(max_length=100, verbose_name='link text')),
('linktype', models.CharField(blank=True, max_length=20, null=True, verbose_name='link type')),
('place', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='externallinks', to='lostplaces.place')),
('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='externallinks', to='lostplaces.explorer', verbose_name='Submitter')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='photoalbum',
name='externallink_ptr',
field=models.OneToOneField(auto_created=True, null=True, blank=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, serialize=False, to='lostplaces.externallink'),
preserve_default=False,
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 3.2.7 on 2021-10-01 20:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('lostplaces', '0009_photoalbum_externallink_interim'),
]
operations = [
# insert data from subclass into parent class with subclass 'number' and primary key/id
migrations.RunSQL("""INSERT INTO lostplaces_externallink (submitted_when, url, label, place_id, submitted_by_id, subclass, subclassid)
SELECT submitted_when, url, label, place_id, submitted_by_id, 1, id
FROM lostplaces_photoalbum;"""
),
# update subclass primary key to point to parent class (notice composite key values):
migrations.RunSQL("UPDATE lostplaces_photoalbum SET externallink_ptr_id=lostplaces_externallink.id FROM lostplaces_externallink WHERE lostplaces_externallink.subclassid=lostplaces_photoalbum.id AND lostplaces_externallink.subclass=1;"
),
]

View File

@@ -0,0 +1,56 @@
# Generated by Django 3.2.7 on 2021-10-01 22:48
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('lostplaces', '0010_photoalbum_externallink_datamigration'),
]
operations = [
migrations.RemoveField(
model_name='externallink',
name='subclass',
),
migrations.RemoveField(
model_name='externallink',
name='subclassid',
),
migrations.RemoveField(
model_name='photoalbum',
name='id',
),
migrations.RemoveField(
model_name='photoalbum',
name='label',
),
migrations.RemoveField(
model_name='photoalbum',
name='linktype',
),
migrations.RemoveField(
model_name='photoalbum',
name='place',
),
migrations.RemoveField(
model_name='photoalbum',
name='submitted_by',
),
migrations.RemoveField(
model_name='photoalbum',
name='submitted_when',
),
migrations.RemoveField(
model_name='photoalbum',
name='url',
),
migrations.AlterField(
model_name='photoalbum',
name='externallink_ptr',
field=models.OneToOneField(auto_created=True, default=-1, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='lostplaces.externallink'),
preserve_default=False,
),
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 3.2.7 on 2021-10-02 02:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('lostplaces', '0011_remove_migrated_photoalbum_data'),
]
operations = [
migrations.AlterField(
model_name='externallink',
name='linktype',
field=models.CharField(blank=True, choices=[('youtube', 'YouTube'), ('vimeo', 'Vimeo'), ('flickr', 'Flickr'), ('googlephotos', 'Google Photos'), ('photoalbum', 'Photo album')], max_length=20, null=True, verbose_name='link type'),
),
migrations.DeleteModel(
name='PhotoAlbum',
),
]

View File

@@ -3,10 +3,18 @@ from django.utils.translation import ugettext_lazy as _
from lostplaces.models.place import PlaceAsset
LINK_TYPES = (
('youtube', 'YouTube'),
('vimeo', "Vimeo"),
('flickr', 'Flickr'),
('googlephotos', "Google Photos"),
('photoalbum', "Photo album")
)
class ExternalLink(PlaceAsset):
class Meta:
abstract = True
abstract = False
url = models.URLField(
max_length=200,
@@ -16,6 +24,10 @@ class ExternalLink(PlaceAsset):
max_length=100,
verbose_name=_('link text')
)
class PhotoAlbum(ExternalLink):
pass
linktype = models.CharField(
choices=LINK_TYPES,
max_length=20,
verbose_name=_('link type'),
blank=True,
null=True
)

View File

@@ -104,7 +104,7 @@ class PlaceAsset(Submittable):
"""
class Meta:
abstract = True
abstract = True
place = models.ForeignKey(
Place,

View File

@@ -104,16 +104,16 @@
</section>
<section class=" LP-Section">
<h1 class="LP-Headline">{% translate 'Photo albums submitted by' %} {{explorer.user.username}}</h1>
<h1 class="LP-Headline">{% translate 'External links submitted by' %} {{explorer.user.username}}</h1>
<div class="LP-LinkList">
<ul class="LP-LinkList__Container">
{% for photo_album in assets.photoalbums.all %}
{% for external_link in assets.externallinks.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 target="_blank" href="{{external_link.url}}" class="LP-Link">
<span class="LP-Text">{{external_link.label}}</span>
</a>
{% if user.explorer == photo_album.submitted_by%}
<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
{% if user.explorer == external_link.submitted_by%}
<a href="{% url 'external_link_delete' pk=external_link.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>

View File

@@ -1,7 +1,7 @@
{% extends 'global.html'%}
{% load i18n %}
{% block title %}{% translate 'Submit a photo album' %}{% endblock %}
{% block title %}{% translate 'Submit an external link' %}{% endblock %}
{% 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
@@ -13,7 +13,7 @@
{% block maincontent %}
<form class="LP-Form" method="POST">
<fieldset class="LP-Form__Fieldset">
<legend class="LP-Form__Legend">{% translate 'Submit a photo album for' %} {{place.name}}</legend>
<legend class="LP-Form__Legend">{% translate 'Submit an external link for' %} {{place.name}}</legend>
{% csrf_token %}
<div class="LP-Form__Composition">
<div class="LP-Form__Field">
@@ -27,6 +27,12 @@
</div>
</div>
<div class="LP-Form__Composition">
<div class="LP-Form__Field">
{% include 'partials/form/inputField.html' with field=form.linktype %}
</div>
</div>
<div class="LP-Form__Composition LP-Form__Composition--buttons">
{% include 'partials/form/submit.html' with referrer=request.META.HTTP_REFERER %}
</div>

View File

@@ -62,16 +62,16 @@
</section>
<section class=" LP-Section">
<h1 class="LP-Headline">{% translate 'Photo albums' %}</h1>
<h2 class="LP-Headline">{% translate 'External links' %}</h2>
<div class="LP-LinkList">
<ul class="LP-LinkList__Container">
{% for photo_album in place.photoalbums.all %}
{% for external_link in place.externallinks.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 target="_blank" href="{{external_link.url}}" class="LP-Link">
<span class="LP-Text">{{external_link.label}}</span>
</a>
{% if user.explorer == photo_album.submitted_by or user.explorer == place.submitted_by %}
<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
{% if user.explorer == external_link.submitted_by or user.explorer == place.submitted_by %}
<a href="{% url 'external_link_delete' pk=external_link.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete external link">
<div class="RV-Iconized__Container RV-Iconized__Container--small">
{% icon 'trash' className="RV-Iconized__Icon" %}
</div>
@@ -80,7 +80,7 @@
</li>
{% endfor %}
<li class="LP-LinkList__Item">
<a href="{% url 'photo_album_create' place_id=place.id %}" class="LP-Link">
<a href="{% url 'external_link_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>
@@ -88,7 +88,7 @@
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>
</svg>
<span class="RV-Iconized__Text">{% translate 'Add photo album' %}</span>
<span class="RV-Iconized__Text">{% translate 'Add external link' %}</span>
</div>
</a>
</li>

View File

@@ -19,8 +19,8 @@ from lostplaces.views import (
PlaceVisitDeleteView,
PlaceImageCreateView,
PlaceImageDeleteView,
PhotoAlbumCreateView,
PhotoAlbumDeleteView,
ExternalLinkCreateView,
ExternalLinkDeleteView,
ExplorerProfileView,
ExplorerProfileUpdateView
)
@@ -48,6 +48,6 @@ urlpatterns = [
path('place_image/create/<int:place_id>/', PlaceImageCreateView.as_view(), name='place_image_create'),
path('place_image/delete/<int:pk>/', PlaceImageDeleteView.as_view(), name='place_image_delete'),
path('photo_album/create/<int:place_id>/', PhotoAlbumCreateView.as_view(), name='photo_album_create'),
path('photo_album/delete/<int:pk>/', PhotoAlbumDeleteView.as_view(), name='photo_album_delete')
path('external_link/create/<int:place_id>/', ExternalLinkCreateView.as_view(), name='external_link_create'),
path('external_link/delete/<int:pk>/', ExternalLinkDeleteView.as_view(), name='external_link_delete')
]

View File

@@ -12,7 +12,7 @@ from django.http import HttpResponseForbidden
from django.utils.translation import ugettext_lazy as _
from lostplaces.forms import SignupVoucherForm, TagSubmitForm
from lostplaces.models import Place, PhotoAlbum
from lostplaces.models import Place, ExternalLink
from lostplaces.views.base_views import IsAuthenticatedMixin
from lostplaces.common import redirect_referer_or
@@ -48,17 +48,17 @@ class HomeView(IsAuthenticatedMixin, View):
}
return render(self.request, 'home_unauth.html', context)
class PhotoAlbumCreateView(PlaceAssetCreateView):
model = PhotoAlbum
fields = ['url', 'label']
template_name = 'photo_album/photo_album_create.html'
success_message = _('Photo album link submitted')
class ExternalLinkCreateView(PlaceAssetCreateView):
model = ExternalLink
fields = ['url', 'label', 'linktype']
template_name = 'external_link/external_link_create.html'
success_message = _('External link submitted')
class PhotoAlbumDeleteView(PlaceAssetDeleteView):
model = PhotoAlbum
class ExternalLinkDeleteView(PlaceAssetDeleteView):
model = ExternalLink
pk_url_kwarg = 'pk'
success_message = _('Photo album link deleted')
permission_denied_messsage = _('You are not allowed to edit this photo album link')
success_message = _('External link deleted')
permission_denied_messsage = _('You are not allowed to edit this external link')
class PlaceTagSubmitView(IsAuthenticatedMixin, View):
def post(self, request, tagged_id, *args, **kwargs):