Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django查询忽略预期结果_Python_Mysql_Django_Django Orm - Fatal编程技术网

Python Django查询忽略预期结果

Python Django查询忽略预期结果,python,mysql,django,django-orm,Python,Mysql,Django,Django Orm,我必须在一个有点复杂的建模的大型数据库上执行查询,我将尝试在下面对其进行简化: class ScreeningItem(models.Model): # other fields receivedItem = models.OneToOneField(ReceivedItem, null=True, on_delete=models.SET_NULL) class ReceivedItem(models.Model): # other fields dossie

我必须在一个有点复杂的建模的大型数据库上执行查询,我将尝试在下面对其进行简化:

class ScreeningItem(models.Model):
    # other fields
    receivedItem = models.OneToOneField(ReceivedItem, null=True, on_delete=models.SET_NULL)

class ReceivedItem(models.Model):
    # other fields
    dossier = models.ForeignKey(Dossier, null=True, on_delete=models.SET_NULL)

class Dossier(models.Model):
    # other fields
    subjects = models.ManyToManyField('SubjectTypes', through='Subjects',
                                      through_fields=('dossier', 'subjectType'))

class Subject(models.Model):
    main = models.BooleanField(null=True)
    dossier = models.ForeignKey(Dossier, null=True, on_delete=models.SET_NULL)
    subjectType =  models.ForeignKey(SubjectType, null=True, on_delete=models.SET_NULL)

class SubjectType(models.Model):
    # other fields
    name = models.CharField(max_length=255, null=True, blank=True)
    parent = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
现在的问题是,我必须在
ScreeningItem
表项中查找相关字段
SubjectType.name
包含特定单词时的项目。不,更糟。正如您在下面看到的,在该模型中有一个父子自引用,我必须在相关的
SujectType
中查找这些特定的单词,如果它们存在的话,还有它们的父代和祖父母

我的尝试:

exp = 'something'
queryset = ScreeningItem.objects.filter(
    Q(receivedItem__dossier__subjects__subjecttype__name__iregex=exp) |     
    Q(receivedItem__dossier__subjects__subjecttype__parent__name__iregex=exp) |     
    Q(receivedItem__dossier__subjects__subjecttype__parent__parent__name__iregex=exp))     
然而,当我收到大量远低于我预期的记录时,我检查了数据库,惊讶地发现有许多
ScreeningItem
有一个
ReceivedItem
,其中有一个
档案
,与
主题类型
相关,其中有我正在搜索的单词

不幸的是,这里不允许我透露内容。因此,我在下面编写了测试例程:

def test():
    exp = 'something'  # valid and equal both for Python and MySQL regular expression engines
    re_exp = re.compile(exp, re.IGNORECASE)
    queryset_1 = ScreeningItem.objects.filter(
        Q(receivedItem__dossier__subjects__subjecttype__name__iregex=exp) |     
        Q(receivedItem__dossier__subjects__subjecttype__parent__name__iregex=exp) |     
        Q(receivedItem__dossier__subjects__subjecttype__parent__parent__name__iregex=exp))     
    set_1 = set(queryset_1.values_list('id', flat=True))
    print(len(set_1))

    queryset_2 = GnomoItemTriagem.objects.filter(receivedItem__dossier__isnull=False)
    set_2a = set()
    set_2b = set()
    for item in queryset_2:
        subjects = item.receivedItem.dossier.subjects
        if subjects.filter(
                Q(name__iregex=exp) |
                Q(parent__name__iregex=exp) |
                Q(parent__parent__name__iregex=exp)).count() > 0:
            set_2a.add(item.id)

        for subject in subjects.all():
            if re_exp.findall(subject.name) or\
                (subject.parent and re_exp.findall(subject.parent.name)) or \
                    (subject.parent and subject.parent.parent and re_exp.findall(subject.parent.parent.name)):
                set_2b.add(item.id)

    print(len(set_2a))
    print(len(set_2b))
然后我的结果是

1596
21223
21223

那么,我的第一个查询应该如何编写,才能同时返回所有21223个所需的项目呢?我做错了什么?

由于
主题
主题类型
的多对多字段,它已经“着陆”在该模型上。您可以查询另一个
\u subjecttype
的原因是,它正在“反向”中访问父项的
外键

因此,您的查询应该如下所示:

queryset = ScreeningItem.objects.filter(
    Q(receivedItem__dossier__subjects__name__iregex=exp) |     
    Q(receivedItem__dossier__subjects__parent__name__iregex=exp) |     
    Q(receivedItem__dossier__subjects__parent__parent__name__iregex=exp)
)
queryset=ScreeningItem.objects.filter(
Q(受试者档案、受试者姓名、iregex=exp)|
Q(受访对象、家长、姓名、经验)
Q(接收数据、档案、受试者、家长、家长、姓名、iregex=exp)
)

它没有出错的原因是您的
父关系没有
相关的\u名称
。因此,这意味着您的
父关系的默认
相关的\u name\u查询
主题类型
。因此,您可以进行一个查询,在其中查找带有
receivedItem的
ScreeningItem
,以及带有As
SubjectType的
SubjectType
子对象的
SubjectType
,或者该子对象的父对象,子部分因此出错。

您需要提供样本、编辑的数据,并向我们显示您正在获得的结果和您期望的结果。第二个不应该是'Q(subjecttype\uuu name\uu iregex=exp)`所以在过滤中使用
subjecttype\uuu
作为“前缀”。现在看起来您正在搜索名为
exp
的主题。(可能是您未共享的模型的某些部分)@WillemVanOnsem
主题
档案
模型中的字段,它通过
主题
模型将“多对多”与
主题类型
模型关联,哪一个是链接表。@VBobCat:ah但是接下来的查询应该是
receivedItem\uuuuuu-dossier\uuuuu-subjects\uuuuuuuuu-name\uuuuuuuuu-iregex=…
我猜?@VBobCat:因为您模型的名称是
subjecttype
。由于您没有为
父对象定义
相关的\u名称
,因此父对象的“反向”关系名称的默认名称为
\u subjecttype
。因此,您在这里基本上查询了一个
ScreeningItem
和一个
receivedItem
和一个
docsier
和一个名为
SubjectType
的子SubjectType,或者该子对象的父对象,等等。