add view to show speaker pictures without exposing all of MEDIA_ROOT

This commit is contained in:
Thomas Steen Rasmussen 2017-02-19 13:15:55 +01:00
parent cb5c2386eb
commit 56d8a9765d
3 changed files with 45 additions and 2 deletions

View file

@ -111,6 +111,11 @@ urlpatterns = [
SpeakerDetailView.as_view(),
name='speaker_detail'
),
url(
r'^speakers/(?P<slug>[-_\w+]+)/pictures/(?P<picture>[-_\w+]+)/$',
SpeakerPictureView.as_view(),
name='speaker_picture',
),
url(
r'^events/$',
EventListView.as_view(),

View file

@ -103,8 +103,12 @@ class EventInstance(CreatedUpdatedModel):
def get_speaker_picture_upload_path(instance, filename):
""" We want speaker pictures are saved as MEDIA_ROOT/speakers/bornhack-2016/filename """
return 'speakers/%s/%s' % (instance.camp.slug, filename)
""" We want speaker pictures are saved as MEDIA_ROOT/speakers/camp-slug/speaker-slug/filename """
return 'speakers/%(campslug)s/%(speakerslug)s/%(filename)s' % {
'campslug': instance.camp.slug,
'speakerslug': instance.slug,
'filename': filename
}
class Speaker(CreatedUpdatedModel):

View file

@ -6,6 +6,40 @@ from . import models
from django.http import Http404
import datetime
from django.conf import settings
from django.views import View
from django.views.decorators.http import require_safe
from django.http import Http404
from django.utils.decorators import method_decorator
@method_decorator(require_safe, name='dispatch')
class SpeakerPictureView(CampViewMixin, DetailView):
model = models.Speaker
def get(self, request, *args, **kwargs):
# do we have the requested picture?
if kwargs['picture'] == 'thumbnail':
if self.get_object().picture_small:
picture = self.get_object().picture_small
else:
raise Http404()
elif kwargs['picture'] == 'large':
if self.get_object().picture_small:
picture = self.get_object().picture_small
else:
raise Http404()
else:
raise Http404()
# make nginx return the picture using X-Accel-Redirect
# (this works for nginx only, other webservers use x-sendfile),
# TODO: what about runserver mode here?
response = HttpResponse()
response['X-Accel-Redirect'] = '/_media/speakers/%(campslug)s/%(speakerslug)s/%(filename)s' % {
'campslug': self.camp.slug,
'speakerslug': self.get_object().slug,
'filename': picture.name
}
return response
class SpeakerDetailView(CampViewMixin, DetailView):