Почему моя фильтрация набора запросов по действительным пк возвращает полный набор запросов?
Насколько я понимаю, кверисеты всегда можно фильтровать. Однако, если я создам этот кверисет, фильтрация нарушится:
set_synonyms = Compound.objects.filter(synonyms__name__icontains=query_string)
Это правильный набор вопросов:
<QuerySet [<Compound: 2-[4-(2-methylpropyl)phenyl]propanoic acid>, <Compound: 2-[4-(2-methylpropyl)phenyl]propanoic acid>, <Compound: 2-[4-(2-methylpropyl)phenyl]propanoic acid>, <Compound: 2-[4-(2-methylpropyl)phenyl]propanoic acid>, '...(remaining elements truncated)...']>
и я могу получить pk любого элемента кверисета, например:
pk=set_synonyms.first().pk
(pk имеет значение 76). Но когда я фильтрую по нему, возвращается весь набор запросов:
set_synonyms.filter(pk=pk)
просто возвращает весь кверисет set_synonyms
. А использование set_synonyms.get(pk=pk)
вызывает MultipleObjectsReturned
исключение (потому что возвращает весь кверисет set_synonyms
).
Возможная релевантная информация: отношение между моделями Compound
и Synonym
является отношением 1 ко многим (1 соединение имеет много синонимов).
class Synonym(MixinPubChemCompound, models.Model):
"""Model definition for synonym naming of compound"""
name = models.CharField(max_length=999, db_index=True, null=True)
compound = models.ForeignKey(
Compound, on_delete=models.CASCADE, related_name='synonyms')
retrieved_from = models.ForeignKey(
generic_models.Reference, related_name='synonyms',
on_delete=models.PROTECT)
class Compound(MixinPubChemCompound, models.Model):
cid = models.IntegerField(unique=True, db_index=True)
iupac_name = models.ForeignKey(
IupacName, on_delete=models.PROTECT, unique=False)
Очевидно, что в строке запроса было несколько синонимов одного и того же соединения. Таким образом, в результирующем кверисете были дубликаты одного и того же соединения. Таким образом, фильтрация по pk этого набора возвращает несколько экземпляров в наборе (в данном конкретном случае весь набор). Добавление distinct()
решает проблему. Таким образом, замена
set_synonyms = Compound.objects.filter(synonyms__name__icontains=query_string)
с
set_synonyms = Compound.objects.filter(synonyms__name__icontains=query_string).distinct()
решает проблему.