比较 Django DetailView 中两个模型的值

Comparing values from two models within Django DetailView

所以我正在尝试创建一个自动化的 "tick sheet" 作为在我的工作场所自动化流程的提案的概念证明。

在工作中,我们收到来自不同供应商的订单,每天需要根据纸上的预期清单手动勾选收到的订单 sheet。

我使用通用的 DetailView 是为了让每个零售商都有一个单独的页面,并有一个模型代表与供应商具有多对多关系的零售商。我还有一个订单模型 'simulate' 到实际 WMS 数据库的连接(目的是在获得实际数据库读取访问权限后修改它 if/when 这已投入生产。)

我需要预期订单(在 Suppliers ManyToMany 关系中)与 'real' 订单模型数据中的订单相匹配,并且 return 关于它是否存在于数据库中的答案(在我可以将其显示在模板上的一种方式)。

经过几次疯狂的尝试自己解决后,我对如何在 DetailView 的上下文中实现这一点感到有点困惑,所以我担心我误解了什么...

编辑:我应该提到我只需要 'supplier code' 来匹配,但也打算让程序使用 'order reference' 检查重复订单,一旦我想通了,因为没有这个功能整个事情变得有点多余...

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

我的views.py:

from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from .models import Retailer, Order


class RetailerListView(ListView):

    model = Retailer
    context_object_name = 'retailer_list'

    def get_context_data(self, **kwargs):

        context = super().get_context_data(**kwargs)
        context['title'] = 'Select Retailer'

        return context

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['title'] = 'Order Checklist'
        context['db_orders'] = Order.objects.filter(retailer_code=self.object.retailer_code)       

        return context

    def do_order_checklist(self):

        pass # WIP

如有任何帮助,我们将不胜感激...

我明白了,你要找的答案可能就是这个。 当您获得每个零售商的 supplier_codes 列表时。例如你已经有了列表。
retailers_supplier_codes = [1, 2, 3, ...]
matching_orders = Order.objects.filter(supplier_code__in = retailers_supplier_codes)

也许您可以使用 Exists 来注释订单是否在数据库中。例如:

from django.db.models import Exists, OuterRef
...

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    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

然后在模板中显示:

{% for item in db_orders %}
   {% if item.in_db %}
       // do something
   {% else %}
       // else
   {% endif %}
{% endfor %}