具有多个字段的模型中的查询集(Django)

时间:2018-04-26 00:57:08

标签: django django-models many-to-many django-queryset

我的问题与在多个到多个字段之间互连的模型上创建查询集有关。

context - 学生进入的应用程序,必须为其教师评分。应用程序显示学生的问题具有以下逻辑:每个学生必须评价一些教师。每位教师都有与他们相关的不同类别的问题(“智力”,“尊重”,“同理心”等),并且每个类别都有一些与之相关的问题。

模型是:

class Items(models.Model):
     item = models.TextField()
     def __str__(self):
          return self.item

class Categories(models.Model):
    category = models.CharField(max_length=50,null=True)
    items_associated  = models.ManyToManyField(Items)
    def __str__(self):
       return self.category

class Professors(models.Model):
    professor = models.CharField(max_length=50,null=True)
    categories_assigned = models.ManyToManyField(Categories)
    def __str__(self):
       return self.professor

class Students(models.Model):
    student_logged = models.CharField(max_length=50,null=True)
    professors_to_evaluate = models.ManyToManyField(Professors)
    def __str__(self):
       return self.student_logged
当学生进入网络时,有一些相关的教师(模范学生),这些教师又分配了一些类别(模型教授),这些类别又有一些相关的问题(模型类别)。 我想在字典中存储模型项目中的这些问题。我该怎么办?

我尝试过滤和__in,但我无法得到它。

非常感谢并感谢您的智慧

编辑:我会尝试给你一个例子,因为我认为这可能有点难以解释。

汤姆学生必须使他的老师有资格,他们是 rick-professor barney-teacher

Rick-professor 将根据问题类别进行评估:尊重待遇技术知识

尊重处理的类别存在与之相关的问题:

  • 老师平等对待每个人
  • 老师不说粗鲁的事情
  • 老师很善良

技术知识类别有与之相关的问题:

  • 他教得很清楚
  • 他展示了高级知识

所以我想要的是,当汤姆学生进入网络对Rick教授进行评级时,该应用程序会向他显示相关问题,在这种情况下是:

  • 老师平等对待每个人
  • 老师不说粗鲁的事情
  • 老师很善良
  • 他教得很清楚
  • 展示高级知识

然后当他去评价barney-teacher时,网站会根据barney-teacher指定的类别向他展示一些不同的问题。

1 个答案:

答案 0 :(得分:0)

我强烈建议您使用related_name属性。我已将_x添加到相关名称中,以使查询更加明显。

class Items(models.Model):
     item = models.TextField()
     def __str__(self):
          return self.item

class Categories(models.Model):
    category = models.CharField(max_length=50,null=True)
    items_associated  = models.ManyToManyField(Items, related_name='category_x')
    def __str__(self):
       return self.category

class Professors(models.Model):
    professor = models.CharField(max_length=50,null=True)
    categories_assigned = models.ManyToManyField(Categories, related_name='professor_x')
    def __str__(self):
       return self.professor

class Students(models.Model):
    student_logged = models.CharField(max_length=50,null=True)
    professors_to_evaluate = models.ManyToManyField(Professors, related_name='student_x')
    def __str__(self):
       return self.student_logged

items_for_student = Items.objects.filter(category_x__professor_x__student_x=student)

但是,您对字段使用的命名约定也有点古怪。我已经使用了以下最佳实践,因此您可以看到它的外观。

  1. 没有与模型同名的字段
  2. 模型应该是单数(极少数例外)
  3. ManyToMany或ForeignKey关系应该共享模型的名称以查询自己的文档。
  4. 这些规则就是最佳实践。

    class Item(models.Model):
         name = models.TextField()
         def __str__(self):
              return self.name
    
    class Category(models.Model):
        name = models.CharField(max_length=50,null=True)
        items = models.ManyToManyField(Item, related_name='categories')
        def __str__(self):
           return self.name
    
    class Professor(models.Model):
        name = models.CharField(max_length=50,null=True)
        categories = models.ManyToManyField(Category, related_name='professors')
        def __str__(self):
           return self.name
    
    class Student(models.Model):
        name = models.CharField(max_length=50,null=True)
        professors = models.ManyToManyField(Professor, related_names='students')
        def __str__(self):
           return self.name
    

    使用该结构,查询将如下所示:

    items = Item.objects.filter(categories__professors__students=student)
    

    另请注意,上述查询在数据库上运行的成本非常高,因为它会评估为3个连接。