0

新しい投稿が作成されたときに、'observers' ManyToMany フィールドで定義されたユーザーのリストに通知メールを送信したいと考えています。

投稿はエラーなしで作成され、オブザーバー ユーザーのリストが正常に追加されます (post_detail.html テンプレートに表示されます) が、通知メールがオブザーバー ユーザーに送信されることはありません。

以下の new_post 関数で何か間違ったことをしていると思います 。これは、ユーザーが投稿にコメントしたときにメールを送信するためにこのコードから適応させたもので、うまくいきます。どんな助けでも大歓迎です。

models.py (関連部分):

from django.db import models
from django.contrib.auth.models import User

from django.contrib.sites.models import Site
from django.db.models import signals
from notification import models as notification

class Post(models.Model):
    author = models.ForeignKey(User, related_name="added_posts")
    observers = models.ManyToManyField(User, verbose_name=_("Observers"), related_name='observers+', blank=True, null=True)

# send notification to Post observers
def create_notice_types(app, created_models, verbosity, **kwargs):
    notification.create_notice_type("new_post", "New post created", "A new post has been created")
signals.post_syncdb.connect(create_notice_types, sender=notification)

def new_post(sender, instance, created, **kwargs):   

    context = {
        'observer': instance,
        'site': Site.objects.get_current(),
    }

    recipients = []
    pk=instance._get_pk_val()

    for observer in instance.observers.all().distinct():
        if observer.user not in recipients:
            recipients.append(observer.user)

    notification.send(recipients, 'new_post', context)

signals.post_save.connect(
    new_post, sender=models.get_model(
    'blog', 'Post'), dispatch_uid="pkobservers")

views.py (関連部分):

@login_required
def add(request, form_class=PostForm, template_name="blog/post_add.html"):
    post_form = form_class(request)
    if request.method == "POST" and post_form.is_valid():
        post = post_form.save(commit=False)
        post.author = request.user
        post_form.save()
        post_form.save_m2m()
        return redirect("blog_user_post_detail", 
            username=request.user.username, slug=post.slug)
    return render_to_response(template_name, 
        {"post_form": post_form}, context_instance=RequestContext(request))

編集:

これも試してみました (blog_post および blog_post_observers テーブルを削除してからmanage.py syncdb再度実行しましたが、まだ機能しません):

models.py

class Post(models.Model):
    # ....
    observers = models.ManyToManyField(User, verbose_name=_("Observers"), related_name='observers+')

def new_post(sender, instance, created, **kwargs):   

    context = {
        'observer': instance,
        'site': Site.objects.get_current(),
    }

    recipients = instance.observers.all()
    pk=instance._get_pk_val()

    notification.send(recipients, 'new_post', context)

signals.post_save.connect(new_post, sender=models.get_model('blog', 'Post'), dispatch_uid="pkobservers")

編集 2 2013 年 6 月 27 日木曜日: 11:48:49 イタリア時間:

次のビューを使用して投稿を編集/更新すると、通知メールが機能します。

ビュー.py

@login_required
def edit(request, id, form_class=PostForm, template_name="blog/post_edit.html"):
    post = get_object_or_404(Post, id=id)
    if post.author != request.user:
        request.user.message_set.create(message="You can't edit items that aren't yours")
        return redirect("desk")
    post_form = form_class(request, instance=post)
    if request.method == "POST" and post_form.is_valid():
        post = post_form.save(commit=False)
        post.updated_at = datetime.now()
        post_form.save()
        post_form.save_m2m()
        messages.add_message(request, messages.SUCCESS, message=_("Successfully updated post '%s'") % post.title)
        return redirect("blog_user_post_detail", username=request.user.username, slug=post.slug)
    return render_to_response(template_name, {"post_form": post_form, "post": post}, context_instance=RequestContext(request))
4

2 に答える 2

2

まず第一に、各オブザーバーは理想的にはユーザーであり、None ではないため、多対多の関係は空白または null であってはならないと思います。これにより、エラーが発生する可能性がある None ユーザーにメールを送信しようとするのを回避できます。

第二に、私はあなたがただ使うことができると思います

recipients = instance.observers.all().distinct()

リストをループする代わりに (distinct() はすでに一意のユーザーのみを考慮しています)

第三に、「distinct()」が本当に必要な理由がわかりません。ユーザーは複数回オブザーバーになることができますか?

recipients = instance.observers.all()

4番目に、コードでは、すでにユーザーである「オブザーバー」を使用してinstance.observers.all()をループしています。なぜ受信者にobserver.userを追加するのですか? オブザーバーを追加するだけで十分だと思います。

最後に、受信者が空でないことを確認します。notification.send() をテストした場合、コードは正しいようです。

于 2013-06-26T15:22:03.420 に答える
0

新しい投稿を作成すると、オブザーバーに通知メールが送信されるようになりました。

基本的に、post.id を設定した後、save をもう一度呼び出す必要がありました。

ビュー.py:

@login_required
def add(request, form_class=PostForm, template_name="blog/post_add.html"):
    post_form = form_class(request)
    if request.method == "POST" and post_form.is_valid():
        post = post_form.save(commit=False)
        post.author = request.user
        post_form.save()
        post.id = post.id # set post id
        post_form.save() # save a second time for notifications to be sent to observers 
        return redirect("blog_user_post_detail", 
            username=request.user.username, slug=post.slug)
    return render_to_response(template_name, 
        {"post_form": post_form}, context_instance=RequestContext(request))

models.py は、質問の最初の EDIT: から変更されていません (助けてくれたJC Leitãoに感謝します)。

ここで、次のことを確認してください。

models.py

class Post(models.Model):
    observers = models.ManyToManyField(User, verbose_name=_("Observers"), related_name='observers+')

def new_post(sender, instance, created, **kwargs):   

    context = {
        'observer': instance,
        'site': Site.objects.get_current(),
    }

    recipients = instance.observers.all()
    pk=instance._get_pk_val()

    notification.send(recipients, 'new_post', context)

signals.post_save.connect(new_post, sender=models.get_model('blog', 'Post'), dispatch_uid="pkobservers")
于 2013-06-28T13:54:51.130 に答える