Django-在模板中显示计算字段的列表

时间:2018-09-06 19:24:58

标签: python django django-templates django-views

我正在将查询集列表和总价格列表传递给模板。我使用我的申请表的反向关系来显示该申请存在的每一行。我正在传递请购单的总价(将所有行的价格加在一起)。我正在尝试以表格格式显示每条记录,并在提交按钮旁边的底部显示累积价格。我最初的想法显然是遍历该列表,但这给我带来了一个问题,因为我将嵌套三个for循环,因此不会显示预期的结果。

pending_action.html

    <h1>Pending Action</h1> 
            {% for req_header in req_header_list %}         
                <div class="accordion" id="accordionExample">
                    <div class="card">
                        <div class="card-header" id="headingOne">
                        <h5 class="mb-0">
                            <button class="btn btn-link" type="button" data-toggle="collapse" data-target="#req{{ req_header.id }}" aria-expanded="false" aria-controls="collapseOne">                       
                                {{ req_header }} 
                            </button>
                        </h5>
                        </div>

                        <div id="req{{ req_header.id }}" class="collapse" aria-labelledby="headingOne" data-parent="#accordionExample">
                        <div class="card-body">
                            <table class="table">
                                <tr>
                                    <th>Line</th>
                                    <th>Description</th>
                                    <th>Quantity</th>
                                    <th>Total Price</th>
                                    <th>Status</th>
                                </tr>    
                                {% for line in req_header.par_req_line.all %}
                                    <tr>
                                        <td>{{line}}</td>
                                        <td>{{line.description}}</td>
                                        <td>{{line.quantity}}</td>
                                        <td>{{line.total_price}}<td>
                                        <td>{{line.status}}</td>                     
                                    </tr>
                                {% endfor %}
                                <tr>
                                    <td>
                                        <form action="#" method="POST">       
                                                <input type="submit" value="Submit">
                                        </form>
                                    </td>
                                    <td></td>
                                    <td></td>
                                    <td>
                                         <!--WANT TO DISPLAY THE TOTAL PRICE PER REQUISITION HERE                                         
                                          {{price_list.0}}
                                    </td>

                                </tr>
                            </table>   
                        </div>
                        </div>
                    </div>                
                </div>

        {% endfor %}
    </div>

views.py

def pending_action(request):
    user = CustomUser.objects.get(username=request.user)
    user_req_headers = Requisition.objects.filter(username=user)
    complete_status = RequisitionStatus.objects.get(status='Completed')
    req_header_list = []
    total_price = 0
    price_list = []

    for req_header in user_req_headers:
        req_lines = RequisitionLine.objects.filter(Q(parent_req = req_header) & ~Q(status=complete_status))
        for line in req_lines:
            if line.parent_req not in req_header_list:
                req_header_list.append(line.parent_req)

            total_price = total_price + line.total_price
        price_list.append(total_price)
        total_price = 0

    return render(request, 'req/pending_action.html', {'req_header_list':req_header_list, 'price_list':price_list})

models.py

class Requisition(models.Model):
    username = models.ForeignKey(
        'users.CustomUser', on_delete=models.CASCADE, related_name='req_user')
    signature = models.CharField(max_length=10, blank=True, null=True)



class RequisitionLine(models.Model):

    parent_req = models.ForeignKey('Requisition', on_delete=models.CASCADE, related_name='par_req_line' )
    sequence = models.PositiveIntegerField()
    item_code = models.ForeignKey(
        'items.ItemMaster', on_delete=models.CASCADE, related_name='req_item', blank=True, null=True)
    description = models.CharField(max_length=50, blank=True)
    extra_information = models.TextField(blank=True)
    quantity = models.PositiveIntegerField(blank=True, default=0,null=True)
    price = models.DecimalField(max_digits=19, decimal_places=2, blank=True, default=0.00,null=True)
    total_price = models.DecimalField(max_digits=19, decimal_places=2, blank=True, default=0.00,null=True)
    purchase_order = models.CharField(max_length=9, blank=True,null=True)
    po_line = models.PositiveSmallIntegerField(blank=True,null=True)
    req_delivery_date = models.DateField(blank=True,null=True)
    act_delivar_date = models.DateField(blank=True, null=True)
    status = models.ForeignKey('RequisitionStatus', related_name='req_status', on_delete=models.CASCADE, blank=True, null=True)
    assistance = models.ForeignKey('users.UserRoles', related_name='req_assist', blank=True, null=True, on_delete=models.CASCADE, limit_choices_to= ~Q(role='Requestor'))
    catagory = models.ForeignKey('items.ItemCatagory', on_delete=models.CASCADE, related_name='line_cat',  blank=True, null=True)
    notes = models.TextField(blank=True)

    class Meta:
        unique_together = ('parent_req','sequence')

StackTrace

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/req/pending/

Django Version: 2.1
Python Version: 3.7.0
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'req',
 'users.apps.UsersConfig',
 'items']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\###\Documents\Python\venv\env\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\###\Documents\Python\venv\env\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\###\Documents\Python\venv\env\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\###\Documents\Python\venv\env\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
  21.                 return view_func(request, *args, **kwargs)

File "C:\Users\###\Documents\Python\django\lambda\req\views.py" in pending_action
  273.     user_reqs = Requisition.objects.filter(par_req_line__in=user_req_lines_incomplete).annotate(aggregated_price=sum('par_req_line__total_price'))

Exception Type: TypeError at /req/pending/
Exception Value: unsupported operand type(s) for +: 'int' and 'str'

1 个答案:

答案 0 :(得分:0)

您应该重构您的views.py以返回与您的条件匹配的单个Requisition对象的查询集,并用您要提供的汇总价格数据进行注释。然后,您需要重构您的html模板以遍历单个查询集。最大限度地使用Django ORM将使您的代码更短,并且运行速度更快。

在views.py

from django.db.models import Sum

def pending_action(request):
    user_req_lines_incomplete = RequisitionLine.objects.filter(parent_req__username=request.user).exclude(status__status='Completed'))
    user_reqs = Requisition.objects.filter(par_req_line__in=user_requisition_lines_incomplete).annotate(aggregated_price=Sum('par_req_line__total_price'))
    return render(request, 'req/pending_action.html', {'user_reqs':user_reqs})        

请注意,在对模型进行注释之前,在相关模型上进行过滤时,Django ORM的内部存在一些诡计。当您filter(par_req_line__in时,这也意味着将仅在符合过滤条件的par_req_line上计算该行后面出现的注释。因此,您的汇总将仅汇总user_req_lines_incomplete中的行。我有95%的把握是您想要的,但是如果您正在寻找其他条件,请随时澄清。为了让您的所有代码都带有许多for循环和名称,我有些挣扎。 (没有判断力。)

在ending_action.html中

<!-- I took out most of your HTML to simplify -->
<h1>Pending Action</h1> 

{% for req in user_reqs %}
    <h5>{{req}}</h5> <!-- You can show whatever you want for your req here -->
    {% for line in req.par_req_line.all %x} 
        <tr>
            <td>{{line}}</td>
            <td>{{line.description}}</td>
            <td>{{line.quantity}}</td>
            <td>{{line.total_price}}<td>
            <td>{{line.status}}</td>                     
        </tr>
    {% endfor %}
    Total price: {{req.aggregated_price}} <!-- Use the annotated data here -->
{% endfor %}

希望有帮助。