2012-09-20 10 views
8

Ho 2 tabelle products e catagories collegate da chiave esterna. Devo aggiornare campo products.new_cost utilizzando il campo catagories.price_markup come segue:Tabella di aggiornamento Django utilizzando i dati da un'altra tabella

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 

In SQL è così facile, ma come farlo utilizzando Django ORM?

mia prova semplificata non funziona 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')) 

risposta

-5

Django utilizza __ (doppia sottolineatura) per i campi correlati. Cambia il numero category.price_markup in un category__price_markup e dovresti essere in chiaro.

+5

Errore: 'I riferimenti campo aggiunti non sono consentiti in questa query'. Ticket su di esso https://code.djangoproject.com/ticket/14104 – Deadly

+2

In tal caso, provare a utilizzare un extra tra filtro e aggiornamento, quindi utilizzare il campo aggiuntivo nell'aggiornamento. Qualcosa come 'Product.activated.select_related ('category'). Filter (update = 1) .extra (select = {'_ new_price': 'pleer_cost * category.price_markup'}). Update (new_price = _new_price)'. Potrebbe essere necessario regolarlo un po ', ma è l'idea generale. –

+0

Provato Alex, ancora non funzionerà si lamenterà che "_new_price" non è nella lista dei campi. La funzione di aggiornamento non interessa i campi selezionati, controlla solo i campi che il modello ha – 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 si può aggirare il problema con

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

molto lento per i tavoli di grandi dimensioni – shadi

8

Secondo il documentation, aggiornamenti utilizzando unire le clausole non sono supportati, vedere:

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

Inoltre, secondo questo issue, questo è di progettazione e non è in programma di cambiarlo nel prossimo futuro:

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.

Problemi correlati