Django 2.2 ORM 排除未按预期工作
Django 2.2 ORM Exclude Not Working as expected
我正在尝试从 Cust
模型中获取所有在 Stat (ForeignKey)、Django 2.2 中没有记录的客户列表
class Cust(models.Model):
name = models.CharField(max_length=50)
active = models.BooleanField(default=True)
class Stat(models.Model):
cust = models.ForeignKey(Cust, on_delete=models.PROTECT, null=True)
date = models.DateField(null=True, blank=True)
我正在尝试这个但没有用,
month = datetime.now()
month = month.strftime("%Y-%m")
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=inner_qs)
print(inner_qs)
print(data)
上面的查询返回:
<QuerySet [<Stat: Ruth>]>
<QuerySet [<Cust: Jhonny>, <Cust: Rony>, <Cust: Sinta>, <Cust: Ruth>]>
如您所见,我需要从数据 queryset/list 中排除结果 [<Stat: Ruth>]
。
但我期望的是:
<QuerySet [<Stat: Ruth>]>
<QuerySet [<Cust: Jhonny>, <Cust: Rony>, <Cust: Sinta>>
根据 django 文档 1 关于 __in
,它指出:
In a given iterable; often a list, tuple, or queryset. It’s not a common use case, but strings (being iterables) are accepted.
有几种方法可以解决这个问题。
替换
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=inner_qs)
1. 和
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=[o.cust_id for o in inner_qs])
2.另一种方式是用
代替
id_list =Stat.objects.filter(date__icontains=month)\
.values_list('cust_id', flat=True)\
# flat=True will return list rather
# than tuple in the ValueListQueryset
data = Cust.objects.exclude(id__in=id_list)
在这里,你首先生成一个排除id_list然后用它来排除。
3. #2 的修改方式 distinct()
id_list =Stat.objects.filter(date__icontains=month)\
.values_list('cust_id', flat=True)\
.distinct().order_by()
# distinct() is used to get unique 'cust_id's
# distinct() does not work without order_by()
data = Cust.objects.exclude(id__in=id_list)
我正在尝试从 Cust
模型中获取所有在 Stat (ForeignKey)、Django 2.2 中没有记录的客户列表
class Cust(models.Model):
name = models.CharField(max_length=50)
active = models.BooleanField(default=True)
class Stat(models.Model):
cust = models.ForeignKey(Cust, on_delete=models.PROTECT, null=True)
date = models.DateField(null=True, blank=True)
我正在尝试这个但没有用,
month = datetime.now()
month = month.strftime("%Y-%m")
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=inner_qs)
print(inner_qs)
print(data)
上面的查询返回:
<QuerySet [<Stat: Ruth>]>
<QuerySet [<Cust: Jhonny>, <Cust: Rony>, <Cust: Sinta>, <Cust: Ruth>]>
如您所见,我需要从数据 queryset/list 中排除结果 [<Stat: Ruth>]
。
但我期望的是:
<QuerySet [<Stat: Ruth>]>
<QuerySet [<Cust: Jhonny>, <Cust: Rony>, <Cust: Sinta>>
根据 django 文档 1 关于 __in
,它指出:
In a given iterable; often a list, tuple, or queryset. It’s not a common use case, but strings (being iterables) are accepted.
有几种方法可以解决这个问题。
替换
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=inner_qs)
1. 和
inner_qs = Stat.objects.filter(date__icontains=month)
data = Cust.objects.exclude(id__in=[o.cust_id for o in inner_qs])
2.另一种方式是用
代替 id_list =Stat.objects.filter(date__icontains=month)\
.values_list('cust_id', flat=True)\
# flat=True will return list rather
# than tuple in the ValueListQueryset
data = Cust.objects.exclude(id__in=id_list)
在这里,你首先生成一个排除id_list然后用它来排除。
3. #2 的修改方式 distinct()
id_list =Stat.objects.filter(date__icontains=month)\
.values_list('cust_id', flat=True)\
.distinct().order_by()
# distinct() is used to get unique 'cust_id's
# distinct() does not work without order_by()
data = Cust.objects.exclude(id__in=id_list)