2015-10-13 3 views
0

У меня есть следующие модели:Джанго - Выполнение QuerySet задачи уровня, прежде чем удалить

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

Но проблема в том, что она работает на уровне объекта, так что если я хочу, чтобы удалить 200,000 изображений, он должен сделать то же самое количество обновлений к камере.

Есть ли способ создать новый метод или сигнал, где я могу сделать что-то вроде этого?

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

Спасибо!

Edit 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(), счетчик обновляется, поэтому, когда изображение удаляется либо в админе, в оболочке и т. Д., Счетчик автоматически обновляется. – 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 

Off верхней части моей шляпы, вы можете сделать что-то вроде

# 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() 

 Смежные вопросы

  • Нет связанных вопросов^_^