Как заставить мой шаблон «загружаться» на секунду или две перед обновлением после POST - PullRequest
5 голосов
/ 14 января 2020

У меня проблема с событием MariaDB в сочетании с моей Django моделью. Для контекста, вот мой код модели:

class PartGroup(models.Model):
    GroupID = models.AutoField(primary_key=True, unique=True)
    Label = models.CharField(max_length=40, blank=True)
    SiteID = models.ForeignKey('Site', on_delete=models.CASCADE, null=True)
    InspectionPeriod = models.IntegerField(blank=False, null=True)
    LastInspected = models.DateField(blank=True, null=True)
    InspectionDue = models.CharField(max_length=255, blank=True)
    ConnectedTo = models.ManyToManyField('self', blank=True, null=True)

Поля, которые я хочу выделить здесь: InspectionPeriod, LastInspected и InspectionDue. У меня есть другая модель, которая добавляет проверки, связанные с GroupID. Здесь указана дата проверки:

class GroupInspection(models.Model):
    InspectionID = models.AutoField(primary_key=True, unique=True)
    GroupID = models.ForeignKey('PartGroup', on_delete=models.CASCADE, null=True, unique=True)

class GroupReport(models.Model):
    ReportID = models.AutoField(primary_key=True, unique=True)
    InspectionID = models.ForeignKey('GroupInspection', on_delete=models.CASCADE, null=True)
    Date = models.DateField(auto_now=False, auto_now_add=False, null=True)
    Comment = models.CharField(max_length=255, blank=True)
    Signature = models.CharField(max_length=255, blank=True)

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

Вот где возникает проблема

Мне необходимо обновлять событие MariaDB раз в 1 секунду, чтобы эта работа работала достаточно хорошо. Я не уверен, является ли это абсолютно ужасной производительностью или нет, если у кого-то есть другое решение, которое работает более плавно, это приветствуется. Но это не настоящая проблема. Когда я создаю проверку, она сразу же перенаправляется на страницу шаблона моей группы. Перенаправление занимает меньше секунды, что приводит моих пользователей в замешательство, так как они только что создали проверку, и пока не отображается на перенаправлении, если они сразу не обновят sh через 1 секунду.

Как я могу обойти это?

РЕДАКТИРОВАТЬ 1 Я забыл упомянуть - способ, которым это работает на уровне шаблона, состоит в том, что у меня есть страница, которая показывает табличное представление всех моих групп и их атрибутов. Затем у меня есть несколько кнопок, которые создают проверку в зависимости от того, какая кнопка нажата. Это просто перенаправляет обратно на ту же страницу, поэтому одна секунда является проблемой, поскольку перенаправление обычно занимает меньше секунды.

РЕДАКТИРОВАТЬ 2 Вот мой взгляд:

def groupList(request, site):
    status = "default"
    if request.method == "POST":

        list = GroupInspection.objects.filter(GroupID = request.POST.get("group"))
        if not list.exists():
            insp = GroupInspection.create(PartGroup.objects.get(GroupID = request.POST.get("group")))
            insp.save()


        if 'pass' in request.POST:
            groupReport = GroupReport.create(GroupInspection.objects.get(GroupID = request.POST.get("group")), date.today(), "Pass", request.user.username)
            groupReport.save()
        if 'fail' in request.POST:
            groupReport = GroupReport.create(GroupInspection.objects.get(GroupID = request.POST.get("group")), date.today(), "Fail", request.user.username)
            groupReport.save()
        if 'checkSubmit' in request.POST:
            groupReport = GroupReport.create(GroupInspection.objects.get(GroupID = request.POST.get("group")), date.today(), request.POST.get("comments"), request.user.username)
            groupReport.save()
        status = "changed"
    siteselected = Site.objects.get(SiteID = site)
    groupList = PartGroup.objects.filter(SiteID = siteselected)
    warnings = 0
    expired = 0
    good = 0

    for group in groupList:
        if group.LastInspected == None:
            group.InspectionDue = "Yes"
            expired = expired + 1

        else:
            Deadline = group.LastInspected + timedelta(days=group.InspectionPeriod)

            if datetime.now().date() > Deadline:
                group.InspectionDue = "Yes"
                expired = expired + 1

            elif datetime.now().date() > (Deadline - timedelta(days=30)):
                group.InspectionDue = "<30 Days"
                warnings = warnings + 1
            else:
                group.InspectionDue = "No"
                good = good + 1
        group.save()

    context = {
        'status': status,
        'SiteNo': siteselected.SiteID,
        'SiteName':siteselected.SiteName,
        'groupList': groupList,
        'expired': expired,
        'warnings': warnings,
        'good': good,
        }
    template = loader.get_template('moorings/groupList.html')
    return HttpResponse(template.render(context, request))

РЕДАКТИРОВАТЬ 3 Вот мой SQL Событие

CREATE EVENT updateLastInspected 
 ON SCHEDULE EVERY 1 SECOND
 DO
 UPDATE proj_partgroup g INNER JOIN (   SELECT i.GroupID_id, max(r.Date) Date   FROM proj_groupinspection i    INNER JOIN proj_groupreport r ON r.InspectionID_id = i.InspectionID   GROUP BY i.GroupID_id ) t ON g.GroupID = t.GroupID_id SET g.LastInspected = t.Date;

1 Ответ

1 голос
/ 15 января 2020

Вы можете заменить SQL Событие на Django сигнал , который запускается после любого GroupReport обновления, а в случае создания нового отчета - обновления, соответствующие PartGroup дате последнего обновления.

proj / signal.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from django.apps import apps


GroupReport = apps.get_model("proj", "GroupReport")
PartGroup = apps.get_model("proj", "PartGroup")


@receiver(post_save, sender=GroupReport)
def update_partgroup_lastinspection(sender, instance, created, **kwargs):
    if created:
        # cause FKs can be null - may need to add
        # null checks or try / except
        pg = instance.InspectionID.GroupID
        if instance.Date > pg.LastInspected:
            pg.LastInspected = instance.Date
            pg.save(update_fields=['Date'])

        # another option to perform same update
        PartGroup.objects.filter(
            LastInspected__lt=instance.Date,
            group_inspection__group_report=instance
        ).update(
            LastInspected=instance.Date
        )

proj / apps.py

...
class ProjConfig(AppConfig):
    name = "proj"
...
  def ready(self):
      import proj.signals

Вы можете пропустить проверку того, что значение больше, и просто обновить его прямо сейчас. Или вместо этого добавьте logi c в метод модели save() (который обычно более предпочтителен, чем сигналы).


Предыдущий ответ - здесь дело не в этом, groupList содержит изменения в экземплярах.

Вы возвращаете groupList, который содержит старые результаты.

Причина этого заключается в том, что при повторении по (for group in groupList) QuerySets оценивается , при этом результат кэшируется в этом экземпляре QuerySet, а затем, когда он используется в контексте - этот оцененный результат передается, хотя экземпляры были обновлены в базе данных. QuerySets необходимо запустить и снова оценить, чтобы получить результаты fre sh.

Одно простое решение для повторного использования QuerySet и его повторной оценки - это append .all () к предыдущему QuerySet - это создаст копию предоставленного QuerySet, и, поскольку он новый, он еще не оценен.

    context = {
        ...
        'groupList': groupList.all(),
        ...
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...