0

So I'm attempting to create an automated "tick sheet" as a proof of concept for a proposal to automate a process at my workplace.

At work we receive orders from various Suppliers and need to manually tick off the orders that are received against a list of what is expected on a paper sheet each day.

I'm using the generic DetailView in order to have a separate page for each Retailer and have a model representing the Retailer with a ManyToMany relationship with the Suppliers. I also have an Order model to 'simulate' a connection to the actual WMS database (with the intention of modifying it after getting actual db read access if/when this is put into production.)

I need the expected orders (in the Suppliers ManyToMany relationship) to match against those in the 'real' Order model data, and return an answer as to whether it exists in the db (in a way that I can display it on a template).

After a few frantic attempts to solve it myself I'm a little stumped as to how to achieve this within the context of the DetailView, so I fear I am misunderstanding something...

edit: I should have mentioned I only need the 'supplier code' to match but also intend to have the program check for duplicate orders using the 'order reference' once I've figured this out, as without this functionality the whole thing becomes a bit redundant...

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

My 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

Any help would be appreciated...

cakethief
  • 3
  • 3

2 Answers2

0

I see, probably the answer you are looking for is this. as you get the list of supplier_codes in each retailer. instance you already have the list.
retailers_supplier_codes = [1, 2, 3, ...]
matching_orders = Order.objects.filter(supplier_code__in = retailers_supplier_codes)

0

Probably you can use Exists to to annotate if the order is in DB. For example:

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

Then show in template:

{% for item in db_orders %}
   {% if item.in_db %}
       // do something
   {% else %}
       // else
   {% endif %}
{% endfor %}
ruddra
  • 50,746
  • 7
  • 78
  • 101
  • Turns out this is not quite doing what I need but did take me further - I have posted another question at https://stackoverflow.com/questions/60197998/django-exists-exists-return-if-there-is-no-matching-data – cakethief Feb 12 '20 at 22:47