2015-10-13 72 views
0

我有以下型號:Django的 - 執行查詢集級別任務之前刪除

class Camera(models.Model) 
    deleted_images_counter = models.IntegerField(...) 

class Image(models.Model) 
    image = models.ImageField(....) 
    camera = models.ForeignKey(Camera) 

現在,我想更新相機deleted_images_counter場當我刪除一個或多個圖像。

我雖然關於使用信號:

@receiver(pre_delete, sender=Image,dispatch_uid="test") 
def update_deleted_images_counter(sender, instance, using, **kwargs): 
    camera = instance.camera 
    camera.counter = camera.counter + 1 
    camera.save() 

但問題是,它工作在對象級別,所以如果我想刪除20萬倍的圖像,它必須進行更新的相同數量的相機。

有什麼辦法可以創建一個新的方法或信號,我可以做這樣的事情嗎?

images_to_delete = Images.objects.filter(...) 
images_to_delete.delete()  

#some method of something 
def delete(queryset, ....): 
    #update the counter 
    camera.deleted_images_counter = camera.deleted_images_counter + queryset.count() 
    camera.save() 

    #continue with the delete... 
    queryset.delete() 

謝謝!

編輯1:

我剛剛注意到我想要做的一個缺陷。我假設要刪除的圖像屬於同一臺相機,但如果它們不是來自同一臺相機,則此方法無效。實現我想要的東西的唯一方法就是在聽衆中,我猜...

+0

它有沒有在模型層發生的呢?它可以發生在批量刪除圖像的地方嗎?或者我應該問問圖像是如何刪除的? –

+0

您使用的是什麼版本的Django? [自1.9'delete'](https://docs.djangoproject.com/en/1.9/ref/models/querysets/#delete)返回一個帶有'model label - > deleted rows count'的字典。 – Ivan

+0

那麼,我想要做的是,當我使用.delete(),計數器更新,所以當一個圖像(S)被刪除在管理員,在外殼等,計數器會自動更新。 – Agey

回答

0

您可以查詢集annotate方法獲取查詢集內每個相機的圖像數量。詳細請參照Django docs。他們的例子使用的模型非常相似,你的:

# Each publisher, each with a count of books as a "num_books" attribute. 
>>> from django.db.models import Count 
>>> pubs = Publisher.objects.annotate(num_books=Count('book')) 
>>> pubs 
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...] 
>>> pubs[0].num_books 
73 

# The top 5 publishers, in order by number of books. 
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5] 
>>> pubs[0].num_books 
1323 

關我的帽子的頂部,你可以這樣做

# this should return a list of dicts of format {'camera': int, 'images_to_delete': int} 
aggregated_queryset = image_queryset.values('camera__id').annotate(images_to_delete=Count('id')) 

for record in aggregated_queryset: 
    camera = Camera.objects.get(id=record.get('camera')) 
    images_to_delete = record.get('images_to_delete') 
    camera.deleted_images_counter += images_to_delete 
    camera.save() 

image_queryset.delete()