Django:get_object_or_404不是正确的解决方案,但它是什么?

时间:2012-08-12 13:11:13

标签: django

我正在努力找出正确的解决方案来解决我在这里要做的事情,并且真的很感激一些帮助。

目前,我有一个工作系统,它从数据库中获取“特殊”并在浏览器中显示它。用户可以在浏览器中编辑“特殊”并将其提交给数据库。然后,该更改将显示给用户。

问题是如果数据库中没有预先存在的“特殊”,则“特殊”将不会更新。在我的views.py中,我有:

def changeSpecialOffer(theRequest):
    myProductUuid = theRequest.POST['myProductUuid']
    myNewSpecialOffer = theRequest.POST['myNewSpecialOffer']
    myProduct = get_object_or_404(Product, uuid=myProductUuid)
    myActiveSpecial = get_object_or_404(SpecialOffer.objects.filter(product=myProduct).filter(
                                                            active=True))
    try:
        myActiveSpecial.special = myNewSpecialOffer
        myActiveSpecial.save()
    except:
        return HttpResponse(myActiveSpecial, mimetype='text/plain')
    myActiveSpecial = SpecialOffer.objects.filter(product=myProduct).filter(
                                                            active=True)
    return HttpResponse(myActiveSpecial, mimetype='text/plain')

我知道更新“特殊”不起作用的原因是get_object_or_404正确返回404错误,因为数据库中没有预先存在的“特殊”。

我已经尝试了一段时间来找出解决此问题的最佳方法,而不会在数据库中存在“特殊”的情况下破坏该功能。

到目前为止,我已尝试将get_object_or_404替换为tryexcept,但我遇到了保存功能的问题,例如'unicode' has no attribute 'save()'。< / p>

2 个答案:

答案 0 :(得分:3)

尝试替换:

myActiveSpecial = get_object_or_404(SpecialOffer.objects.filter(product=myProduct).filter(
                                                    active=True))

使用:

myActiveSpecial, just_created = SpecialOffer.objects.get_or_create(product=myProduct, active=True)

或者您可以尝试这样的事情:

try:
    myActiveSpecial = SpecialOffer.objects.get(product=myProduct, active=True)
except SpecialOffer.DoesNotExist:
    myActiveSpecial = SpecialOffer.objects.create(product=myProduct, active=True, ...something.more...)

如果你需要用刚刚创建的对象做更多的事情。

修改

只是一个想法...将模型发送到HttpResponse有点令人费解。也许你会想要手动创建一个你希望在HttpResponse中返回的字符串。当然,目前的代码也有效。它隐式调用模型的__unicode__方法。

另一件事 - 在myActiveSpecial之前重新获取return的原因是什么?我认为这可能没有任何影响。

答案 1 :(得分:1)

get_object_or_404的工作方式是传入模型,然后进行一些查找。这与您说SpecialOffer.objects.get()的情况相同,但它不会引发异常,而是会引发404

你第一次正确使用它,但不是第二次使用它。

请改为尝试:

myProduct = get_object_or_404(Product, uuid=myProductUuid) # this is correct
myActiveSpecial = SpecialOffer.objects.filter(product=myProduct).filter(active=True))

if myActiveSpecial.count():
  # There is one or more active specials!
else:
  # There are no active specials for this product

您还可以使用反向查找技巧(取决于您的模型的设置方式)。

myActiveSpecial = myProduct.specialoffer_set.filter(active=True)