如果没有匹配的数据,Django Exists()/〜Exists()返回吗? [英] Django Exists() / ~Exists() return if there is no matching data?

查看:176
本文介绍了如果没有匹配的数据,Django Exists()/〜Exists()返回吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As per schillingt's answer below I have switched to using 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()))))

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

However I'm now struggling with an errror:

FieldError at /retailers/A001/

Cannot resolve expression type, unknown output_field


原始问题:


Original question:

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

I have the DetailView below with a query/subquery that checks whether supplier_code exists within instances of a second model set up to represent purchase orders received into a live stock database.

目的是用作检查清单/报价单,以返回是否已收到预期要发送的每个供应商的订单.

The intention is for this to function as a checklist/ticksheet that will return whether or not the order has been received for each supplier expected to send one.

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

Getting it to return that there is a match seems to be working fine, and if there is a value it does not recognize (I have purposefully created an invalid order that won't match against the list) it will return that there is no match.

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

However I need this to also tell me that there is simply no data, yet I don't seem to be able to achieve this.

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

For example the below shows the template output; G001 is the 'fake' code I have set up and G002 is a valid one that exists in the suppliers list. However if there is not an order present for G002 it will not return anything.

    Order not received: G001
    Order received: G002

我尝试为上下文写第二个查询,该上下文是context ['db_orders']的镜像,但是使用〜Exists(),然后将if语句嵌套在模板中,但这只会告诉我命令既存在和不存在,反之亦然.

I have tried writing a second query for the context that is a mirror of context['db_orders'] but using the ~Exists() and then nesting the if statements in the template but this will just tell me that the orders both exist and don't exist or vice versa.

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

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

I've also tried to do this in the template using 'is not' or 'is None' or 'is False' but cannot seem to get the output I need

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

Ultimately the intended output is a table that lists all the suppliers expected into a particular retailer with some manner of 'Yes' or 'No' next to them based on whether the order exists among the Order instances. (The template HTML doesn't currently reflect this but that is not the issue)

模板:

{% 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:

The 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

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} >"

推荐答案

如果"False"和"None"之间有区别,则不能使用Exists.那是严格的布尔运算.您将需要使用返回NullableBooleanFieldSubquery,其结果是通过何时案例

If there's a difference in the case between False and None you can't use Exists. That is a strictly boolean operation. You will need to use a Subquery that returns a NullableBooleanField whose result is calculated with When and Case

这篇关于如果没有匹配的数据,Django Exists()/〜Exists()返回吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