通过模型过滤的Django ManyToMany关系

时间:2020-01-12 15:43:11

标签: sql django

假设我具有以下设置(models.py)

class Person(models.Model):
  name = models.CharField(....)


class EventInfo(models.Model):
 attending = models.BooleanField(default=True)
 event = models.ForeignKey('Event')
 person = models.ForeignKey('Person')

class Event(models.Model):
  start = models.DateTimeField(....)
  ....
  participants = models.ManyToManyField(Person, through=EventInfo)

我知道participants实际上是RelatedManager类型的对象这一事实,我可以这样查询它:

e = Event.objects.get(...)
e.participants.filter(name="John") #gives me the Person named 'John'

但是我所缺少的是通过使用指定的直通模型来(例如)过滤所有参加我的活动的所有人的直观方法。 我知道我可以做以下事情之一:

e = Event.objects.get(...)
# would give me a queryset of EventInfo objects, but theres no easy way to get all persons from that:
qs = EventInfo.objects.filter(event=e, attending=True) 

# would give me in fact all persons, but seems rather unintuitive:
qs = Person.objects.filter(eventinfo__event=e, eventinfo__attending=True)

# same thing, quite unintuitive having to query from "the other side"
e.participants.filter(eventinfo__attending=True)

我想写些什么:

e = Event.objects.get(...)
e.participants.filter(attending=True)

这会给我一个人的名单。这是不可能的,因为participants过滤Person而不过滤EventInfo 我在这里想念什么吗?

1 个答案:

答案 0 :(得分:0)

在这里您需要做的是反向外键查找。 因此,要通过参与者访问EventInfo的属性,您将必须执行以下操作。

 import java.util.Scanner;

    class Grades {

        public static boolean isAlphabetOnly(String str) 
        { 
            return (str.matches("^[a-zA-Z]*$")); 
        }   

      public static void main(String[] args) {
        int j = 1;
        double sum = 0;
        double average;

        Scanner keyboard = new Scanner(System.in);
        System.out.println("Insert Student's Name");
        String name = keyboard.next();
        if(!isAlphabetOnly(name)){
            System.out.println("Please enter alfabets only");
            return;
        }
        System.out.println("Insert Student's Surname");
        String surname = keyboard.next();

        System.out.println("Student's name: " + name + " " + surname);

        System.out.println("How many Grades?");
        int nVotes = keyboard.nextInt();
        int[] arrayVotes = new int[nVotes];

        System.out.println("Now insert all the grades");

        for (int i=0; i<arrayVotes.length; i++) {
          System.out.println("Insert the grade " + j);
          arrayVotes[i] = keyboard.nextInt();
          j++;
        }

        for (int i=0; i<arrayVotes.length; i++) {
          sum += arrayVotes[i];
        }

        average = sum / arrayVotes.length;
        System.out.println("Student's grade average is: " + average);

        System.out.println("Does he have a good behaviour? Answer with true or false");
        boolean behaviourStudent = keyboard.nextBoolean();

        average = !behaviourStudent ? Math.floor(average) : Math.ceil(average);

        System.out.println("The grade now is: " + average);

        keyboard.close();
      }
    }