2012-09-20 6 views
8

Mam 2 tabele products i catagories połączone kluczem obcym. muszę zaktualizować pole products.new_cost użyciu pola catagories.price_markup następująco:Tabela aktualizacji Django przy użyciu danych z innej tabeli

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 

W SQL jest to takie proste, ale jak to zrobić używając Django ORM?

Moja uproszczona próba nie działa 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')) 

Odpowiedz

-5

Django używa __ (podwójne) dla podkreślenia pokrewnych dziedzinach. Zmień to category.price_markup na category__price_markup i powinieneś być w czystości.

+5

Błąd: "Połączone odwołania do pól nie są dozwolone w tym zapytaniu". Bilet na ten temat https://code.djangoproject.com/ticket/14104 – Deadly

+2

W takim przypadku spróbuj użyć dodatkowego filtru i aktualizacji, a następnie użyj dodatkowego pola w aktualizacji. Coś jak "Product.activated.select_related (" category "). Filter (update = 1) .extra (select = {'_ new_price': 'pleer_cost * category.price_markup'}). Update (new_price = _new_price)'. Być może będziesz musiał trochę go zmienić, ale jest to ogólny pomysł. –

+0

Próbowałem Alex, nadal nie będzie działać, będzie narzekać, że "_new_price" nie znajduje się na liście pól. Funkcja aktualizacji nie dba o to, które pola wybrałeś, sprawdza tylko, które pola są modelowane. – 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 można workarounded z

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

Bardzo wolno dla dużych tabel – shadi

8

Według documentation, aktualizacje wykorzystujące dołączyć klauzule nie są obsługiwane, patrz:

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

Ponadto, zgodnie z tym issue ta jest z założenia i nie planuje go zmienić w najbliższej przyszłości:

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.