Django查询,其中1位于(第1列,第2列)

Django查询,其中1位于(第1列,第2列),django,postgresql,django-models,django-queryset,Django,Postgresql,Django Models,Django Queryset,在PostgreSQL中,此查询有效并生成正确的结果 SELECT ID FROM table WHERE 1 in (column1, column2); 下表给出的结果为0,2 +----+---------+---------+ | ID | column1 | column2 | +----+---------+---------+ | 0 | 1 | 0 | +----+---------+---------+ | 1 | 2 | 3

在PostgreSQL中,此查询有效并生成正确的结果

SELECT ID FROM table WHERE 1 in (column1, column2);
下表给出的结果为
0,2

+----+---------+---------+
| ID | column1 | column2 |
+----+---------+---------+
| 0  |    1    |    0    |
+----+---------+---------+
| 1  |    2    |    3    |
+----+---------+---------+
| 2  |    2    |    1    |
+----+---------+---------+
| 3  |    0    |    4    |
+----+---------+---------+ 
如何在Django ORM中建模

我考虑过自定义查找,但我需要
'1\uu myin'=[column1,column2]
生成
无法将关键字“1”解析为字段。
我希望避免使用原始SQL,因为我不希望错误地在代码中添加一些漏洞

在同一行上,所有列_x都有不同的值

请尝试使用,并仅对每一列进行检查

from django.db.models import Q

MyModel.objects.filter(Q(column1=1) | Q(column2=2))
这种情况下sql会是什么样子

SELECT * FROM sometable WHERE column1=1 OR column2=1

最后,我实现了一个自定义过滤器来实现“反向输入”,这样您就可以查询列而不是值

过滤器是这样工作的

col\u name\u 1\u\u revin=[值,'col\u name\u 2','col\u name\u 3']

它产生了

值在(“表名”、“列名”、“1”、“表名”、“2”、“表名”、“3”)

仅在
IntegerField
上测试,但也应与其他字段一起使用,只要提供正确的值类型

from django.db.models import lookups
import re

class ReverseIn(lookups.In):
    lookup_name = 'revin'

    def get_prep_lookup(self):
        # We will always call this on a ChampionIntegerField with lookup_name = revin
        if not hasattr(self.rhs, '__iter__'):
            raise ValueError('ReverseIn only works with iterables. Got {} of type {}.'.format(self.rhs),type(self.rhs))
        self.table_name = self.lhs.field.model._meta.db_table
        self.output_field = self.lhs.output_field
        rhs = list(self.rhs)
        lhs = self.lhs.field.column
        try:
            self.lhs = self.lhs.output_field.get_prep_lookup("exact", rhs[0])
        except (TypeError, ValueError) as e:
            raise ValueError('The type of the first item of the argument must be compatible with the type of the column', e)
        return [lhs] + rhs[1:]

    def process_rhs(self, compiler, connection):
        if self.rhs_is_direct_value():
            # Do the quoting yourself, as Django outputs ' instead of " for parameters, and PostgreSQL complains
            # THIS IS DANGEROUS!!!!! I wish I could do it with parameters...
            def sql_sanitize(value):
                # Check if the value respects the rules for column names
                if re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*', value):
                    return value
                else:
                    raise ValueError("The argument {} is not a valid column name".format(value))

            sql = ", ".join('"{}"."{}"'.format(self.table_name, sql_sanitize(value)) for value in set(self.rhs))
            params = []
            return sql, params
        else:
            raise NotImplementedError("ReverseIn only supports direct values")

    def as_sql(self, compiler, connection):
        rhs, rhs_params = self.process_rhs(compiler, connection)
        sql = "%s IN ({rhs})".format(rhs=rhs)
        params = [self.lhs]
        params.extend(rhs_params)
        return sql, params

IntegerField.register_lookup(ReverseIn)

我有5个这样的列,我想对它们匹配多达4个值。这意味着20个AND/OR,而在输入时,我只得到4个AND。有没有办法翻转IN子句?
values=[1,2,3,4]
.filter(Q(column1_uuin=values)| Q(column2_uin=values)|……)
?它返回至少有一列在值中的任何行,不是吗?我想返回其中4列等于值的每一行,其中一列是任意值。对于值=[1,2,3,4],我希望列是[1,2,3,4,X]的任何排列,这应该是您的问题:P如果所有列都不同(如您的问题中所述),那么只需使用
&
而不是
|
。您是对的。对不起,我很难表达这个概念:)我希望代码能够表达它。我不能只使用5&因为值中不会有一列。所以我需要做5,或者里面有4,我检查列[1,2,3,4],列[1,2,3,5],列[1,2,4,5],列[1,3,4,5],列[2,3,4,5],列[2,3,4,5]。如果我需要3个值,组合会增加更多。。