14 Commits

8 changed files with 110 additions and 32 deletions

View File

@@ -39,14 +39,24 @@ class ExplorerUserChangeForm(UserChangeForm):
class Meta: class Meta:
model = User model = User
fields = [ 'username', 'first_name', 'last_name', 'email' ] fields = [ 'username', 'first_name', 'last_name', 'email' ]
''' Hide password hint.'''
password = None password = None
''' Display username, but display it non-editable and not required. '''
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['username'].required = False self.fields['username'].required = False
self.fields['username'].help_text = None self.fields['username'].help_text = None
self.fields['username'].widget.attrs['disabled'] = 'disabled' self.fields['username'].widget.attrs['disabled'] = 'disabled'
def clean_username(self):
# As shown in the above answer.
instance = getattr(self, 'instance', None)
if instance:
return instance.username
else:
return self.cleaned_data.get('username', None)
class ExplorerChangeForm(forms.ModelForm): class ExplorerChangeForm(forms.ModelForm):
class Meta: class Meta:
model = Explorer model = Explorer

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-12-25 01:22+0100\n" "POT-Creation-Date: 2020-12-25 16:04+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Commander1024 <commander@commander1024.de>\n" "Last-Translator: Commander1024 <commander@commander1024.de>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -74,21 +74,21 @@ msgstr "Adresse (URL)"
msgid "link text" msgid "link text"
msgstr "Linktext" msgstr "Linktext"
#: models/models.py:46 #: models/models.py:47
msgid "Biography / Description" msgid "Biography"
msgstr "Beschreibung" msgstr "Beschreibung"
#: models/models.py:47 #: models/models.py:48
msgid "Describe yourself, your preferences, etc. in a few sentences." msgid "Describe yourself, your preferences, etc. in a few sentences."
msgstr "Beschreibe Dich selbst, Deine Vorlieben, usw. in ein paar Sätzen." msgstr "Beschreibe Dich selbst, Deine Vorlieben, usw. in ein paar Sätzen."
#: models/models.py:55 #: models/models.py:56
msgid "Profile image" msgid "Profile image"
msgstr "Profilbild" msgstr "Profilbild"
#: models/models.py:56 #: models/models.py:57
msgid "Optional profile image for display in Explorer profile" msgid "Optional profile image for display in Explorer profile"
msgstr "Optionales Profilbind zur Anzeige im Explorerprofil" msgstr "Optionales Profilbild zur Anzeige im Explorerprofil"
#: models/place.py:21 #: models/place.py:21
msgid "Location" msgid "Location"
@@ -144,19 +144,25 @@ msgstr "Alle Places"
msgid "Place assets" msgid "Place assets"
msgstr "" msgstr ""
#: templates/explorer/profile.html:82 #: templates/explorer/profile.html:76
msgid "Favorite places" #, fuzzy
msgstr "Favoriten-Places" #| msgid "Edit Explorer profile"
msgid "Edit Profile"
msgstr "Explorerprofil bearbeiten"
#: templates/explorer/profile.html:98 #: templates/explorer/profile.html:87
msgid "Favorite places"
msgstr "Favoriten"
#: templates/explorer/profile.html:103
msgid "Places submitted by" msgid "Places submitted by"
msgstr "Places hinzugefügt von" msgstr "Places hinzugefügt von"
#: templates/explorer/profile.html:113 #: templates/explorer/profile.html:118
msgid "Images submitted by" msgid "Images submitted by"
msgstr "Bilder hinzugefügt von" msgstr "Bilder hinzugefügt von"
#: templates/explorer/profile.html:135 #: templates/explorer/profile.html:140
msgid "Photo albums submitted by" msgid "Photo albums submitted by"
msgstr "Fotoalben hinzugefügt von" msgstr "Fotoalben hinzugefügt von"
@@ -176,7 +182,7 @@ msgstr "Ausloggen"
#: templates/global.html:33 #: templates/global.html:33
msgid "Profile" msgid "Profile"
msgstr "" msgstr "Profil"
#: templates/global.html:35 #: templates/global.html:35
msgid "Admin" msgid "Admin"
@@ -402,6 +408,16 @@ msgstr "Noch kein Konto?"
msgid "Please login to proceed" msgid "Please login to proceed"
msgstr "Bitte log Dich ein um fortzufahren" msgstr "Bitte log Dich ein um fortzufahren"
#: views/explorer_views.py:78
#, fuzzy
#| msgid "Successfully updated place"
msgid "Successfully updated Explorer profile"
msgstr "Place erfolgreich aktualisiert"
#: views/explorer_views.py:84 views/place_views.py:105
msgid "Please fill in all required fields."
msgstr "Bitte füll alle benötigten Felder aus."
#: views/place_image_views.py:26 #: views/place_image_views.py:26
msgid "Image(s) submitted successfully" msgid "Image(s) submitted successfully"
msgstr "Bild(er) erfolgreich hinzugefügt" msgstr "Bild(er) erfolgreich hinzugefügt"
@@ -426,10 +442,6 @@ msgstr "Du darfst diesen Place nicht bearbeiten"
msgid "Successfully created place" msgid "Successfully created place"
msgstr "Place erfolgreich erstellt" msgstr "Place erfolgreich erstellt"
#: views/place_views.py:105
msgid "Please fill in all required fields."
msgstr "Bitte füll alle benötigten Felder aus."
#: views/place_views.py:112 #: views/place_views.py:112
msgid "Successfully deleted place" msgid "Successfully deleted place"
msgstr "Place erfolgreich gelöscht" msgstr "Place erfolgreich gelöscht"

