2012-08-12 28 views
5

Estoy luchando por encontrar la solución correcta para lo que estoy tratando de hacer aquí y realmente agradecería algo de ayuda.Django: get_object_or_404 no es la solución correcta, pero ¿qué es?

Por el momento, tengo un sistema en funcionamiento que toma un "Especial" de la base de datos y lo muestra en el navegador. El usuario puede editar ese "Especial" en el navegador y enviarlo a la base de datos. Ese cambio luego se muestra al usuario.

El problema es que el "Especial" no se actualizará si no hay un "Especial" preexistente en la base de datos. En mi views.py tengo:

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') 

sé que la razón por la actualización de la "especial" no funciona es porque el get_object_or_404 está correctamente devolviendo un error 404 ya que no hay preexistente "especial" en el db.

He estado intentando por un tiempo para encontrar la mejor manera de evitar este problema sin romper la función en los casos en que hay un "especial" existente en el db.

Hasta ahora, he tratado de sustituir el get_object_or_404 con try y except, pero entonces a tener problemas con la función de guardar, como 'unicode' has no attribute 'save()'.

Respuesta

3

tratar de sustituir:

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

con:

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

O usted podría intentar algo como esto:

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

si necesita hacer algo más con los justos: objeto creado

EDIT:

Sólo un pensamiento ... Es un poco desconcertante para enviar un modelo de HttpResponse. Quizás desee crear manualmente una cadena que desee devolver en HttpResponse. Por supuesto, el código actual también funciona. Llama implícitamente al método __unicode__ de su modelo.

Otra cosa: ¿cuál es el motivo para volver a buscar el myActiveSpecial justo antes del return? No veo ningún efecto que esto pueda tener.

+0

OK, así que ahora tengo: 'myActiveSpecial = SpecialOffer.objects.filtro (producto = myProduct) .Filter ( activa = True) retorno HttpResponse (myActiveSpecial, tipo MIME = 'text/plain') ' pero parece ir en círculos – Erve1879

+0

Podría ser más específico, lo que no vaya" ronda en círculos "realmente significa? Además, me parece que no necesita volver a buscar 'myActiveSpecial' en absoluto. – frnhr

+0

Lo siento, ¡no muy descriptivo! Básicamente, la función JS para cambiar el especial devuelve el nuevo valor correctamente, pero el nuevo valor no se guarda en el db. Después de volver a cargar la página, se muestra el antiguo especial. Si luego intentas actualizar el especial de nuevo, parece agregar el nuevo especial al anterior ... Pero aún no se guarda. – Erve1879

0

La forma en que get_object_or_404 funciona es pasando en el modelo, y luego algunas búsquedas. Es lo mismo que si dijera SpecialOffer.objects.get() pero en lugar de generar una excepción, aumenta 404.

Lo usó correctamente la primera vez, pero no en la segunda instancia.

Tal vez puedas probar:

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 

También puede utilizar el truco de búsqueda inversa (dependiendo de cómo sus modelos están configurados).

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

. Creo que 'myActiveSpecial.exists()' será mejor en este caso que 'myActiveSpecial.count()'. – yprez

Cuestiones relacionadas