2017-01-26 4 views
0

これは、ユーザ注文メソッドとしてdjangoモデルフィールドを設定するには?

class Order(models.Model): 
    """Order Models""" 

    first_name = models.CharField(
     max_length=256, 
     blank=False, 
     verbose_name=_('Name')) 

    total_order_cost = models.DecimalField(
     max_digits=10, 
     decimal_places=2, 
     default=21, 
     verbose_name=_('Total Order Cost')) 

のための私のモデルであり、私の注文した商品のためのモデル

class OrderItem(models.Model): 
    """ Ordered Item Model """ 

    order = models.ForeignKey(Order, 
     verbose_name=_('Order')) 

    price = models.DecimalField(
     max_digits=10, 
     decimal_places=2, 
     verbose_name=_('Price')) 

    quantity = models.PositiveIntegerField(
     verbose_name=_('Quantity')) 

    total_price = models.DecimalField(
     max_digits=10, 
     decimal_places=2, 
     verbose_name=_('Total Price')) 

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

    def save(self, *args, **kwargs): 
     self.total_price = self.get_cost() 
     super(OrderItem, self).save(*args, **kwargs) 

フィールドTOTAL_PRICEがget_costから値を取得します。フィールドtotal_order_costを同じ方法で動作させるにはどうすればよいですか?私はそれが私が順序オブジェクトを保存するときので、私は、total_order_costのための保存方法を上書きすることはできません

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

から値を取得したい - まだ存在しない項目を命じました。 マイビュー:

def make_order(request): 
    cart = Cart(request) 

    if request.method == 'POST': 
     form = OrderCreateForm(request.POST) 

     if form.is_valid(): 
      order = form.save() # here I save order object 

      for item in cart: # and here I save ordered items 
       OrderItem.objects.create(
        order=order, 
        product=item.product, 
        price=item.product.price, 
        quantity=item.quantity) 

      cart.clear() 
      return HttpResponseRedirect('%s?status_message=%s' 
       % (reverse('get_cart'), _('Thank you for your order!'))) 

    else: 
     form = OrderCreateForm() 

    return render(request, 'products/make_order.html', { 
     'form': form}) 

UPDATE: は、私は

@property 
def total_order_cost(self): 
    return self.orderitem_set.aggregate(total=Sum(F('price') * F('quantity')))['total'] 

を使用する必要があります。しかし、私はそれを使用する方法を今しないことを理解しました。私はこのように試してみましたが、うまくいきませんでした。

+0

私はあなたが、コストと価格をconflatingしていて、それはおそらくいくつかの点で誰かを混乱に終わるだろうと思い... – thebjorn

+0

はなし「の方法として、モデルフィールドを設定」するいかなる些細な方法はありませんdjango ORMに重大なメタクラスハッキングを行っています。フィールドは 'django.db.models.fields.Field'のインスタンスでなければなりません。はるかに簡単な解決法は@Tomの提案するようにプロパティを使うことです。 –

答えて

3

派生データを格納する理由がないのはなぜですか? total_priceフィールドをOrderItemに、total_order_costOrderにドロップし、必要に応じてaggregationF expressionsを使用してクエリを実行するだけです。どのようにsomething like thisについて:

@property 
def total_order_cost(self): 
    return self.orderitem_set.aggregate(total=Sum(F('price') * F('quantity')))['total'] 
+0

'Sum(F( 'price'))'はすべてのdbバックエンドで動作しますか?私はDecimalFieldsがSQLiteにどのように格納されているのか分かりませんが、浮動小数点数と整数だけをサポートしていると思います。 –

+0

@HåkenLidそれは良い質問ですが、私は答えを知らない - 実際に浮動小数点型フィールドにお金の値を格納しないことについての私の典型的な賢明なアドバイスを含めるつもりでしたが、それは問題を混乱させるように感じました。 – Tom

関連する問題