Django 从另一个查询集中排除查询集中的项目
Django exclude Items from Queryset from another Queryset
我有一个相当复杂的模型设置:
- 音频文件存储在不同的数据库中。
- 用户可以select一个数据库,然后应该是一个随机的音频文件
selected.
每个数据库都有一个问题列表,其中一个将是
也是随机抽取的。
答案被保存,每次用户访问数据库时我
必须确保他没有得到相同的组合
(音频文件,问题)他已经回答了。
这是我的代码:
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()
我正在尝试弄清楚如何(有效且不会陷入无限循环)select 一个可用的音频、问题对。目前我已经到了可以得到答案的地步,其中只包含所需的 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}]
我现在如何在第三步中排除它?
编辑:很抱歉没有立即理解您的问题;
似乎最脏的选项是循环遍历每个答案:
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
s 在被查看之前不会被评估,将会大大提高性能。
我有一个相当复杂的模型设置:
- 音频文件存储在不同的数据库中。
- 用户可以select一个数据库,然后应该是一个随机的音频文件 selected.
每个数据库都有一个问题列表,其中一个将是 也是随机抽取的。
答案被保存,每次用户访问数据库时我 必须确保他没有得到相同的组合 (音频文件,问题)他已经回答了。
这是我的代码:
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()
我正在尝试弄清楚如何(有效且不会陷入无限循环)select 一个可用的音频、问题对。目前我已经到了可以得到答案的地步,其中只包含所需的 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}]
我现在如何在第三步中排除它?
编辑:很抱歉没有立即理解您的问题;
似乎最脏的选项是循环遍历每个答案:
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
s 在被查看之前不会被评估,将会大大提高性能。