2013-03-29 17 views
13

Django (python) uygulamasında tüm nesneler için belirli bir sıradaki konum alanını bir kerede güncellemeye çalışıyorum.Tüm modelleri aynı anda Django'da güncelleştirin

Şimdi böyle yaptım, ancak sorun, bir sürü sorgu yapmasıdır.

servers = frontend_models.Server.objects.all().order_by('-vote_count') 

    i = 1 
    for server in servers: 
     server.last_rank = i 
     server.save() 
     i += 1 

Model.objects.all().order_by('some_field').update(position=some_number_that_changes_for each_object) 

teşekkür ederiz ile güncellemek için bir yolu var mı! Sütun tüm değerleri güncelleştirmek için tek bir SQL sorgusu oluşturur

Model.objects.all().order_by('some_field').update(position=F(some_field)+1) 

, bu yüzden de veritabanına etkilidir:

+0

Her nesne için geçirilen sayıyı artırmak ister misiniz? –

+1

django query api, [windows işlevleri] içermiyor (http://www.postgresql.org/docs/9.1/static/tutorial-window.html) (Sanırım). RDBMS'niz bu özelliğe sahipse, [custom sql direct] (https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly) dosyasını çalıştırmalısınız. – danihp

cevap

5

Sen aynı şeyi django.db.models den F() ifade kullanabilirsiniz.

+0

Bu, OP'nin sorusunu yanıtlamaz, çünkü F() yalnızca istedikleri sırada satırlar arasında artış yapmak yerine, aynı satırdaki bir alanın değerini temel alarak hesaplayabilir. –

+0

Belirtilen belirli bir sorun için, aynı satır üzerinde çalışmak üzere yeniden oluşturulabilir; yok hayır? –

+1

Bu yalnızca F (same_field_of_previous_row) + 1 – Byteme

0

Bildiğim kadarıyla, Django'nun nesne-ilişkisel haritalama sistemi bu güncelleme işlemini ifade etmenin bir yolunu sağlamaz. Eğer SQL bunu ifade etmeyi biliyor Ama eğer, o zaman bir custom SQL query aracılığıyla çalıştırabilirsiniz:

from django.db import connection 
cursor = connection.cursor() 
cursor.execute('''UPDATE myapp_server ...''') 

Farklı veritabanı motorları farklı şekillerde bu işlemi ifade etmektedir. PostgreSQL de

SET @rownum=0; 
UPDATE myapp_server A, 
     (SELECT id, @rownum := @rownum + 1 AS rank 
     FROM myapp_server 
     ORDER BY vote_count DESCENDING) B 
SET A.rank = B.rank 
WHERE A.id = B.id 

Sana

UPDATE myapp_server A, 
     (SELECT id, rownumber() AS rank 
     OVER (ORDER BY vote_count DESCENDING) 
     FROM myapp_server) B 
SET A.rank = B.rank 
WHERE A.id = B.id 

kullanmak düşünüyorum (ama bu denenmemiş, bu yüzden dikkat!): MySQL Bu sorguyu çalıştırmak istiyorum.