12

Djangoの「pre_save」シグナルを次の方法でテストしましたが、どちらの方法でもシグナルをキャッチできません。

$

from django.db.models.signals import pre_save
import logging

def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback)
  1. 上記のコードをmanage.pyシェルで実行します。次に、Webサイトを実行して、models.save()が正常に機能することを確認しましたが、コールバック関数が実行されません。

  2. または、シェルで上記のコードを再度実行してから、シェルでmodels.save()を実行します。「保存」は再びうまく機能しますが、それでもコールバック関数には何も起こりません。

  3. 最後に、上記のコードをファイルに埋め込み、__init__.pyWebサイトでsave()関数を実行します。それでも、何も起こりません。

pre_save信号が機能しない理由を理解するのを手伝っていただけませんか。

4

4 に答える 4

10

送信者クラスを設定していません。

from django.db.models.signals import pre_save
from myapp.models import MyModel
import logging

def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback, sender=MyModel)

次に、Django 1.3を使用している場合は、新しいデコレータ構文を使用する必要があります。

# Inside your models.py
from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver

class MyModel(models.Model):
    field1 = models.TextField()
    field2 = models.IntegerField()

@receiver(pre_save, sender=MyModel)
def mymodel_save_handler(sender, **kwargs):
    logging.debug("======================================")

それでうまくいくはずですが、私はコードをテストしていないので、まだ壊れているかどうか教えてください。

于 2011-05-27T14:59:26.070 に答える
3

エリックの答えがうまくいった理由は、models.py内にシグナルを接続させたためです。そのため、Webサイトを介してモデルを保存すると、シグナルハンドラーはシグナルファイアと同じプロセスになります。

例1と3では、なぜそれらが機能しなかったのかを簡単に理解できます。信号受信機がリッスンしている場所とは異なるプロセス(Webサイト)で保存しています。

例2も壊れている理由をもっとよく理解したいのですが、シェルで信号をテストしているときに、自分のプロジェクトで同様の問題をデバッグしました。これは、信号の送信者と受信者がお互いを「見る」ことができないことと関係があります。

于 2011-08-26T09:50:57.097 に答える
3

logging.debug()はルートロガーを使用しています。このハンドラーレベルはデフォルトで30(「警告」)です。

=>logging.debug('something')はまったく何もしていません(DEBUGレベルは10 <30です)。http://docs.python.org/2/library/logging.htmlを参照してください

同じテストは、別のカスタムロガーを使用するか、次のようにして実行する必要があります。

l = logging.getLogger()
l.setLevel(10)
def my_callback(sender, **kwargs):
    logging.debug("======================================")
pre_save.connect(my_callback)

元の質問には、OPが直面している実際の問題(またはその一部)であるかどうかを知るのに十分な情報が含まれていません。
しかし、確かにOPのコードは私の./manage.py shell

于 2012-11-14T18:07:10.987 に答える
-1

djangoシグナルのドキュメントで説明されているように、シグナルpre_saveは3つの一意の引数(キーワード引数ではない)を受け入れるため、my_callback関数を次のように編集する必要があります。

def my_callback(sender,instance, using, **kwargs):
    logging.debug("======================================")
于 2011-05-27T14:58:45.957 に答える