Question

I have two classes - Arzt and Fachbereich - related by a ManyToMany relationship through ArztFachbereich.

class Fachbereich(FachbereichUndArztFachbereiche):
    name = models.CharField(unique=True, max_length=100)

class Arzt(models.Model):
    name = models.CharField(max_length=500)
    fachbereich = models.ManyToManyField(Fachbereich, through="ArztFachbereich")

class ArztFachbereich(FachbereichUndArztFachbereiche):
    arzt = models.ForeignKey(Arzt)
    fachbereich = models.ForeignKey(Fachbereich)
    note = models.FloatField()

I know how I can get the result ordered by the minimum note for Arzt.

Arzt.objects.annotate(best_note=Min("arztfachbereich__note")).order_by("best_note")

But next I first filter Arzt by a Fachbereich-ID (fb_id). And now I do not need the minimum note or something aggregated, but the note for this specific ArztFachbereich.

To clarify what I am talking about: something like this... but I have no clue how to do it in django.

aerzte = Arzt.objects.filter(fachbereich=fb_id)
aerzte.order_by("arztfachbereich__note"
                WHERE arztfachbereich__fachbereich == 
                Fachbereich.objects.get(id=fb_id))

Or another way I thought about:

aerzte = Arzt.objects.filter(fachbereich=fb_id)
aerzte.annotate(specific=ArztFachbereich.objects.get(arzt=self, fachbereich__id=fb_id)
aerzte.order_by("specific")

But I obviously can't access arzt wit that self statement...

Was it helpful?

Solution

If I understand you correctly, this should work:

Arzt.objects.filter(arztfachbereich__fachbereich_id=fb_id)
            .order_by("arztfachbereich__note")

Any queries about this relationship are going to operate on the ArztFachbereich table (possibly JOINed to the Arzt and Fachbereich tables, depending on the query). Here, the filter() is going to correspond to a SQL WHERE clause that limits the rows to a specific value of fachbereich_id, and the order_by then orders the remaining rows by the note value.

I think your confusion comes from the fact that we're querying on the Artz model. Does this make more sense: ArztFachbereich.objects.filter(fachbereich_id=fb_id).order_by("note")? The two statement are essentially equivalent, but filtering on Artz lets you end up with Artz objects rather than ArztFachbereich objects.

(If it's not the case that artz and fachbereich are unique_together, you will also need to put distinct() at the end of the query to make sure you don't end up with duplicate Artz instances in your final query set.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top