martsberger / django-pivot

A module for pivoting Django Querysets
MIT License
209 stars 16 forks source link

Bug with binary fields #23

Closed P3RI9 closed 11 months ago

P3RI9 commented 2 years ago

Hi! I have detected what I think is a bug with this library when using binary fields on a django model. The problem is that answers aren't shown right, just as 0.0 values Code to reproduce this bug: Models:

from django.db import models
class Student(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Subject(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Grades(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
    marks = models.BinaryField()

    def __str__(self):
        return f"{self.student}, {self.subject}, {self.marks}"

Code to fill models with django-shell

from core.models import *
from django_pivot.pivot import pivot

students = ['Jacob', 'Ameliee']
subjects = ['Math', 'Science']
marks = [[b'Bilbao', b'Mariano'], [b'Murcia', b'Concha']]

for i, student_name in enumerate(students):
    st = Student(name=student_name)
    st.save()
    for j, subject_name in enumerate(subjects):
        su = Subject(name=subject_name)
        su.save()
        g = Grades(student=st, subject=su, marks=marks[i][j])
        g.save()

pivot(Grades, 'student__name', 'subject__name', 'marks')

When you change Grades.marks to a SmallIntegerField (in example) it works fine. Could you help me?

martsberger commented 11 months ago

It's not clear to me what you're trying to accomplish. Unfortunately, when I do this suggestion:

When you change Grades.marks to a SmallIntegerField (in example) it works fine.

It does not work fine, I get an error that the field marks expected a number but got b'Bilbao'. Which makes sense, you can't store a string in an integer field. Also, these strings are unusual for "marks" which are usually numbers.

If I use a BinaryField for marks and populate the data like this

marks = [[b'35', b'82'], [b'93', b'71']]

then the pivot table comes out fine. I can even add more marks for a student and see that the aggregations like Sum and Avg work. I'm not sure what you'd expect if you try to aggregate strings with Sum or Avg or if that is really your intended use case.