nja*_*ine 3 python django django-models foreign-key-relationship cart
所以我在尝试更新外键模型的字段时遇到了麻烦。我正在尝试通过另一个模型的方法更新该字段,但它似乎无法正常工作,因为我在运行我的 tests.py 时得到了不正确的值。我正在尝试更新“total_purchased”的值。这是我基本上想要完成的一个例子:
我正在使用 Django 1.6.4
如果问题太长而无法总结,是否允许使用以下 2 行?我在 django 类模型方法中执行此操作:
Ex: Model.ForeignKeyModel.field = some_value
Model.ForeignKeyModel.save()
Run Code Online (Sandbox Code Playgroud)
有以下3种型号:
class Meal (models.Model):
name = models.CharField(max_length=255)
total_purchased = models.IntegerField(default=0, validators=[MaxValueValidator(capacity)])
capacity = models.IntegerField(default=500)
class Item (models.Model):
cart = models.ForeignKey(Cart)
meal = models.ForeignKey(Meal)
quantity = models.IntegerField(validators=[MinValueValidator(0)], default=0)
class Cart (models.Model):
delivery = models.ForeignKey(DeliveryInfo)
subscription = models.BooleanField(default=False)
customer = models.ForeignKey(User)
def add(self, meal, quantity):
""" Dual Add/Remove from cart method, (quantity replaces current quantity) """
item = Item.objects.get_or_create(cart=self, meal=meal)[0]
remaining_capacity = item.meal.capacity - item.meal.total_purchased
# Meal exists on our cart, so proceed with adding or removing
if quantity <= remaining_capacity:
if quantity == 0:
# Add back whatever quantity the user didn't buy
item.meal.total_purchased = 0
item.meal.save()
# Remove entire item from cart (quantity = 0)
item.delete()
elif quantity == item.quantity:
# Do nothing if cart quantity equals current quantity
pass
else:
if quantity < item.quantity:
# Decrement total purchased
item.meal.total_purchased -= (item.quantity - quantity)
item.meal.save()
else:
# Increment total_purchased by the quantity we're adding to the cart
item.meal.total_purchased += (quantity - item.quantity)
item.meal.save()
# Update the Cart
item.quantity = quantity
item.save()
remaining_capacity = item.meal.capacity - item.meal.total_purchased
else:
exceeded = abs(remaining_capacity - quantity)
raise ValidationError("Your cart exceeds the total remaining quantity by {0}!".format(exceeded))
Run Code Online (Sandbox Code Playgroud)
更新后它第一次工作,但似乎忽略了下一个添加到购物车方法调用,我最终在我的测试中得到以下内容: self.assertEqual(item.total_purchased, 2) AssertionError: 1 != 2
我不确定是不是因为在 tests.py 中发生了购物车更新,或者我是否以某种方式错误地保存了数据。任何帮助将不胜感激,谢谢。
按照这里的要求是我的tests.py,我在其中运行测试:
customer = User.objects.filter(pk=1)[0]
delivery_info = DeliveryInfo.objects.filter(owner=customer)[0]
cart_order = CartOrder.objects.create(owner=customer, delivery=delivery_info, subscription=False)
# Query the meal_items
curry_item = Meal.objects.get(pk=1)
burger_item = Meal.objects.get(pk=2)
# Add some meal items to our cart, the cart_order add method creates Items
cart_order.add(curry_item, 2)
cart_order.add(burger_item, 1)
self.assertEqual(burger_item.total_purchased, 1)
# Removing one item from the cart
cart_order.add(curry_item, 1)
# Doing nothing to the cart
cart_order.add(curry_item, 1)
Run Code Online (Sandbox Code Playgroud)
** 这是它无法正确更新值的地方:**
# Adding an item to the cart
cart_order.add(burger_item, 2)
self.assertEqual(burger_item.total_purchased, 2)
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为您使用的模型实例没有更新。
第一次调用get_or_create它时会创建Item并使用Mealfrommeal=meal而第二次它获取Item并且不使用 的相同实例Meal。
由于您已经有一个meal作为参数的实例,您可以替换item.meal为meal,您应该会看到您想要的结果。或者,您可以burger_item在添加后重新加载或任何餐点。
你真的应该考虑使用 F() 表达式来做你的增量,因为它们只在数据库端执行并且可以帮助防止竞争条件。请注意,使用 F() 表达式需要您重新加载Meal以查看它的新值。
在旁注中,注意
# Update the Cart
item.quantity = quantity
item.save()
Run Code Online (Sandbox Code Playgroud)
在 wherequantity == 0和您删除的情况之后被调用,Item因为这会重新创建Item.
| 归档时间: |
|
| 查看次数: |
3704 次 |
| 最近记录: |