Generated: Thu 2013-03-14 13:13 SGT
Source file: /Users/martin/Repos/django-user-media/user_media/views.py
Stats: 81 executed, 0 missed, 9 excluded, 100 ignored
"""Views for the ``django-user-media`` app."""
from django.contrib.auth.decorators import login_required
from django.contrib.contenttypes.models import ContentType
from django.db.models import ObjectDoesNotExist
from django.http import Http404
from django.utils.decorators import method_decorator
from django.views.generic import CreateView, DeleteView, UpdateView
from django_libs.views_mixins import AjaxResponseMixin
from user_media.forms import UserMediaImageForm
from user_media.models import UserMediaImage
class UserMediaImageViewMixin(object):
"""
Mixin for views that deal with `UserMediaImage` objects.
When using this mixin please make sure that you call `_add_next_and_user()`
in your `dispatch()` method.
"""
model = UserMediaImage
def _add_next_and_user(self, request):
self.next = request.POST.get('next', '') or request.GET.get('next', '')
self.user = request.user
def get_context_data(self, **kwargs):
"""
Adds `next` to the context.
This makes sure that the `next` parameter doesn't get lost if the
form was submitted invalid.
"""
ctx = super(UserMediaImageViewMixin, self).get_context_data(**kwargs)
ctx.update({
'action': self.action,
'next': self.next,
})
return ctx
def get_success_url(self):
"""
Returns the success URL.
This is either the given `next` URL parameter or the content object's
`get_absolute_url` method's return value.
"""
if self.next:
return self.next
if self.object and self.object.content_object:
return self.object.content_object.get_absolute_url()
raise Exception(
'No content object given. Please provide ``next`` in your POST'
' data')
class CreateImageView(AjaxResponseMixin, UserMediaImageViewMixin, CreateView):
action = 'create'
form_class = UserMediaImageForm
ajax_template_prefix = 'partials/ajax_'
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
"""Adds useful objects to the class and performs security checks."""
self._add_next_and_user(request)
self.content_object = None
self.content_type = None
self.object_id = kwargs.get('object_id', None)
if kwargs.get('content_type'):
# Check if the user forged the URL and posted a non existant
# content type
try:
self.content_type = ContentType.objects.get(
model=kwargs.get('content_type'))
except ContentType.DoesNotExist:
raise Http404
if self.content_type:
# Check if the user forged the URL and tries to append the image to
# an object that does not exist
try:
self.content_object = \
self.content_type.get_object_for_this_type(
pk=self.object_id)
except ObjectDoesNotExist:
raise Http404
if self.content_object:
# Check if the user forged the URL and tries to append the image to
# an object that does not belong to him
if not self.content_object.user == self.user:
raise Http404
return super(CreateImageView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super(CreateImageView, self).get_context_data(**kwargs)
ctx.update({
'content_type': self.content_type,
'object_id': self.object_id,
})
return ctx
def get_form_kwargs(self):
kwargs = super(CreateImageView, self).get_form_kwargs()
kwargs.update({
'user': self.user,
'content_type': self.content_type,
'object_id': self.object_id,
})
return kwargs
class DeleteImageView(AjaxResponseMixin, UserMediaImageViewMixin, DeleteView):
"""Deletes an `UserMediaImage` object."""
action = 'delete'
model = UserMediaImage
ajax_template_prefix = 'partials/ajax_'
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
"""Adds useful objects to the class."""
self._add_next_and_user(request)
return super(DeleteImageView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super(DeleteImageView, self).get_context_data(**kwargs)
ctx.update({
'image_pk': self.object.pk,
})
return ctx
def get_queryset(self):
"""
Making sure that a user can only delete his own images.
Even when he forges the request URL.
"""
queryset = super(DeleteImageView, self).get_queryset()
queryset = queryset.filter(user=self.user)
return queryset
class UpdateImageView(AjaxResponseMixin, UserMediaImageViewMixin, UpdateView):
"""Updates an existing `UserMediaImage` object."""
action = 'update'
model = UserMediaImage
form_class = UserMediaImageForm
ajax_template_prefix = 'partials/ajax_'
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
"""Adds useful objects to the class."""
self._add_next_and_user(request)
return super(UpdateImageView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super(UpdateImageView, self).get_context_data(**kwargs)
ctx.update({
'content_type': self.object.content_type,
'object_id': self.object.object_id,
'image_pk': self.object.pk,
})
return ctx
def get_form_kwargs(self):
kwargs = super(UpdateImageView, self).get_form_kwargs()
kwargs.update({
'user': self.user,
'content_type': self.object.content_type,
'object_id': self.object.object_id,
})
return kwargs
def get_queryset(self):
"""
Making sure that a user can only edit his own images.
Even when he forges the request URL.
"""
queryset = super(UpdateImageView, self).get_queryset()
queryset = queryset.filter(user=self.user)
return queryset