1
from django.contrib.contenttypes.models import ContentType
2
from django.core.exceptions import ObjectDoesNotExist
3
from django.http import HttpResponse, Http404
5
from exceptions import *
6
from django.conf import settings
7
from default_settings import RATINGS_VOTES_PER_IP
9
class AddRatingView(object):
10
def __call__(self, request, content_type_id, object_id, field_name, score):
11
"""__call__(request, content_type_id, object_id, field_name, score)
13
Adds a vote to the specified model field."""
16
instance = self.get_instance(content_type_id, object_id)
17
except ObjectDoesNotExist:
18
raise Http404('Object does not exist')
20
context = self.get_context(request)
21
context['instance'] = instance
24
field = getattr(instance, field_name)
25
except AttributeError:
26
return self.invalid_field_response(request, context)
33
had_voted = bool(field.get_rating_for_user(request.user, request.META['REMOTE_ADDR'], request.COOKIES))
35
context['had_voted'] = had_voted
38
adds = field.add(score, request.user, request.META.get('REMOTE_ADDR'), request.COOKIES)
39
except IPLimitReached:
40
return self.too_many_votes_from_ip_response(request, context)
42
return self.authentication_required_response(request, context)
44
return self.invalid_rating_response(request, context)
45
except CannotChangeVote:
46
return self.cannot_change_vote_response(request, context)
47
except CannotDeleteVote:
48
return self.cannot_delete_vote_response(request, context)
50
return self.rating_changed_response(request, context, adds)
51
return self.rating_added_response(request, context, adds)
53
def get_context(self, request, context={}):
56
def render_to_response(self, template, context, request):
57
raise NotImplementedError
59
def too_many_votes_from_ip_response(self, request, context):
60
response = HttpResponse('Too many votes from this IP address for this object.')
63
def rating_changed_response(self, request, context, adds={}):
64
response = HttpResponse('Vote changed.')
66
cookie_name, cookie = adds['cookie_name'], adds['cookie']
68
response.delete_cookie(cookie_name)
70
response.set_cookie(cookie_name, cookie, 31536000, path='/') # TODO: move cookie max_age to settings
73
def rating_added_response(self, request, context, adds={}):
74
response = HttpResponse('Vote recorded.')
76
cookie_name, cookie = adds['cookie_name'], adds['cookie']
78
response.delete_cookie(cookie_name)
80
response.set_cookie(cookie_name, cookie, 31536000, path='/') # TODO: move cookie max_age to settings
83
def authentication_required_response(self, request, context):
84
response = HttpResponse('You must be logged in to vote.')
85
response.status_code = 403
88
def cannot_change_vote_response(self, request, context):
89
response = HttpResponse('You have already voted.')
90
response.status_code = 403
93
def cannot_delete_vote_response(self, request, context):
94
response = HttpResponse('You can\'t delete this vote.')
95
response.status_code = 403
98
def invalid_field_response(self, request, context):
99
response = HttpResponse('Invalid field name.')
100
response.status_code = 403
103
def invalid_rating_response(self, request, context):
104
response = HttpResponse('Invalid rating value.')
105
response.status_code = 403
108
def get_instance(self, content_type_id, object_id):
109
return ContentType.objects.get(pk=content_type_id)\
110
.get_object_for_this_type(pk=object_id)
113
class AddRatingFromModel(AddRatingView):
114
def __call__(self, request, model, app_label, object_id, field_name, score):
115
"""__call__(request, model, app_label, object_id, field_name, score)
117
Adds a vote to the specified model field."""
119
content_type = ContentType.objects.get(model=model, app_label=app_label)
120
except ContentType.DoesNotExist:
121
raise Http404('Invalid `model` or `app_label`.')
123
return super(AddRatingFromModel, self).__call__(request, content_type.id,
124
object_id, field_name, score)