2012-09-20 62 views
8

Tengo 2 tablas products y catagories conectadas por clave externa. necesito actualizar campo products.new_cost utilizando el campo catagories.price_markup de la siguiente manera:Tabla de actualización Django usando datos de otra tabla

UPDATE products p 
INNER JOIN categories c ON p.category_id = c.id 
SET p.new_cost = ROUND(p.pleer_cost * (1 + c.price_markup/100), -1) 
WHERE p.update = 1 

En SQL es tan fácil, pero la manera de hacerlo utilizando Django ORM?

Mi intento simplificado no funciona Cannot resolve keyword 'category.price_markup' into field.:

Product.actived.select_related('category').filter(update=1)).update(new_cost=F('pleer_cost') * F('category.price_markup')) 

Respuesta

-5

Django usa __ (doble subrayado) para los campos relacionados. Cambie ese category.price_markup a un category__price_markup y debe estar libre.

+5

Error: 'Las referencias de campo unidas no están permitidas en esta consulta'. Ticket about it https://code.djangoproject.com/ticket/14104 – Deadly

+2

En ese caso, intente utilizar un extra entre el filtro y la actualización, y luego use el campo adicional en su actualización. Algo así como 'Product.activated.select_related ('category'). Filter (update = 1) .extra (select = {'_ new_price': 'pleer_cost * category.price_markup'}). Update (new_price = _new_price)'. Puede que necesite ajustarlo un poco, pero es la idea general. –

+0

Lo intentó Alex, todavía no funciona, se quejará de que "_new_price" no está en la lista de campos. función de actualización no importa qué campos ha seleccionado, solo verifica qué campos tiene – Ramast

-1
from django.db import transaction 

with transaction.atomic(): 
    for p in Product.objects.select_related('category').filter(update=1) 
     p.new_cost= p.pleer_cost * p.category.price_markup 
     p.save() 
-1

AFAIU se puede workarounded con

for row in ModelName.objects.filter(old_field__isnull=False): 
    row.new_field = row.old_field.subfield 
    row.save() 
+0

muy lento para tablas grandes – shadi

8

De acuerdo con la documentation, actualizaciones usando unirse a las cláusulas no son compatibles, consulte:

However, unlike F() objects in filter and exclude clauses, you can’t introduce joins when you use F() objects in an update – you can only reference fields local to the model being updated. If you attempt to introduce a join with an F() object, a FieldError will be raised:

# THIS WILL RAISE A FieldError 
>>> Entry.objects.update(headline=F('blog__name')) 

Además, según esta issue, este es por diseño y no hay planes para cambiarlo en el futuro cercano:

The actual issue here appears to be that joined F() clauses aren't permitted in update() statements. This is by design; support for joins in update() clauses was explicitly removed due to inherent complications in supporting them in the general case.

Cuestiones relacionadas