1

I am trying to make a feedback app in Django, but I can not make my evaluations.

In my models.py, I have 5 choices from very bad to excellent. But I want them to be usable as numbers so I can evaluate the overall value.

After reading Set Django IntegerField by choices=... name I changed my Ratings from VERYBAD = 'Very bad' to VERYBAD = 1 but no I can't even save my value/form.

Feedback(models.Model):
    event = models.ForeignKey(Event)
    # Choice
    VERYBAD = 'Very bad'            #old
    BAD = 2                         #new
    OKAY = 3
    GOOD = 4
    EXCELLENT = 5
    RATING = (
        (VERYBAD, 'Very bad'),
        (BAD, 'Bad'),
        (OKAY, 'Okay'),
        (GOOD, 'Good'),
        (EXCELLENT, 'Excellent'),
    )

    # The ratings
    organisation = models.CharField(
        max_length=9,
        choices=RATING,
        default=OKAY,
    )
   ....

So in my view, I thought I can do the math but I can not.

def rating(request, event_id):
    myevent = Event.objects.get(id=event_id)
    feedback_items = Feedback.objects.filter(event=myevent)
    num_of_items = len(feedback_items)

    def evaluate(feedback_items):
       # The overall rating
       organisation = 0
       for item in feedback_items: 
            organisation += item.organisation

       organisation /= num_of_items

    context = {'feedback_items':feedback_items,
           'num_of_items': num_of_items,
           'myevent': myevent,}

return render(request, 'feedback/rating.html', context)

`

Community
  • 1
  • 1

1 Answers1

0

You have to make organisation an IntegerField, obviously - else you can't hope to do integer operations. If you already have this in production, use a set of migrations to add a new IntegerField, populate it from the existing CharField values (using a dict for mapping old string values to new int values), and finally getting rid of the original field.

Also, you may want to learn how to properly use Django's ORM features like getting related models instances and performing aggregations at the DB level, ie:

from django.db.models import Sum, Count, Avg

def rating(request, event_id):
    myevent = Event.objects.get(id=event_id)

    # this is how you get related models...
    feedback_items = myevent.feedback_set.all()

    # and this is how you use SQL aggregation functions:
    values = feedback_items.aggregate(
        sum=Sum('organisation'),
        count=Count('pk'),
        avg=Avg('organisation')
        )

    # Now 'values' should be a dict with 'sum', 'count' and 'avg'
    # keys, and values['avg'] should be equal to 
    # float(values['sum']) / values['count']
    # FWIW you probably don't need the 'sum' field at all
    # I mentionned it so you can check whether 'avg' value
    # is correct...

     context = {
       'feedback_items':feedback_items,
       'num_of_items': values['count'],
       'avg': values['avg'],
       'myevent': myevent,
        }

     # etc
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • Thank you very much. After rereading the making queries chapter I also managed to make a query that only shows my not already registered fighters in an events category. *Thumbs up* –  Dec 08 '16 at 08:56