如何对多个外键进行排除Django查询

时间:2019-05-01 03:10:57

标签: python django

我的模型示例:

assigned_at

我希望查询所有没有return User.objects.exclude( alpha_thing__assigned_at__isnull=True ).exclude( beta_thing__assigned_at__isnull=True ).all() 日期的事物的用户,即他们可以拥有其他事物,但是应该设置日期。

我尝试过:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"
        />

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

但是结果为空(事物表为空,所以我不确定它是否与联接有关?)。

4 个答案:

答案 0 :(得分:7)

这怎么办

from django.db.models import Q

User.objects.filter(Q(alpha_thing__assigned_at__isnull=False) | Q(beta_thing__assigned_at__isnull=False)).distinct()

屏幕截图

1。身份验证模型结构-User Auth Model

2。事物模型 Thing model data

答案 1 :(得分:2)

还有另一种方法,因为您要过滤“事物”包含所有assigned_date的用户。

您可以:

User.objects.filter(
    alpha_thign__assigned_at__isnull=False,
    beta_thign__assigned_at__isnull=False,
)

简单。

这里不需要使用Q对象或|(或)操作。

您想要的不是

  • alpha_thing__assigned_at__isnull=False
  • beta_thing__assigned_at__isnull=False

您正在寻找的是

  • alpha_thing__assigned_at__isnull=False AND
  • beta_thing__assigned_at__isnull=False

答案 2 :(得分:0)

对于没有日期为空的事物的所有用户,请尝试:

return User.objects.exclude(
    alpha_thing__assigned_at=None
).exclude(
    beta_thing__assigned_at=None
).all()

顺便说一句,无论是否使用.all(),我都得到相同的结果,所以:

return User.objects.exclude(
    alpha_thing__assigned_at=None
).exclude(
    beta_thing__assigned_at=None
)

返回与第一个示例相同的结果。

答案 3 :(得分:0)

您尝试过这样的事情吗?

from django.db.models import Q

has_null_alpha = Q(alpha_thing__isnull=False, alpha_thing__assigned_at__isnull=True)

has_null_beta = Q(beta_thing__isnull=False, beta_thing__assigned_at__isnull=True)

User.objects.exclude(has_null_alpha | has_null_beta)

推理

我认为您看到意外结果的原因可能与查询集中有多个ForeignKey路径这一事实无关。您所说的“事物表为空”可能是关键,而用户未出现的原因是他们没有alpha_thingbeta_thing关系。< / p>

注意:

  • QuerySet User.objects.exclude(alpha_thing__assigned_at__isnull=True)User表和Thing表之间产生左外部联接,这意味着在对WHERE子句进行任何比较之前,那么在没有NULL的任何行中,您都会得到assigned_at的{​​{1}}。

  • 一个真正奇怪的事情是Thing导致了 INNER 联接,因此语句filter实际上只产生了实际上 User.objects.filter(alpha_thing__assigned_at__isnull=False)的相关对象具有alpha_thing的非NULL值(排除那些没有相关assigned_at的人)。