View File

@@ -11,7 +11,7 @@ import uuid
from django.db import models from django.db import models
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.signals import post_save from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@@ -31,8 +31,9 @@ def generate_profile_image_filename(instance, filename):
class Explorer(models.Model): class Explorer(models.Model):
""" """
Profile that is linked to the a User. Profile that is linked to the Django user.
Every user has a profile. Every user has a profile.
Provides additional attributes for user profile.
""" """
user = models.OneToOneField( user = models.OneToOneField(
@@ -74,6 +75,25 @@ def create_user_profile(sender, instance, created, **kwargs):
def save_user_profile(sender, instance, **kwargs): def save_user_profile(sender, instance, **kwargs):
instance.explorer.save() instance.explorer.save()
@receiver(pre_save, sender=Explorer)
def auto_delete_file_on_change(sender, instance, **kwargs):
"""
Deletes old file from filesystem
when corresponding `Explorer` object is updated
with new file.
"""
if not instance.pk:
return False
try:
old_file = Explorer.objects.get(pk=instance.pk).profile_image
except Explorer.DoesNotExist:
return False
print("Deleting:", old_file)
new_file = instance.profile_image
if not old_file == new_file:
old_file.delete(save=False)
class Voucher(Expireable): class Voucher(Expireable):
""" """
Vouchers are authorization tokens to allow the registration of new users. Vouchers are authorization tokens to allow the registration of new users.

View File

@@ -72,7 +72,7 @@ class PlaceAsset(Submittable):
null=True null=True
) )
class PlaceImage (PlaceAsset): class PlaceImage(PlaceAsset):
""" """
PlaceImage defines an image file object that points to a file in uploads/. PlaceImage defines an image file object that points to a file in uploads/.
Intermediate image sizes are generated as defined in THUMBNAIL_ALIASES. Intermediate image sizes are generated as defined in THUMBNAIL_ALIASES.
@@ -104,7 +104,6 @@ class PlaceImage (PlaceAsset):
return 'Image ' + str(self.pk) return 'Image ' + str(self.pk)
# These two auto-delete files from filesystem when they are unneeded: # These two auto-delete files from filesystem when they are unneeded:
@receiver(post_delete, sender=PlaceImage) @receiver(post_delete, sender=PlaceImage)
@@ -118,7 +117,6 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
thumbmanager = get_thumbnailer(instance.filename) thumbmanager = get_thumbnailer(instance.filename)
thumbmanager.delete(save=False) thumbmanager.delete(save=False)
@receiver(pre_save, sender=PlaceImage) @receiver(pre_save, sender=PlaceImage)
def auto_delete_file_on_change(sender, instance, **kwargs): def auto_delete_file_on_change(sender, instance, **kwargs):
""" """
@@ -137,5 +135,4 @@ def auto_delete_file_on_change(sender, instance, **kwargs):
# No need to delete thumbnails, as they will be overwritten on regeneration. # No need to delete thumbnails, as they will be overwritten on regeneration.
new_file = instance.filename new_file = instance.filename
if not old_file == new_file: if not old_file == new_file:
if os.path.isfile(old_file.path): old_file.delete(save=False)
os.remove(old_file.path)

