neurix
neurix

Reputation: 4316

Django: SQL query with distinct on model function

Hi Stackoverflow people,

in my current project, I have the following model structure:

class Project(models.Model):
    student_id = models.ForeignKey(User)
    class_a = models.ForeignKey(ClassA)
    class_b = models.ForeignKey(ClassB)
    ...

class ClassA(models.Model):
    teacher_name = models.CharField(...)

class ClassB(models.Model):
    teacher_name = models.CharField(...)

ClassA and ClassB are very different and only they only have the teacher_name in common, therefore I keep it in separate classes. In addition, in each project only class_a or class_b can contain a ForeignKey (it can not be assigned to two classes).

When I display all projects and I want to list the names of the teacher, therefore I created a little model function, which returns the teacher's name:

def get_teacher_name(self):
    if self.class_a:
        return self.class_a.teacher_name
    if self.class_b:
        return self.class_b.teacher_name

Now, I want to write a query which returns the names of teachers for a student_id and only returns the teachers name once, e.g.: For Student X Project Teacher Biology Mrs. X Physics Mr. Y (-> Math Mr. Y should be disregarded)

How should I structure the Django query? I would like to do Project.objects.filter(student_id=user.pk).values('get_teacher_name').distinct(), but this is not possible. Is there a solution for it?

Thank you for your suggestions!

Upvotes: 3

Views: 381

Answers (1)

You'er looking for values and annotate https://docs.djangoproject.com/en/dev/topics/db/aggregation/#order-of-annotate-and-values-clauses

Which will give you unique values for a values call.

import itertools

class_a_names = user.project_set.values_list('class_a__teacher_name', flat=True).annotate()
class_b_names = user.project_set.values_list('class_b__teacher_name', flat=True).annotate()
unique_teachers = set(itertools.chain(class_a_names, class_b_names))

Upvotes: 3

Related Questions