Django Exists()/〜Exists()是否返回没有匹配的数据?

问题描述 投票:0回答:1

编辑:

根据下面的schillingt的回答,我已切换为使用Case / When:

        context['db_orders'] = Order.objects.filter(
            retailer_code=self.object.retailer_code).annotate(
            in_db=Case(When(Q(Subquery(self.object.suppliers.filter(
                supplier_code=(OuterRef('supplier_code')))
            ), then=Value(True), default=Value(False), output_field=NullBooleanField()))))

但是我现在正为一个错误而苦苦挣扎:

FieldError at /retailers/A001/

Cannot resolve expression type, unknown output_field

原始问题:

我在下面的DetailView中带有一个查询/子查询,该查询/子查询用于检查第二个模型的实例中是否存在supplier_code,该第二个模型的实例代表接收到活库存数据库中的采购订单。

旨在将其用作清单/报价单,将返回是否已收到预期要发送的每个供应商的订单。

[使其返回匹配项似乎工作正常,并且如果存在不能识别的值(我有意创建了一个与列表不匹配的无效订单),它将返回存在没有匹配项。

但是我还需要告诉我,根本没有数据,但是我似乎无法实现这一目标。

例如,下面显示了模板输出; G001是我设置的“伪造”代码,而G002是供应商列表中存在的有效代码。但是,如果没有针对G002的订单,它将不返回任何内容。

    Order not received: G001
    Order received: G002

我已经尝试过编写第二个查询上下文,它是上下文的镜像['db_orders'],但是使用〜Exists(),然后将if语句嵌套在模板中,但这只会告诉我订单都存在并且不存在,反之亦然。

 context['not_db_orders'] = Order.objects.filter(
            retailer_code=self.object.retailer_code).annotate(in_db=~Exists(squery))

我也尝试使用'is not'或'is None'或'is False'在模板中执行此操作,但似乎无法获得我需要的输出

最终预期输出是一个表,该表根据订单实例中是否存在订单,列出了进入特定零售商的所有期望供应商,并在其旁边以某种方式“是”或“否”列出。 (模板HTML当前不反映这一点,但这不是问题)

模板:

{% extends 'tick_sheet/base.html' %}

{% block content %}

<h1>{{ object.retailer_name }}</h1>
<ul>
    {% for supplier in object.get_supplier_values %}
    <li>{{ supplier }}</li>
    {% endfor %}
</ul>

<ul>
{% for item in db_orders %}
        {% if item.in_db %}
            <li>Order received: {{ item.supplier_code }} - {{ item.supplier_name }}</li>
        {% elif not item.in_db or item.in_db is None %}
            <li>Order not received: {{ item.supplier_code }} - {{item.supplier_name}}</li>
        {% endif %}
{% endfor %}
</ul>
{% endblock content %}

DetailView:

class RetailerDetailView(DetailView):

    model = Retailer
    slug_field = 'retailer_code'
    slug_url_kwarg = 'retailer_code'

    def get_context_data(self, **kwargs):

        context = super().get_context_data(**kwargs)
        context['now'] = timezone.now()
        context['title'] = 'Order Checklist'

        squery = self.object.suppliers.filter(
            supplier_code=OuterRef('supplier_code'))

        context['db_orders'] = Order.objects.filter(
            retailer_code=self.object.retailer_code).annotate(in_db=Exists(squery))

        return context

Models.py

from django.db import models
from django.utils import timezone


class Order(models.Model):

    ''' To simulate connection to main stock db '''

    retailer_code = models.CharField(max_length=4)
    retailer_name = models.CharField(max_length=100)
    supplier_code = models.CharField(max_length=4)
    supplier_name = models.CharField(max_length=100)
    order_reference = models.CharField(max_length=20)
    despatch_date = models.DateTimeField(default=timezone.now)

    def __str__(self):

        return f"< {self.order_reference}', {self.supplier_name}, {self.retailer_name} >"


# -------------------------------------------------------------------------------------

class Retailer(models.Model):

    retailer_code = models.CharField(max_length=4)
    retailer_name = models.CharField(max_length=100)
    suppliers = models.ManyToManyField('Supplier')
    slug = models.SlugField(unique=True, null=True)

    def get_supplier_values(self):

        return [(suppliers.supplier_code + ' - ' + suppliers.supplier_name) for suppliers in self.suppliers.all()]

    def save(self, *args, **kwargs):

        self.slug = self.slug or slugify(self.retailer_code)
        super().save(*args, **kwargs)

    def __str__(self):

        return f"< {self.retailer_code} - {self.retailer_name} >"


class Supplier(models.Model):

    supplier_code = models.CharField(max_length=4)
    supplier_name = models.CharField(max_length=100)

    def __str__(self):

        return f"< {self.supplier_code}, {self.supplier_name} >"
django django-queryset exists not-exists django-subquery
1个回答
0
投票
如果False和None之间的区别,则不能使用Exists。那是严格的布尔运算。您将需要使用Subquery返回一个NullableBooleanField,其结果是通过WhenCase计算得出的
© www.soinside.com 2019 - 2024. All rights reserved.