Почему моя фильтрация набора запросов по действительным пк возвращает полный набор запросов?

Насколько я понимаю, кверисеты всегда можно фильтровать. Однако, если я создам этот кверисет, фильтрация нарушится:

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()

решает проблему.

Вернуться на верх