def add(self, obj, usr, opt): """ Add/modify a user option. """ # Retreive the method and content type for the supplied instance. method = method_for_instance(obj) ctype = ContentType.objects.get_for_model(obj) # Check if obj and usr exist and if opt is a valid option. if not obj or not usr or not method or not opt in method.options: return False try: # Get the RatingData instance for the supplied arguments data = self.get(content_type__pk=ctype.pk, object_id=obj.pk, user__pk=usr.pk) # If something was found, and the method allows changes and # if the supplied opt is different then the current option, # then save the new option for the usr. if method.allow_change and data.option != opt: data.option = opt data.update = datetime.datetime.now() data.save() return True return False except RatingData.DoesNotExist: # If no record was found, create a new one data = self.create(content_type=ctype, object_id=obj.pk, user=usr, option=opt) return True
def total(self, obj, opt=None): """ Returns the total # of ratings for the supplied object. Can also be supplied for a option to get the total for a certain option. """ ctype = ContentType.objects.get_for_model(obj) method = method_for_instance(obj) # If a option is specifed, add the option to the query. opt_kwargs = {} if opt in method.options: opt_kwargs = {'option': opt} return self.filter(content_type__pk=ctype.pk, object_id=obj.pk, **opt_kwargs).aggregate( Count('id'))['id__count']
def data(self): """ Retrieves a break down of totals and percentages for each option. """ method = method_for_instance(self.instance) return_data = {} for opt in method.options: opt_total = RatingData.objects.total(self.instance, opt=opt) if opt_total == 0 or self.total == 0: perc = 0 else: perc = float(opt_total) / float(self.total) return_data[str(opt)] = { 'percentage': int(perc * 100), 'total': opt_total} return return_data
def render(obj, **extra_context): t = None try: ct = ContentType.objects.get_for_model(obj) method = method_for_instance(obj) except: return None model = ct.model.lower() app = ct.app_label.lower() try: # Retreive the template from the method. t = get_template(method.template) except: try: # Retrieve the template based of off the content object t = get_template('critic/%s__%s.html' % (app, model)) except: # Use the default if no template was found. t = get_template('critic/render.html') if not t: return None # The conext that will be passed to the rendered template. from critic.models import RatingData context = { 'obj': obj, 'method': method, 'content_type_id': ct.pk, 'average': RatingData.objects.average(obj), 'total': RatingData.objects.total(obj)} context.update(extra_context) # Render the template return render_to_string(t.name, context)