【问题标题】:Django NOT IN without NOT NULL没有 NOT NULL 的 Django NOT IN
【发布时间】:2013-01-12 10:14:17
【问题描述】:

我正在为我的开发板软件实现“忽略用户”功能。该功能必须隐藏由用户忽略的成员启动的线程。我决定将被忽略用户的 ID 提取到 python 列表中,如果该列表不为空,则将排除添加到查询集。

if ignored_users:
    queryset_threads = queryset_threads.exclude(start_poster_id__in=ignored_users)

但是,exclude 的工作方式存在问题,即“调用 filter() 并在开头添加 NOT”。在这里,过滤器产生以下 SQL:

`threads_thread` . `start_poster_id` IN (2, 3, 4, 5) AND `threads_thread` . `start_poster_id` NOT NULL

如何摆脱 NOT NULL?已删除帐户的成员发布的主题在“start_poster_id”列中为 NULL。

【问题讨论】:

    标签: django django-orm


    【解决方案1】:

    您发布的原始 SQL 似乎不正确。它实际上是无效的。 NOT NULL 是什么值?

    无论如何,NULL 不是从.exclude() 添加的。它必须从代码中的其他位置添加。

    .exclude() 只是将WHERE NOT 添加到您指定的参数中 - 它不会添加它自己的参数。

    See the docs for .exclude() here.

    例如:

    >>> query = Threads.objects.exclude(id__in=[1,2,3,4]).query.__str__()
    >>> query
    'SELECT `test_threads`.`id`, `test_threads`.`threads_name` 
    FROM `test_threads` 
    WHERE NOT (`test_threads`.`id` IN (1, 2, 3, 4))'
    

    您最初分配的queryset_threads 是否过滤NOT NULL?类似这样:

    >>> query = Threads.objects.filter(id__isnull=False)
    >>> query = query.exclude(id__in=[1,2,3,4]).query.__str__()
    >>> query
    'SELECT `test_threads`.`id`, `test_threads`.`threads_name` 
    FROM `test_threads` 
    WHERE (`test_threads`.`id` IS NOT NULL 
    AND NOT (`test_threads`.`id` IN (1, 2, 3, 4)))'
    

    【讨论】:

    • NOT NULL 源自 start_poster ForeignKey 字段,该字段可以为空(即线程属于已删除成员时)。当我过滤(start_poster_id__in=[1, 2, 3, 4])时,会导致“IN AND NOT NULL”SQL。当我使用排除时,它只是将过滤器包装在 NOT 中。我正在寻找的是告诉 Django 忽略字段可以为空的事实。现在我正在使用自定义 WHERE via .extra()
    • 请发布整个视图。 filter 和 exclude 都不应该为外键添加额外的参数。完整视图将帮助我查看指定 NULL 的位置。
    猜你喜欢
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2011-03-29
    • 2011-01-15
    相关资源
    最近更新 更多