【问题标题】:Complex Query for Django ORMDjango ORM 的复杂查询
【发布时间】:2013-06-09 00:18:10
【问题描述】:

我正在尝试使用 Django 的 ORM 执行一个复杂的查询,但我似乎找不到一个好的解决方案。也就是说,我有一个 Web 应用程序,用户可以在其中根据视频回答问题。我需要显示至少有一个问题未回答(未回答)的指定用户的所有视频。我还不能用 ORM 弄明白……我知道我可能会为此编写一个 SQL 查询并使用原始 SQL 函数执行它,但我真的更愿意留在 ORM 中。

模型:视频、问题、响应和默认用户。

关系:

  • 问题与视频有多对多的关系
  • Response 对 Question、Video 和 User 各有一个外键

查询需要做什么:

  • 显示指定用户至少有一个视频问题未回答(未回答)的所有视频。

任何帮助都会很棒!我已经为此苦苦挣扎了太久了。

编辑:我拥有的模型是(简化的):

class Video(TimeStampedModel):

     title = models.CharField(max_length=200)
     source_id = models.CharField(max_length=20)


class Question(TimeStampedModel):

    DEMOGRAPHIC_QUESTION = 'd'
    QUESTION_TYPES = (
        (VIDEO_QUESTION, 'Video related question'),
        (DEMOGRAPHIC_QUESTION, 'Demographic question'),
    )

    MULTIPLE_CHOICE = 0
    PLAIN_TEXT = 1
    RESPONSE_TYPE = (
        (MULTIPLE_CHOICE, 'Multiple Choice'),
        (PLAIN_TEXT, 'Plain Text')
    )

    type = models.CharField(max_length=1, choices=QUESTION_TYPES)
    videos = models.ManyToManyField(Video, null=True, blank=True)
    title = models.CharField(max_length=500)
    priority = models.IntegerField()

class Response(TimeStampedModel):
     user = models.ForeignKey(User)
     question = models.ForeignKey(Question)
     video = models.ForeignKey(Video, blank=True, null=True)
     choice = models.ForeignKey(Choice, null=True, blank=True,related_name='selected_choice')
     text = models.CharField(max_length=500, blank=True)

// Not relevant but included for clarity
class Choice(TimeStampedModel):
     question = models.ForeignKey(Question)
     text_response = models.CharField(max_length=500)
     image = models.FileField(upload_to=_get_choice_img_path, blank=True)
     value = models.IntegerField(default=0)
     external_id = models.IntegerField(default=0)

【问题讨论】:

  • 分享您拥有的模型。这样帮助会更容易
  • 问题视频是多对多?为什么?似乎每个问题都只与一个视频有关,即使每个视频都有很多问题。
  • 是的问题视频是多对多的,因为我们希望能够将同一个问题应用于多个视频。例如 - 你最喜欢这个视频的哪个方面。这个问题适用于许多视频。

标签: django django-orm


【解决方案1】:

从您的模型的外观逻辑上判断,我认为接近以下内容应该没问题。

q = Response.objects.select_related().filter(user__name=user).filter(response__choice=None)

videos = Video.objects.filter(id__in=q.extra(where=["{}>=1".format(q.count())]).values('video_id'))

希望你明白我在那里做了什么。第一行基本上尝试对模型对象进行自然连接。第二行使用第一行中生成的查询来获取计数并检查它是否至少为 1,并获取属于该查询的视频。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-27
    • 2012-08-03
    • 1970-01-01
    • 2021-09-07
    • 2020-01-03
    • 2015-12-06
    • 2015-05-16
    • 2011-06-08
    相关资源
    最近更新 更多