View File

@@ -71,6 +71,11 @@
<span class="LP-Paragraph">{{asset_count}}</span> <span class="LP-Paragraph">{{asset_count}}</span>
</td> </td>
</tr> </tr>
<tr>
<td>
<a href="/explorer/update/"><button class="LP-Button LP-Button">{% trans 'Edit Profile' %}</button></a>
</td>
</tr>
</table> </table>
</div> </div>
</div> </div>

View File

@@ -1,13 +1,13 @@
{% extends 'global.html'%} {% extends 'global.html'%}
{% load static %}
{% load i18n %} {% load i18n %}
{% load thumbnail %}
{% load widget_tweaks %} {% load widget_tweaks %}
# {% block title %}{% trans 'Edit Explorer profile' %}{% endblock %} # {% block title %}{% trans 'Edit Explorer profile' %}{% endblock %}
{% block maincontent %} {% block maincontent %}
<form class="LP-Form" method="POST"> <form class="LP-Form" method="POST" enctype="multipart/form-data">
<fieldset class="LP-Form__Fieldset"> <fieldset class="LP-Form__Fieldset">
<legend class="LP-Form__Legend">{% trans 'Edit Explorer profile' %}</legend> <legend class="LP-Form__Legend">{% trans 'Edit Explorer profile' %}</legend>
{% csrf_token %} {% csrf_token %}
@@ -35,9 +35,9 @@
</div> </div>
<div class="LP-Form__Composition"> <div class="LP-Form__Composition">
{% if explorer_image_url %} {% if explorer_image %}
<div class="LP-Form__Field"> <div class="LP-Form__Field">
<img class="LP-Form__Field LP-Image" src="{{ explorer_image_url }}"/> <img src="{% thumbnail explorer_image 200x200 %}"/>
</div> </div>
{% endif %} {% endif %}
<div class="LP-Form__Field"> <div class="LP-Form__Field">

View File

@@ -7,6 +7,7 @@ from django.utils.translation import ugettext_lazy as _
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.contrib import messages
from lostplaces.common import get_all_subclasses from lostplaces.common import get_all_subclasses
from lostplaces.views.base_views import IsAuthenticatedMixin from lostplaces.views.base_views import IsAuthenticatedMixin
@@ -47,8 +48,40 @@ class ExplorerProfileUpdateView(IsAuthenticatedMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
context = { context = {
'explorer_image_url': request.user.explorer.profile_image.url,
'explorer_user_change_form': ExplorerUserChangeForm(instance=request.user), 'explorer_user_change_form': ExplorerUserChangeForm(instance=request.user),
'explorer_change_form': ExplorerChangeForm(instance=request.user.explorer) 'explorer_change_form': ExplorerChangeForm(instance=request.user.explorer)
} }
if request.user.explorer.profile_image:
context['explorer_image'] = request.user.explorer.profile_image
return render(request, 'explorer/profile_update.html', context) return render(request, 'explorer/profile_update.html', context)
def post(self, request, *args, **kwargs):
print(request.POST)
explorer_user_change_form = ExplorerUserChangeForm(
request.POST,
instance=request.user
)
explorer_change_form = ExplorerChangeForm(
request.POST,
request.FILES,
instance=request.user.explorer
)
if explorer_change_form.is_valid() and explorer_user_change_form.is_valid():
explorer_user_change_form.save()
explorer_change_form.save()
print(explorer_change_form.cleaned_data)
messages.success(
self.request,
_('Successfully updated Explorer profile')
)
else:
# Usually the browser should have checked the form before sending.
messages.error(
self.request,
_('Please fill in all required fields.')
)
return redirect(reverse_lazy('explorer_profile_update'))

View File

@@ -151,3 +151,4 @@ class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
return redirect( return redirect(
reverse_lazy('place_detail', kwargs={'pk': place.pk}) reverse_lazy('place_detail', kwargs={'pk': place.pk})
) )