Django обновление количества элементов при каждом сохранении или удалении - PullRequest
1 голос
/ 16 апреля 2020

Я новичок в 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)

1 Ответ

0 голосов
/ 16 апреля 2020

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

class Event(models.Model):
    # …

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

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

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

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

from django.db.models import Count

Test.objects.annotate(<b>number_of_events=Count('event')</b>)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...