python - Django Python - Itertools 没有使产品与拍卖销售额保持一致

标签 python python-3.x django django-views django-templates

我根据 EntityPeriod 这两个条件生成了一个产品列表。 检索到的列表包含所有产品和每个产品的所有拍卖销售额的总和。下面的示例显示了 XZY 公司在 11 月份的 4 种产品列表。在列出的所有产品中,只有一种产品 (sku 30) 的两次拍卖销售额分别为 180 美元和 220 美元。问题是其余产品没有销售,因此空值未与产品正确对齐。我仍然需要列出这些产品并显示 0 美元的销售额。

模型.py

class Entity(models.Model):
    entity = models.CharField(max_length=40)

class Period(models.Model):
    period = models.CharField(max_length=7)

class Product(models.Model):
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE, default=None, blank=True, null=True)
    period = models.ForeignKey(Period, on_delete=models.CASCADE, default=None, blank=True, null=True)
    sku = models.CharField(max_length=40)
    projectedsales = models.DecimalField(max_digits=11, decimal_places=2)

class Post(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, default=None, blank=True, null=True)
    auctionsale = models.DecimalField(max_digits=11, decimal_places=2)

Views.py

def get(self, request):
        form = ProductsViewForm()
        return render(request, "products_list.html", {'form': form})

    def post(self, request):
        products = None
        posts = None
        entities = None
        periods = None
        mylist = None
        form = ProductsViewForm(request.POST)
        if request.method == 'POST':
            if form.is_valid():
                entityquery = form.cleaned_data['entity']
                periodquery = form.cleaned_data['period']
                entities = Entity.objects.get(entity=entityquery)
                periods = Period.objects.get(period=periodquery)
                products = Product.objects.filter(entity=entityquery, period=periodquery).values('id', 'period', 'entity', 'sku', 'projectedsales')
                posts = Post.objects.filter(product__sku__in=products.values('sku'), product__entity=entityquery, product__period=periodquery).annotate(total=Sum('auctionsale'))
                mylist = list(itertools.zip_longest(products, posts, fillvalue='0'))
            args = {'form': form, 'periods': periods, 'entities': entities, 'mylist': mylist}
        return render(request, "products_list.html.html", args)

products_list.html

<div class="row">
    <div class="col-12">
        <form method="POST">
            {% csrf_token %}
            <div class="form-row">
                <div class="form-group col-md-4">
                    {{ form.entity|add_class:"custom-select" }}
                </div>
                <div class="form-group col-md-4">
                    <input type="text" name="period" id="id_period" class="form-control" placeholder="mm/yyyyy" maxlength="7" minlength="7" required> 
                </div>
                <div class="form-group col-md-4">
                    <input type="submit" value="Run Balance Sheet" class="btn btn-primary btn-block">
                </div>
            </div>
        </form>
    </div>
</div>

<div class="row">
    <div class="col-12">
        <br>
        {% if entities %}
            <center><h4>Auction Sales</h4></center>
            <center><h5>Entity : {{entities.entity}}</h5></center>  
        {% endif %}

        {% if periods %}
            <center><h5>Period : {{periods.period}}</h5> </center>
        {% endif %}
        <br>
        {% if mylist %}
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th scope="col">Product</th>
                        <th scope="col">Projected Sales</th>
                        <th scope="col">Total Auction Sales</th>
                    </tr>
                </thead>
                <tbody>
                    {% for product, post in mylist %}
                        <tr>
                            <td>{{product.sku}}</td>
                            <td>{{product.projectedsales}}</td>
                            <td>{{post.total}}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        {% endif %}
    </div>
</div>

查询

Entity: Company XZY 
Period: 11/2020

预期结果

Product -- Projected Auction Sales -- Total Auction Sales
sku 10  -- $100                    -- $0
sku 20  -- $200                    -- $0
sku 30  -- $600                    -- $400
sku 40  -- $500                    -- $0

我得到的结果

Product -- Projected Auction Sales -- Total Auction Sales
sku 10  -- $100                    -- $400
sku 20  -- $200                
sku 30  -- $600
sku 40  -- $500

最佳答案

我宁愿使用 Coalesce(...)--(Django Doc) Django 的数据库功能以及 Sum()--(Django Doc)功能

from django.db.models import Sum
<b>from django.db.models.functions import Coalesce</b>

product_qs = Product.objects.annotate(
    action_sum=<b>Coalesce(Sum("post__auctionsale"), 0)</b>
                                                ^^^^^ this is the default value
)
for product in product_qs:
    print(product.sku, " ---- ", product.action_sum)

# Result
30  ----  400
10  ----  0
20  ----  0
40  ----  0

关于python - Django Python - Itertools 没有使产品与拍卖销售额保持一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65376707/

相关文章:

python - 如何正确使用 tf.scatter_update 进行 N 维更新?

python-3.x - 在哪里可以找到 PyQt5 方法签名?

django - 在Django中为 "workspaces"设置权限的正确方法?

python - Formset 对象 - 对象没有属性 'fields'

python - 如何将字典转换为嵌套字典?

python - 使用 str(count) 追加到列表会出错

python - Django 网址.py : best way to not have a page number in the url for the first page in a list view?

python-3.x - Networkx-索引错误 : list index out of range while using (greedy_modularity_communities

python - 从具有特定列和条件的数据框中选择行(不使用列名)

python - 无法将字典更新序列元素 #0 转换为序列