Django: фильтровать записи на основе отношения «один ко многим»

#python #django #django-models

#python #django #django-модели

Вопрос:

У меня есть следующие модели,

 class User(models.Model):
    name = models.CharField(max_length=255)
    ...

class InsuranceProfile(models.Model):
       user = models.ForeignKey(User, on_delete=models.CASCADE)
       ...


class ProductExpertiseMaster(models.Model):
    class Meta:
        db_table = 'product_expertise_master'

    name = models.CharField(max_length=255)

    main_category = models.CharField(max_length=255)


class UserProductExpertise(models.Model): 
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
    product_expertise = models.ForeignKey(ProductExpertiseMaster, on_delete=models.DO_NOTHING)
 

Итак, что я пытаюсь сделать, я хочу фильтровать записи на основе различных полей, некоторые из которых принадлежат модели пользователя, а некоторые из них принадлежат InsuranceProfile модели.Я фильтрую записи на основе User amp; InsuranceProfile model, которые работают нормально. Теперь я хочу добавить еще один фильтр, который будет основан на UserProductExpertise модели. Я хочу получить все страховые профили с данными пользователя, которые имеют некоторое условие соответствия с записями экспертизы продукта в UserProductExpertise модели. Любая помощь будет оценена.

Ответ №1:

Вы можете попробовать так, используя __isnull :

 InsuranceProfile.objects.filter(user__userproductexpertise__isnull=False)
 

Он вернет всех пользователей, у которых есть запись в UserProductExpertise модели. Для запроса вам нужно использовать все строчные буквы имени модели (ie userproductexpertise ) и добавить __isnull в конце.

Комментарии:

1. Я думаю, мне нужно перефразировать свой вопрос. Я уже применяю фильтр к модели InsuranceProfile с помощью модели User, и я хочу добавить файл модели UserProductExpertise. Моим конечным результатом должны быть все записи, которые соответствуют всем трем моделям. Надеюсь, это очистит его или дайте мне знать, если хотите узнать больше.

Ответ №2:

Я думаю, вам следует внести некоторые изменения в свои модели, прежде чем продолжить.

Модель UserProductExpertise — это связующая таблица между ProductExpertiseMaster и User, которая обеспечивает связь «многие ко многим». Если вы не хотите добавлять дополнительные поля в модель UserProductExpertise, вы можете удалить ее и определить отношение пользователя в модели ProductExpertiseMaster.

Если вы предпочитаете использовать отдельную модель для этой связи, on_delete=models .DO_NOTHING подвержен ошибкам, вы можете изменить его на models .КАСКАД

Вот пример с отношением «многие ко многим»:

 class User(models.Model):
    name = models.CharField(max_length=255)

class InsuranceProfile(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.CharField(("Content"), max_length=500)


class ProductExpertiseMaster(models.Model):
    class Meta:
        db_table = 'product_expertise_master'

    name = models.CharField(max_length=255)

    main_category = models.CharField(max_length=255)
    user = models.ManyToManyField(User, verbose_name=("Users"), related_name="expertises")
 

Для фильтрации вашего запроса:

 InsuranceProfile.objects.filter(user__expertises__isnull=False)