0

小売業者と在庫のある商品について、2つのモデルを定義しました。製品は別のアプリで定義されています。在庫アイテムを取得および追加するための2つのモデルメソッドを定義しました。コードの関連部分は次のとおりです。

class Retailer(models.Model):
    name = models.CharField(max_length=100)
    @property
    def stock_items(self):
        return StockItem.objects.filter(retailer__id=F('id'))

    def add_stock_item(self, product_id):
        try:
            print "Checking if it's already in stock"
            self.stock_items.get(product__id=product_id)
            print "It's already in stock"
        except ObjectDoesNotExist:
            try:
                print "Adding item to stock"
                product = Product.objects.get(pk=product_id)
                StockItem.objects.create(retailer=self, product=product)
                print "Added to stock"
            except Product.DoesNotExist:
                print "Such product doesn't exist"
    def __unicode__(self):
        return self.name


StockItem(models.Model):
    retailer = models.ForeignKey(Retailer)
    product = models.ForeignKey(Product)
    def __unicode__(self):
        return "%s - %s %s" % (self.retailer, self.product.brand, self.product)

これらのモデルメソッドを使用したい場合、何か奇妙なことが起こります。最初のアイテムを追加すると、正しく機能しなくなります(これらの例では、製品1は16 GBのiPhoneで、製品2は32 GBのiPhoneです)。

まず、在庫にいくつかの製品を追加しましょう。

>>> r = Retailer.objects.get(pk=1)
>>> r.stock_items
[]
>>> r.add_stock_item(1)
Checking if it's already in stock
Adding item to stock
Added to stock
>>> r.add_stock_item(2)
Checking if it's already in stock
Adding item to stock
Added to stock

ここまでは順調ですね。次に、製品をもう一度追加して、エラーがどのように処理されるかを確認してみましょう。

>>> r.add_stock_item(1)
Checking if it's already in stock
It's already in stock
>>> r.add_stock_item(2)
Checking if it's already in stock
Adding item to stock
Added to stock

何?なぜ再び製品2を追加したのですか。製品1と同様のメッセージが表示されるはずでした。在庫を見てみましょう。

>>> r.stock_items
[<StockItem: hh - Apple iPhone 4S 16GB>]

製品2はどうなりましたか?データベースへの追加に失敗しましたか?

[<StockItem: hh - Apple iPhone 4S 16GB>, <StockItem: hh - Apple iPhone 4S 32GB>, <StockItem: hh - Apple iPhone 4S 32GB>]

どうやらそうではありません。データベースに追加されましたが、どういうわけか私たちのプログラムはそれを正しくチェックできません。r.stock_itemsを呼び出すと、在庫に追加された最初の製品のみが表示されます。シェルを再起動しても状況は変わらないので、関数が評価されたときのせいではないと思います。

なぜこれが発生し、どうすれば修正できますか?

4

2 に答える 2

1

メソッドを削除@propertyして、次のように変更してみてください。

def stock_items(self):
    return self.stockitem_set.all()
于 2013-01-26T16:50:54.977 に答える
1

メソッドが失敗した理由は、その式が思ったとおりに機能しないためです。構文は、同じ行内のF()値を比較するためのものです。そのため、式は、関連する小売業者IDが現在の行のIDと同じであることを確認していました。これは最初のアイテムには当てはまりましたが、行IDは新しいアイテムとともに増加しましたが、小売業者IDは同じままであるため、後続のアイテムには当てはまりません。

于 2013-01-26T17:15:12.387 に答える