簡體   English   中英

Django 信號 - 如何使用 post_save 發送 model 中保存的內容?

[英]Django signals - how do I send what was saved in the model using post_save?

嘗試使用信號通過 websockets 發送使用.save() 保存的最后一條記錄。 我在data中輸入了什么?

#models.py
from django.db import models
from django.db.models.signals import post_save
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

class DataModel(models.Model):
    time = models.DateTimeField()
    value = models.FloatField()

    def __str__(self):
        return str(self.time)

def save_post(sender, instance, **kwargs):
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        "echo_group",
        {"type": "on.message", "data": data},
    )

post_save.connect(save_post, sender=DataModel)

我想我可以只獲取索引最高的記錄並發送它,但想知道是否有更優雅的解決方案。

我認為instance.__dict__是你想要的。 它將所有 model 屬性轉換為字典鍵值對

所以你可以做類似的事情

def save_post(sender, instance, **kwargs):
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(
        "echo_group",
        {"type": "on.message", "data": instance.__dict__},
    )

更新

我跳過提到該instance是剛剛保存並觸發post_save信號的實際 object。 因此,在給定的問題中, instance將類似於instance = DataModel.objects.create(**kwargs)

前奏:處理通道水化

要知道上次修改的內容,您需要一個上次修改的字段。 這是一個眾所周知的模式,Django 使用 DateTimeFields 的auto_now=True參數來幫助解決它。 這些字段不可編輯,並盡可能使用數據庫觸發器來獲得結果(這就是它們不可編輯的原因)。

如前所述,這很常見,所以我通常使用基礎 model:

class AuditableBase(models.Model):
    """
    Base class that adds created_at and last_modified fields for audit purposes.
    """

    created_at = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

現在獲取最后修改的記錄並用最后修改的通道水合通道是微不足道的,無論是否發生保存:

class DataModel(AuditableBase):
    time = models.DateTimeField()
    value = models.FloatField()

    def __str__(self):
        return str(self.time)

# On channel start:
latest = DataModel.objects.latest('last_modified')

信號處理程序

但是,如果我們使用 post save 信號,我們已經在“instance”參數中擁有剛剛保存的 object。 為了輕松將其轉換為 json,我們可以使用 model_to_dict 和 DjangoJSONEncoder 來處理大多數問題:

from django.forms.models import model_to_dict
from django.core.serializers import DjangoJSONEncoder
import json

def save_post(sender, instance, **kwargs):
    channel_layer = get_channel_layer()
    data = model_to_dict(instance)
    json_data = json.dumps(data, cls=DjangoJSONEncoder)
    async_to_sync(channel_layer.group_send)(
        "echo_group",
        {"type": "on.message", "data": json_data},
    )

Model_to_dict 會將 model 轉換為字典,並且可以使用fields= (顯式包含)或exclude= (顯式排除)進行限制。 DjangoJSONEncoder 處理時態數據,這是 json 的默認編碼器不支持的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM