user_media.views: 90 total statements, 100.0% covered

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

  1. """Views for the ``django-user-media`` app."""
  2. from django.contrib.auth.decorators import login_required
  3. from django.contrib.contenttypes.models import ContentType
  4. from django.db.models import ObjectDoesNotExist
  5. from django.http import Http404
  6. from django.utils.decorators import method_decorator
  7. from django.views.generic import CreateView, DeleteView, UpdateView
  8. from django_libs.views_mixins import AjaxResponseMixin
  9. from user_media.forms import UserMediaImageForm
  10. from user_media.models import UserMediaImage
  11. class UserMediaImageViewMixin(object):
  12. """
  13. Mixin for views that deal with `UserMediaImage` objects.
  14. When using this mixin please make sure that you call `_add_next_and_user()`
  15. in your `dispatch()` method.
  16. """
  17. model = UserMediaImage
  18. def _add_next_and_user(self, request):
  19. self.next = request.POST.get('next', '') or request.GET.get('next', '')
  20. self.user = request.user
  21. def get_context_data(self, **kwargs):
  22. """
  23. Adds `next` to the context.
  24. This makes sure that the `next` parameter doesn't get lost if the
  25. form was submitted invalid.
  26. """
  27. ctx = super(UserMediaImageViewMixin, self).get_context_data(**kwargs)
  28. ctx.update({
  29. 'action': self.action,
  30. 'next': self.next,
  31. })
  32. return ctx
  33. def get_success_url(self):
  34. """
  35. Returns the success URL.
  36. This is either the given `next` URL parameter or the content object's
  37. `get_absolute_url` method's return value.
  38. """
  39. if self.next:
  40. return self.next
  41. if self.object and self.object.content_object:
  42. return self.object.content_object.get_absolute_url()
  43. raise Exception(
  44. 'No content object given. Please provide ``next`` in your POST'
  45. ' data')
  46. class CreateImageView(AjaxResponseMixin, UserMediaImageViewMixin, CreateView):
  47. action = 'create'
  48. form_class = UserMediaImageForm
  49. ajax_template_prefix = 'partials/ajax_'
  50. @method_decorator(login_required)
  51. def dispatch(self, request, *args, **kwargs):
  52. """Adds useful objects to the class and performs security checks."""
  53. self._add_next_and_user(request)
  54. self.content_object = None
  55. self.content_type = None
  56. self.object_id = kwargs.get('object_id', None)
  57. if kwargs.get('content_type'):
  58. # Check if the user forged the URL and posted a non existant
  59. # content type
  60. try:
  61. self.content_type = ContentType.objects.get(
  62. model=kwargs.get('content_type'))
  63. except ContentType.DoesNotExist:
  64. raise Http404
  65. if self.content_type:
  66. # Check if the user forged the URL and tries to append the image to
  67. # an object that does not exist
  68. try:
  69. self.content_object = \
  70. self.content_type.get_object_for_this_type(
  71. pk=self.object_id)
  72. except ObjectDoesNotExist:
  73. raise Http404
  74. if self.content_object:
  75. # Check if the user forged the URL and tries to append the image to
  76. # an object that does not belong to him
  77. if not self.content_object.user == self.user:
  78. raise Http404
  79. return super(CreateImageView, self).dispatch(request, *args, **kwargs)
  80. def get_context_data(self, **kwargs):
  81. ctx = super(CreateImageView, self).get_context_data(**kwargs)
  82. ctx.update({
  83. 'content_type': self.content_type,
  84. 'object_id': self.object_id,
  85. })
  86. return ctx
  87. def get_form_kwargs(self):
  88. kwargs = super(CreateImageView, self).get_form_kwargs()
  89. kwargs.update({
  90. 'user': self.user,
  91. 'content_type': self.content_type,
  92. 'object_id': self.object_id,
  93. })
  94. return kwargs
  95. class DeleteImageView(AjaxResponseMixin, UserMediaImageViewMixin, DeleteView):
  96. """Deletes an `UserMediaImage` object."""
  97. action = 'delete'
  98. model = UserMediaImage
  99. ajax_template_prefix = 'partials/ajax_'
  100. @method_decorator(login_required)
  101. def dispatch(self, request, *args, **kwargs):
  102. """Adds useful objects to the class."""
  103. self._add_next_and_user(request)
  104. return super(DeleteImageView, self).dispatch(request, *args, **kwargs)
  105. def get_context_data(self, **kwargs):
  106. ctx = super(DeleteImageView, self).get_context_data(**kwargs)
  107. ctx.update({
  108. 'image_pk': self.object.pk,
  109. })
  110. return ctx
  111. def get_queryset(self):
  112. """
  113. Making sure that a user can only delete his own images.
  114. Even when he forges the request URL.
  115. """
  116. queryset = super(DeleteImageView, self).get_queryset()
  117. queryset = queryset.filter(user=self.user)
  118. return queryset
  119. class UpdateImageView(AjaxResponseMixin, UserMediaImageViewMixin, UpdateView):
  120. """Updates an existing `UserMediaImage` object."""
  121. action = 'update'
  122. model = UserMediaImage
  123. form_class = UserMediaImageForm
  124. ajax_template_prefix = 'partials/ajax_'
  125. @method_decorator(login_required)
  126. def dispatch(self, request, *args, **kwargs):
  127. """Adds useful objects to the class."""
  128. self._add_next_and_user(request)
  129. return super(UpdateImageView, self).dispatch(request, *args, **kwargs)
  130. def get_context_data(self, **kwargs):
  131. ctx = super(UpdateImageView, self).get_context_data(**kwargs)
  132. ctx.update({
  133. 'content_type': self.object.content_type,
  134. 'object_id': self.object.object_id,
  135. 'image_pk': self.object.pk,
  136. })
  137. return ctx
  138. def get_form_kwargs(self):
  139. kwargs = super(UpdateImageView, self).get_form_kwargs()
  140. kwargs.update({
  141. 'user': self.user,
  142. 'content_type': self.object.content_type,
  143. 'object_id': self.object.object_id,
  144. })
  145. return kwargs
  146. def get_queryset(self):
  147. """
  148. Making sure that a user can only edit his own images.
  149. Even when he forges the request URL.
  150. """
  151. queryset = super(UpdateImageView, self).get_queryset()
  152. queryset = queryset.filter(user=self.user)
  153. return queryset