Хобрук: Ваш путь к мастерству в программировании

Django обновляет количество элементов при каждом сохранении или удалении

Я новичок в Django и все еще учусь. Я хочу отслеживать, сколько events у меня на тесте. Моя текущая модель выглядит так

class Test(models.Model):
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=255, blank=True)
    num_of_events = models.IntegerField(default=0)

    class Meta:
        verbose_name = 'Test'
        verbose_name_plural = 'Tests'

    def __str__(self):
        return self.name


class Event(models.Model):
    name = models.CharField(max_length=255)
    test = models.ForeignKey(Test,on_delete=models.CASCADE)

    class Meta:
        verbose_name = 'Event'
        verbose_name_plural = 'Events'

    def __str__(self):
        return self.name

    def save(self):
        obj, created = Test.objects.update_or_create(name=self.test)
        obj.num_of_events += 1
        super().save()

    def delete(self):
        self.test.num_of_events -= 1
        super().delete()

Я думал, что могу просто переопределить функцию save(), но она не обновляется в панели администратора и по-прежнему показывает 0.

Я пытаюсь понять, что я делаю неправильно.

РЕДАКТИРОВАТЬ: admin.py

class TestAdmin(admin.ModelAdmin):
    list_display = ('name', 'description', 'num_of_events')

    fieldsets = [
        (None, {'fields': ('name', 'description')})
    ]

class EventsAdmin(admin.ModelAdmin):
    pass

class PropertyAdmin(admin.ModelAdmin):
    list_display = ('name', 'property_type', 'expected_value')

admin.site.register(Test, TestAdmin)
admin.site.register(Event, EventsAdmin)
admin.site.register(Property, PropertyAdmin)
16.04.2020

  • Пожалуйста, не храните количество предметов. Вы можете использовать аннотацию для получения количества Events за Test. Это надежнее. 16.04.2020
  • Что вы делаете неправильно, так это не сохранение объекта Test, но, тем не менее, дублирование данных — это не хорошая идея. 16.04.2020
  • документы аннотаций/агрегации -› docs.djangoproject.com/en/3.0/topics /дб/агрегация 16.04.2020

Ответы:


1

Вы забыли сохранить объект Test. Например с:

class Event(models.Model):
    # …

    def save(self):
        if self.test_id is not None:
            obj = self.test
            obj.num_of_events += 1
            obj.save()
        super().save()

    def delete(self):
        if self.test_id is not None:
            self.test.num_of_events -= 1
            self.test.save()
        super().delete()

Но, тем не менее, сохранение количества элементов обычно не является хорошей идеей. Допустим, вы меняете .test данного Event, тогда вам нужно вычесть из старого Test и прибавить к новому Test. Кроме того, массовые операции ORM, такие как .update(..) обход .save() и сигналов, поэтому будет сложно или невозможно сохранить это правильно.

Дело в том, что вам не нужно не хранить количество Events. Действительно, вы можете просто получить их с помощью:

from django.db.models import Count

Test.objects.annotate(number_of_events=Count('event'))

Объекты Test, возникающие из этого набора запросов, будут иметь дополнительный атрибут .number_of_events, содержащий число связанных Event объектов.

16.04.2020
  • Куда бы я поместил эту строку? 16.04.2020
  • @Halloween: в представлениях, где вам, например, нужно количество событий или нужно отфильтровать количество событий. 16.04.2020
  • Он находится на странице администратора. Я использую list_display для вывода переменных на панели. 16.04.2020
  • @Halloween: вы можете переопределить get_queryset из ModelAdmin для отображения аннотаций: stackoverflow.com/a/48607830/67579 16.04.2020
  • Я добавил свой admin.py к вопросу. Буду ли я помещать его в функцию EventsAdmin? 16.04.2020
  • @Halloween: нет, в TestAdmin, так как это тот, у которого есть количество событий. 16.04.2020
  • Есть ли где-нибудь, что объясняет это? я этого не понимаю. 16.04.2020
  • Новые материалы

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..

    React Hooks: основы деструктуризации массива
    Kent C. Dodds написал классный пост о том, как грядущая функция React под названием Hooks работает на капоте. Предстоящий хук React useState основан на деструктурировании массива, давайте..

    Пакеты R, используемые в Tesla
    Добро пожаловать обратно! R — очень популярный язык программирования, используемый множеством компаний, включая Tesla! Итак, давайте взглянем на некоторые пакеты R, которые использует Tesla...

    Сокращение и слияние токенов для эффективных моделей VL: обзор
    Часто в задачах, связанных с компьютерным зрением и НЛП, вычислительно затратная и требующая большого объема памяти обработка становится препятствием для более быстрого логического вывода модели, а..