如何在Django

时间:2019-05-16 09:50:43

标签: python django-models django-forms django-views

我正在尝试检索所选项目的总数
由用户在购物车中购买。 用户退房时,他将被重定向到“订单”页面,其中
用户填写所有信息并提交订单。但是总金额未反映在数据库中。

forms.py(在我的订单应用中)

  from django import forms
  from .models import Order


  class OrderCreateForm(forms.ModelForm):

    class Meta:
        model = Order
        fields = ['first_name', 'last_name', 'email', 'address', 
        'postal_code', 'city']

models.py(在我的订单应用中)

 from django.db import models
 from shop.models import Product


  class Order(models.Model):
      first_name = models.CharField(max_length=60)
      last_name = models.CharField(max_length=60)
      email = models.EmailField()
      address = models.CharField(max_length=150)
      postal_code = models.CharField(max_length=30)
      city = models.CharField(max_length=100)
      created = models.DateTimeField(auto_now_add=True)
      updated = models.DateTimeField(auto_now=True)
      paid = models.BooleanField(default=False)
      total_cost = models.DecimalField(max_digits=100,       
      decimal_places=3, default=0)


       class Meta:
           ordering = ('-created', )

       def __str__(self):
         return 'Order {}'.format(self.id)


       def total_cost(self):
          return sum([item.total_cost for item in self.items.all()])

       def get_total_cost(self):
          return sum(item.get_cost() for item in self.items.all())


   class OrderItem(models.Model):
       order = models.ForeignKey(Order, related_name='items',  
       on_delete=models.CASCADE)
       product = models.ForeignKey(Product, 
       related_name='order_items', on_delete=models.CASCADE)
       price = models.DecimalField(max_digits=10, decimal_places=2)
        quantity = models.PositiveIntegerField(default=1)
        total_price = models.DecimalField(max_digits=100, 
        decimal_places=3, default=0)

        def __str__(self):
            return '{}'.format(self.id)

        def get_cost(self):
             return self.price * self.quantity

views.py(在我的订单应用中)

   from django.shortcuts import render
   from .models import OrderItem
   from django.contrib.auth.decorators import login_required
   from .forms import OrderCreateForm
   from cart.cart import Cart


   @login_required
   def order_create(request):
     cart = Cart(request)
     if request.method == 'POST':
       form = OrderCreateForm(request.POST)
     if form.is_valid():
        order = form.save()
        for item in cart:
            OrderItem.objects.create(
                order=order,
                product=item['product'],
                price=item['price'],
                quantity=item['quantity'],
                total_price=item['total_price'],
            )
        cart.clear()
        return render(request, 'created.html', {'order': order})
      else:
        form = OrderCreateForm()
        return render(request, 'create.html', {'form': form})

我已经使用了脆性表单来呈现表单

create.html

  {% extends 'base.html' %}
  {% load crispy_forms_tags %}
  {% load static %}
  {% block title %}
  Your Shopping Cart| Checkout
  {% endblock %}

{% block content %}
 <div class="container">
    <div class="row" style="margin-top: 6%">
        <div class="col-md-8">
            <h4 class="page-header">Billing Details</h4>
            <form action="." method="post">
                {% csrf_token %}
                {{ form | crispy }}<br>
                <input type="submit" class="btn btn-primary"       
                value="Submit order">
            </form>
        </div>
        <div class="col-md-4">
            <div class="page-header">
                Your Order
                 <li class="list-group-item ">Total Cost: Rs {{ 
                  cart.get_total_price }}</li>
            </div>
            <ul class="list-group">
                {% for item in cart %}
                    <li class="list-group-item">
                    {{ item.quantity }} x {{ item.product.name }}
                    <span>Rs. {{ item.total_price }}</span>
                    </li>
                {% endfor %}


            </ul>

        </div>
    </div>
  </div>
 {% endblock %}

Cart.py(在我的购物车应用中)

   from decimal import Decimal
   from django.conf import settings
   from shop.models import Product


  class Cart(object):
    def __init__(self, request):
    self.session = request.session
    cart = self.session.get(settings.CART_SESSION_ID)
    if not cart:
        cart = self.session[settings.CART_SESSION_ID] = {}
    self.cart = cart

   def add(self, product, quantity=1, update_quantity=False):
    product_id = str(product.id)
    if product_id not in self.cart:
        self.cart[product_id] = {'quantity': 0, 'price':   
         str(product.price)}
    if update_quantity:
        self.cart[product_id]['quantity'] = quantity
    else:
        self.cart[product_id]['quantity'] += quantity
    self.save()

   def save(self):
     self.session[settings.CART_SESSION_ID] = self.cart
    self.session.modified = True

  def remove(self, product):
    product_id = str(product.id)
    if product_id in self.cart:
        del self.cart[product_id]
        self.save()

  def __iter__(self):
    product_ids = self.cart.keys()
    products = Product.objects.filter(id__in=product_ids)
    for product in products:
        self.cart[str(product.id)]['product'] = product

    for item in self.cart.values():
        item['price'] = Decimal(item['price'])
        item['total_price'] = item['price'] * item['quantity']
        yield item

 def __len__(self):
    return sum(item['quantity'] for item in self.cart.values())

 def get_total_price(self):
    return sum(Decimal(item['price']) * item['quantity'] for item in 
    self.cart.values())

 def clear(self):
    del self.session[settings.CART_SESSION_ID]
    self.session.modified = True

admin.py(在我的订单应用中)

 from django.contrib import admin
 from .models import Order, OrderItem


  class OrderItemInline(admin.TabularInline):
    model = OrderItem
    raw_id_fields = ['product']


    class OrderAdmin(admin.ModelAdmin):
       list_display = ['id', 'first_name', 'last_name', 'email',   
       'address', 'postal_code', 'city', 'total_cost', 'paid', 
       'created','updated']
        list_filter = ['paid', 'created', 'updated']
        inlines = [OrderItemInline]


 admin.site.register(Order, OrderAdmin)

输出:-

这些是模板和数据库的输出,在这里我们可以看到总价格为0.00

create.html

database - ADMIN page - Orders.

1 个答案:

答案 0 :(得分:0)

您仅在total_price中修改OrderItem

您没有使用total_price对象的Order做任何事情,因此将保持为0

我建议您做的是为订单计算出一个total_price字段。

所以,相反:

  class Order(models.Model):
      total_price = models.DecimalField(max_digits=100,       
      decimal_places=3, default=0)

类似的东西:

  class Order(models.Model):
      def total_price(self):
          return sum([item.total_price for item in self.items.all()])

请记住,尽管我认为没有必要,也许您需要稍微调整一下“管理员”视图才能显示该字段,