【问题标题】:filtering a queryset, applying more than one filter过滤查询集,应用多个过滤器
【发布时间】:2018-11-27 04:02:42
【问题描述】:

我的模型是:

models.User:
       id = pk
       username = text

    models.Offer
       id = pk           
       description = text
       publicationDate = Date
       user = Fk(User)

    my serializer is:

    class UserOfferSerializer(ModelSerializer):
        offers = OfferSerializerAll(many=True, read_only=True)
        class Meta:
            model = User
            fields = ('id', 'username', 'offers')

我正在尝试在查询集上应用多个过滤器:

users = users.filter(offers__publicationDate__range=[startdate, enddate]). prefetch_related(Prefetch('offers', queryset=Offer.objects.filter(
publicationDate__range=[startdate, enddate]))).distinct()

然后

users = users.filter(offers__description__icontains=sometext).prefetch_related(Prefetch('offers', queryset=Offer.objects.filter(description__icontains=sometext))).distinct()

第一个工作正常,另一个抛出以下异常:

ValueError: 'offers' lookup was already seen with a different queryset. You may need to adjust the ordering of your lookups.

更新:

我当前的代码是:

    if (offerBeginDate != None and offerEndDate != None):
        b = offerBeginDate.split('-')
        e = offerEndDate.split('-')

        startdate = datetime.date(int(b[0]), int(b[1]), int(b[2]))
        enddate = datetime.date(int(e[0]), int(e[1]), int(e[2]))

        users = users.filter(offers__publicationDate__range=[startdate, enddate])
        offers = offers.filter(publicationDate__range=[startdate, enddate])

    if (descriptionText != None):

        users = users.filter(offers__functionDescription__icontains=descriptionText.strip())
        offers = offers.filter(functionDescription__icontains=descriptionText.strip())


    users = users.prefetch_related('offers', Prefetch(queryset=offers))

有什么帮助吗?谢谢大家:)))

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    您可以使用Prefetch 对象的to_attr 参数来预取额外的查询集:

    users = users.filter(offers__description__icontains=sometext).prefetch_related(
            Prefetch('offers', queryset=Offer.objects.filter(
    publicationDate__range=[startdate, enddate]), to_attr='date_offers'), 
            Prefetch('offers', queryset=Offer.objects.filter(description__icontains=sometext), to_attr='description_offers')).distinct()
    

    UPD

    如果您需要为预取的查询集动态添加过滤器,您可以像这样单独定义它:

    if some_case:
        users = users.filter(offers__description__icontains=sometext)
        offers=Offer.objects.filter(description__icontains=sometext)
    if some_case_2:
        users = users.filter(**conditions)
        offers = offers.filter(**conditions)
    
    users = users.prefetch_related(Prefetch('offers', queryset=offers))
    

    现在 users 查询集中的每个用户都有两个属性:user.date_offersuser.description_offers

    【讨论】:

    • 非常感谢 :)) 我正在尝试让它工作但尚未成功,我会尽快更新
    • 我也尝试在两个阶段应用预取,因为我不想总是应用两个过滤器,这取决于用户的选择。
    • 我需要这样申请:if(date!=None): apply first filter if(sometext!=None): apply second filter
    • @RodwanBakkar 是的,这是我的代码中的错误。我已经更新了答案。检查一下。
    • 是的,对不起,这些过滤器让我强调我看不到变化,它就像一个魅力,非常感谢你拯救了我的一天:))))))
    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 2019-02-09
    • 2021-05-30
    • 1970-01-01
    • 2013-01-01
    • 2014-06-12
    相关资源
    最近更新 更多