Django Django 2中带有Exists子查询的表达式出现时引发:NotImplementedError:对位逻辑运算使用.bitand和.bitor

问题描述

models.py

class PersonPhoneQuerySet(models.QuerySet):

    def with_bill_sums(self,bill_date_from: datetime.date,bill_date_till: datetime.date):
        return self.annotate(
            sum_all=Coalesce(
                Sum('telephone__bill__value',filter=Q(
                    telephone__bill__dt__gte=bill_date_from,telephone__bill__dt__lte=bill_date_till,)),Value(0)
            ),sum_service=Coalesce(
                Sum(
                    Case(
                        When(
                            Q(
                                # Problem line
                                Exists(Telephone.objects.filter(num=OuterRef('telephone__bill__call_to'))) |
                                Q(telephone__bill__bill_type=BillType.INTERNET) |
                                Q(telephone__bill__bill_type=BillType.PAYMENT) |
                                Q(telephone__bill__call_to=BILL_IN_ROAMING_AON_TEXT),telephone__bill__dt__gte=bill_date_from,),then='telephone__bill__value'),default=0,output_field=models.DecimalField()
                    )),)


class Telephone(models.Model):
    num = models.CharField('Номер',max_length=50,unique=True)
    sim = models.CharField('SIM карта',blank=True)


class Person(models.Model):
    fio = models.CharField('ФИО',max_length=50)
    email = models.EmailField('Email',null=True,blank=True)


class PersonPhone(models.Model):
    BIG_DATE = datetime.date(3333,1,1)

    objects = PersonPhoneQuerySet.as_manager()

    telephone = models.ForeignKey(Telephone,models.CASCADE,verbose_name='Телефон')
    person = models.ForeignKey(Person,verbose_name='Сотрудник')
    date_from = models.DateField('Начало периода привязки')
    date_till = models.DateField('Конец периода привязки',default=BIG_DATE)
    limit = models.IntegerField('Лимит',default=0)
    tariff = models.CharField('Тариф',max_length=20,blank=True,default='')


class Bill(models.Model):
    telephone = models.ForeignKey(Telephone,verbose_name='Телефон')
    bill_type = models.DecimalField('Тип соединения',choices=BillType.choices,db_index=True,max_digits=1,decimal_places=0)
    dt = models.DateTimeField('Дата и время звонка')
    value = models.DecimalField('Стоимость',max_digits=10,decimal_places=4,default=0)
    call_to = models.CharField('Вызываемый абонент',max_length=32,default='',db_index=True)
    duration = models.DecimalField('Продолжительность,сек',max_digits=8,decimal_places=0,blank=True)
    call_direction = models.CharField('Направление соединения',choices=CallDirection.choices,max_length=1,default=CallDirection.UNDEFINED)

运行:

from apps.mobile import models,consts
from common_tools.date import last_day_of_month

date_from = datetime.datetime(2020,5,1)
date_till = last_day_of_month(date_from)
qs = models.PersonPhone.objects.filter(
    person__fio__icontains='SomeMan',telephone__num__icontains='+79655171234',date_from__lte=date_from,date_till__gte=date_till,).with_bill_sums(date_from,date_till)
for i in qs:
    print(
        i,'\n sum_all: {}'.format(i.sum_all),'\n sum_service: {}'.format(i.sum_service),)

它适用于Django 3。

是否可以使用django 2运行它?

如果我将Exists expr移至命名注释-然后将其分组。

我可以通过Bill查询来实现它,但是想要使用PersonPhoneQuerySet.with_bill_sums

跟踪:

Traceback (most recent call last):
  File "C:/kvk/develop/Python/int/manage.py",line 21,in <module>
    main()
  File "C:/kvk/develop/Python/int/manage.py",line 17,in main
    execute_from_command_line(sys.argv)
  File "C:\python\venv\int\lib\site-packages\django\core\management\__init__.py",line 381,in execute_from_command_line
    utility.execute()
  File "C:\python\venv\int\lib\site-packages\django\core\management\__init__.py",line 375,in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\python\venv\int\lib\site-packages\django\core\management\base.py",line 323,in run_from_argv
    self.execute(*args,**cmd_options)
  File "C:\python\venv\int\lib\site-packages\django\core\management\base.py",line 364,in execute
    output = self.handle(*args,**options)
  File "C:\kvk\develop\Python\int\int\management\commands\exec.py",line 60,in handle
    return str(function(**kwargs))
  File "C:\kvk\develop\Python\int\apps\mobile\samples\check.py",line 482,in main
    qs_logic1()
  File "C:\kvk\develop\Python\int\apps\mobile\samples\check.py",line 389,in qs_logic1
    qs = models.PersonPhone.objects.filter(
  File "C:\kvk\develop\Python\int\apps\mobile\models.py",line 95,in with_bill_sums
    Exists(Telephone.objects.filter(num=OuterRef('telephone__bill__call_to'))) |
  File "C:\python\venv\int\lib\site-packages\django\db\models\expressions.py",line 106,in __or__
    raise NotImplementedError(
NotImplementedError: Use .bitand() and .bitor() for bitwise logical operations.

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)