Django从另一个Queryset中排除Queryset中的Items

时间:2015-01-08 15:38:09

标签: python django django-queryset

我有一个非常复杂的模型设置:

  • Audiofiles存储在不同的数据库中。
  • 用户可以选择数据库,然后应该是随机的音频文件 地选择。
  • 对于每个数据库,都有一个问题列表,其中一个是 随机挑选。

  • 每次用户访问数据库时都会保存答案 必须确保他没有得到相同的组合 (Audiofile,Question)他已经回答了。

这是我的代码:

class Database(models.Model):
    name = models.CharField(max_length=200, unique=True)
    questions = models.ManyToManyField(Question)

class AudioData(models.Model):    
    database = models.ForeignKey(Database)

class Question(models.Model):
    ...

# added as a helper class for this problem
class AudioQuestionPair(models.Model):
    audioData = models.ForeignKey(AudioData)
    question = models.ForeignKey(Question)
    database = models.ForeignKey(Database)

class NewAnswer(models.Model):
    user = models.ForeignKey(User)
    question = models.ForeignKey(Question)
    audioData = models.ForeignKey(AudioData)
    timestamp = models.DateField(auto_now_add=True)
    body = models.TextField()

我试图找出,如何(有效地,无需进入无限循环)选择一个可用的音频,问题对。目前我已经达到了这样的程度,即我可以获得答案的字典,仅包含所需的ID和对列表。但我无法弄清楚如何从对中排除答案。

answers = NewAnswer.objects.filter(user=request.user).filter(audioData__database=id).values('audioData_id', 'question_id')

结果

[{'audioData_id': 2, 'question_id': 2}, {'audioData_id': 1, 'question_id': 1}]

获得所有可用的对

pairs = AudioQuestionPair.objects.filter(database=id).values('audioData_id', 'question_id')

结果

 [{'audioData_id': 1, 'question_id': 1}, {'audioData_id': 2, 'question_id': 1}, {'audioData_id': 5, 'question_id': 1}, {'audioData_id': 6, 'question_id': 1}, {'audioData_id': 7, 'question_id': 1}]

如何在第三步中排除这一点?

1 个答案:

答案 0 :(得分:-1)

编辑:很抱歉没有立即理解您的问题;

似乎最肮脏的选择是在每个答案上循环:

answers = NewAnswer.objects.filter(user=request.user).filter(audioData__database=id).values_list('audioData_id', 'question_id')
available_pairs = AudioQuestionPair.objects.filter(database=id)
for a in answers:
    available_pairs = available_pairs.exclude(audioData_id=a[0], question_id=a[1])

还应该可以遍历每个NewAnswer并构建一个(可能很大的)Q对象并使用它来执行一个大的OR查询,但我不确定这是否考虑到QuerySet在被查看之前不会被评估,将会大大提高性能。