I'm struggling to work out the correct solution for what I'm trying to do here and would really appreciate some help.
At the moment, I have a working system which takes a "Special" from the db and displays it in the browser. The user is able to edit that "Special" in the browser and submit it to the db. That change is then shown to the user.
The problem is that the "Special" will not update if there is no pre-existing "Special" in the db. In my views.py I have:
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')
I know that the reason the updating of the "Special" does not work is because the get_object_or_404
is correctly returning a 404 error as there is no pre-existing "Special" in the db.
I've been trying for a while to work out the best way to get around this problem without breaking the function in cases where there is an existing "Special" in the db.
So far, I've tried replacing the get_object_or_404
with try
and except
, but I then run into problems with the save function, such as 'unicode' has no attribute 'save()'
.
Try to replace:
myActiveSpecial = get_object_or_404(SpecialOffer.objects.filter(product=myProduct).filter(
active=True))
with:
myActiveSpecial, just_created = SpecialOffer.objects.get_or_create(product=myProduct, active=True)
Or you could try something like this:
try:
myActiveSpecial = SpecialOffer.objects.get(product=myProduct, active=True)
except SpecialOffer.DoesNotExist:
myActiveSpecial = SpecialOffer.objects.create(product=myProduct, active=True, ...something.more...)
if you need to do something more with the just-created object.
EDIT:
Just a thought... It's a bit puzzling to send a Model to HttpResponse
. Maybe you will want to manually create a string that you wish to return in HttpResponse
. Of course, current code also works. It implicitly calls the __unicode__
method of your model.
Another thing - what is the reason for re-fetching the myActiveSpecial
just before the return
? I don't see any effect this may have.
The way get_object_or_404
works is by passing in the model, and then some lookups. It is the same as if you said SpecialOffer.objects.get()
but instead of raising an exception, it raises 404
.
You used it correctly the first time, but not the second instance.
Try this instead:
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
You can also use the reverse lookup trick (depending on how your models are set up).
myActiveSpecial = myProduct.specialoffer_set.filter(active=True)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With