Add ability to upload photos to an event
This commit is contained in:
parent
9d51251031
commit
fc198115e7
8 changed files with 128 additions and 6 deletions
|
@ -5,7 +5,7 @@ from django.utils.safestring import mark_safe
|
||||||
from .models.locale import Language, Continent, Country, SPR, City
|
from .models.locale import Language, Continent, Country, SPR, City
|
||||||
from .models.profiles import UserProfile, Organization, Team, Member, Category, Topic
|
from .models.profiles import UserProfile, Organization, Team, Member, Category, Topic
|
||||||
from .models.search import Searchable
|
from .models.search import Searchable
|
||||||
from .models.events import Place, Event, Attendee
|
from .models.events import Place, Event, EventPhoto, Attendee
|
||||||
|
|
||||||
admin.site.register(Language)
|
admin.site.register(Language)
|
||||||
admin.site.register(Continent)
|
admin.site.register(Continent)
|
||||||
|
@ -59,6 +59,8 @@ class EventAdmin(admin.ModelAdmin):
|
||||||
attendee_count.short_description = 'Attendees'
|
attendee_count.short_description = 'Attendees'
|
||||||
admin.site.register(Event, EventAdmin)
|
admin.site.register(Event, EventAdmin)
|
||||||
|
|
||||||
|
admin.site.register(EventPhoto)
|
||||||
|
|
||||||
class MemberAdmin(admin.ModelAdmin):
|
class MemberAdmin(admin.ModelAdmin):
|
||||||
list_display = ('__str__', 'role')
|
list_display = ('__str__', 'role')
|
||||||
list_filter = ('role', 'team')
|
list_filter = ('role', 'team')
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from .models.profiles import Team, UserProfile
|
from .models.profiles import Team, UserProfile
|
||||||
from .models.events import Event, Place
|
from .models.events import Event, Place, EventPhoto
|
||||||
|
|
||||||
from datetime import time
|
from datetime import time
|
||||||
from time import strptime, strftime
|
from time import strptime, strftime
|
||||||
|
@ -196,6 +196,11 @@ class NewTeamEventForm(forms.ModelForm):
|
||||||
class DeleteEventForm(forms.Form):
|
class DeleteEventForm(forms.Form):
|
||||||
confirm = forms.BooleanField(label="Yes, delete event", required=True)
|
confirm = forms.BooleanField(label="Yes, delete event", required=True)
|
||||||
|
|
||||||
|
class UploadEventPhotoForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = EventPhoto
|
||||||
|
fields = ['src', 'title', 'caption']
|
||||||
|
|
||||||
class NewPlaceForm(forms.ModelForm):
|
class NewPlaceForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Place
|
model = Place
|
||||||
|
|
31
events/migrations/0017_add_event_images.py
Normal file
31
events/migrations/0017_add_event_images.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Generated by Django 2.0 on 2018-03-17 20:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import imagekit.models.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('events', '0016_make_searchable_uri_unique'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EventPhoto',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('title', models.CharField(max_length=256)),
|
||||||
|
('caption', models.TextField(blank=True, null=True)),
|
||||||
|
('src', models.ImageField(upload_to='event_photos')),
|
||||||
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='photos', to='events.Event')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='userprofile',
|
||||||
|
name='avatar',
|
||||||
|
field=imagekit.models.fields.ProcessedImageField(default='http://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?d=mm', upload_to='avatars', verbose_name='Photo Image'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -6,6 +6,9 @@ from django.shortcuts import reverse
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from imagekit.models import ImageSpecField
|
||||||
|
from imagekit.processors import ResizeToFill
|
||||||
|
|
||||||
from .locale import *
|
from .locale import *
|
||||||
from .profiles import *
|
from .profiles import *
|
||||||
from .search import *
|
from .search import *
|
||||||
|
@ -183,4 +186,13 @@ class Attendee(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s at %s" % (self.user, self.event)
|
return "%s at %s" % (self.user, self.event)
|
||||||
|
|
||||||
|
class EventPhoto(models.Model):
|
||||||
|
event = models.ForeignKey(Event, related_name='photos', on_delete=models.CASCADE)
|
||||||
|
title = models.CharField(max_length=256)
|
||||||
|
caption = models.TextField(null=True, blank=True)
|
||||||
|
src = models.ImageField(verbose_name=_('Photo'), upload_to='event_photos')
|
||||||
|
thumbnail = ImageSpecField(source='src',
|
||||||
|
processors=[ResizeToFill(250, 187)],
|
||||||
|
format='JPEG',
|
||||||
|
options={'quality': 60})
|
||||||
|
|
14
get_together/templates/get_together/events/add_photo.html
Normal file
14
get_together/templates/get_together/events/add_photo.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "get_together/base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Add photo to {{event.name}}</h2>
|
||||||
|
<form enctype="multipart/form-data" action="{% url "add-event-photo" event.id%}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<table>
|
||||||
|
{{ photo_form }}
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary">Upload</button>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
|
<link href="{% static 'css/bootstrap-album.css' %}" rel="stylesheet"/>
|
||||||
<style>
|
<style>
|
||||||
.gt-profile {
|
.gt-profile {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -20,7 +21,9 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 16px;
|
top: 16px;
|
||||||
left: 6px;
|
left: 6px;
|
||||||
|
}
|
||||||
|
.table td, .table th {
|
||||||
|
border-top: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -62,6 +65,31 @@
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><h4>Photos</h4><hr/></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
{% for photo in event.photos.all %}
|
||||||
|
<div class="card mb-4 box-shadow mr-1" style="width: 250px">
|
||||||
|
<div class="card-banner">
|
||||||
|
<a href="{{photo.src.url}}" target="_blank">
|
||||||
|
<img class="card-img-top" src="{{photo.thumbnail.url}}" alt="{{photo.title}}">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p class="card-text"><strong>{{photo.title}}</strong></p>
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<small class="text-muted">{{photo.caption}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><a class="btn btn-primary" href="{% url 'add-event-photo' event.id %}">Upload</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
|
|
@ -62,6 +62,7 @@ urlpatterns = [
|
||||||
path('events/<int:event_id>/+delete/', views.delete_event, name='delete-event'),
|
path('events/<int:event_id>/+delete/', views.delete_event, name='delete-event'),
|
||||||
path('events/<int:event_id>/+add_place/', views.add_place_to_event, name='add-place'),
|
path('events/<int:event_id>/+add_place/', views.add_place_to_event, name='add-place'),
|
||||||
path('events/<int:event_id>/+share/', views.share_event, name='share-event'),
|
path('events/<int:event_id>/+share/', views.share_event, name='share-event'),
|
||||||
|
path('events/<int:event_id>/+photo/', views.add_event_photo, name='add-event-photo'),
|
||||||
path('events/<int:event_id>/<str:event_slug>/', views.show_event, name='show-event'),
|
path('events/<int:event_id>/<str:event_slug>/', views.show_event, name='show-event'),
|
||||||
|
|
||||||
path('places/', views.places_list, name='places'),
|
path('places/', views.places_list, name='places'),
|
||||||
|
|
|
@ -6,9 +6,9 @@ from django.shortcuts import render, redirect
|
||||||
from django.http import HttpResponse, JsonResponse
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
|
||||||
from events.models.profiles import Team, UserProfile, Member
|
from events.models.profiles import Team, UserProfile, Member
|
||||||
from events.forms import TeamEventForm, NewTeamEventForm, DeleteEventForm, NewPlaceForm
|
from events.forms import TeamEventForm, NewTeamEventForm, DeleteEventForm, NewPlaceForm, UploadEventPhotoForm
|
||||||
|
|
||||||
from events.models.events import Event, Place, Attendee
|
from events.models.events import Event, EventPhoto, Place, Attendee
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import simplejson
|
import simplejson
|
||||||
|
@ -62,6 +62,35 @@ def create_event(request, team_id):
|
||||||
else:
|
else:
|
||||||
return redirect('home')
|
return redirect('home')
|
||||||
|
|
||||||
|
def add_event_photo(request, event_id):
|
||||||
|
event = Event.objects.get(id=event_id)
|
||||||
|
if not request.user.profile.can_edit_event(event):
|
||||||
|
messages.add_message(request, messages.WARNING, message=_('You can not make changes to this event.'))
|
||||||
|
return redirect(event.get_absolute_url())
|
||||||
|
|
||||||
|
if request.method == 'GET':
|
||||||
|
form = UploadEventPhotoForm()
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'event': event,
|
||||||
|
'photo_form': form,
|
||||||
|
}
|
||||||
|
return render(request, 'get_together/events/add_photo.html', context)
|
||||||
|
elif request.method == 'POST':
|
||||||
|
new_photo = EventPhoto(event=event)
|
||||||
|
form = UploadEventPhotoForm(request.POST, request.FILES, instance=new_photo)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return redirect(event.get_absolute_url())
|
||||||
|
else:
|
||||||
|
context = {
|
||||||
|
'event': event,
|
||||||
|
'photo_form': form,
|
||||||
|
}
|
||||||
|
return render(request, 'get_together/events/add_photo.html', context)
|
||||||
|
else:
|
||||||
|
return redirect('home')
|
||||||
|
|
||||||
def add_place_to_event(request, event_id):
|
def add_place_to_event(request, event_id):
|
||||||
event = Event.objects.get(id=event_id)
|
event = Event.objects.get(id=event_id)
|
||||||
if not request.user.profile.can_edit_event(event):
|
if not request.user.profile.can_edit_event(event):
|
||||||
|
|
Loading…
Reference in a new issue