質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • Python

    9217questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1176questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

  • メール

    265questions

    メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

  • SMTP

    101questions

    SMTP(Simple Mail Transfer Protocol)はIPネットワークでemailを伝送する為のプロトコルです。

djangoでSMTPサーバを指定したメール送信がうまくいかない。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 473

s-hara

score 40

 前提・実現したいこと

djangoにて社内のsmtpサーバを指定してWEBからパスワードリセットメールが送信できない。
以下、長文となりますが、実装した機能の要点(コード)と、問題点をまとめました。

■djangoシェル上でメール送信テスト

setting.pyの設定

EMAIL_HOST = '<社内のSMTPサーバ名を指定>'
EMAIL_PORT = '25'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

■python manage.py shellで以下を実行。

In [1]: from django.core.mail import send_mail

In [2]: send_mail(
   ...:     'Subject here_mailhub',
   ...:     'Here is the message.',
   ...:     'fromアドレスを指定',
   ...:     ['toアドレスを指定'],
   ...: )
Out[2]: 1

⇒問題なくメール送信される(OK)

■パスワードリセット用機能を実装し、WEBからパスワードリセット用メールを送信するとメールが配信されない。

※setting.pyは上記と同じ内容。

※パスワードリセットは以下の構成(要点だけ記載)

●url.py
    path('password_reset/', views.PasswordReset.as_view(), name='password_reset'),
    path('password_reset/done/', views.PasswordResetDone.as_view(), name='password_reset_done'),
    path('reset/<uidb64>/<token>/', views.PasswordResetConfirm.as_view(), name='password_reset_confirm'),
    path('reset/done/', views.PasswordResetComplete.as_view(), name='password_reset_complete'),
●views.py

from .forms import (MyPasswordResetForm, MySetPasswordForm)

from django.contrib.auth.views import (PasswordChangeDoneView,
    PasswordResetView, PasswordResetDoneView, PasswordResetConfirmView, PasswordResetCompleteView
)
from django.urls import reverse_lazy

class PasswordReset(PasswordResetView):
    """パスワード変更用URLの送付ページ"""
    subject_template_name = 'accounts/subject.txt'
    email_template_name = 'accounts/message.txt'
    template_name = 'accounts/password_reset_form.html'
    form_class = MyPasswordResetForm
    success_url = reverse_lazy('password_reset_done')


class PasswordResetDone(PasswordResetDoneView):
    """パスワード変更用URLを送りましたページ"""
    template_name = 'accounts/password_reset_done.html'
●forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordChangeForm, PasswordResetForm, SetPasswordForm


class MyPasswordResetForm(PasswordResetForm):
    """パスワード忘れたときのフォーム"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'


class MySetPasswordForm(SetPasswordForm):
    """パスワード再設定用フォーム(パスワード忘れて再設定)"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'

class PasswordResetConfirm(PasswordResetConfirmView):
    """新パスワード入力ページ"""
    form_class = MySetPasswordForm
    success_url = reverse_lazy('password_reset_complete')
    template_name = 'accounts/password_reset_confirm.html'


class PasswordResetComplete(PasswordResetCompleteView):
    """新パスワード設定しましたページ"""
    template_name = 'accounts/password_reset_complete.html'
●password_reset_form.html


<form action="" method="POST">
    {{ form.non_field_errors }}
    {% for field in form %}
    <div class="form-group">
        <label for="{{ field.id_for_label }}">{{ field.label_tag }}</label>
        {{ field }}
        {{ field.errors }}
    </div>
    {% endfor %}
    {% csrf_token %}
    <button type="submit" class="btn btn-primary btn-lg">送信</button>
</form>
●password_reset_done.html

<p>
    パスワード再設定用のメールを送信しました。<br>
    メールに記載されているリンクから再設定を行ってください。
</p>
●message.txt
{{ user.username }} 様

下記URLよりサイトにアクセスの上、パスワードの再設定を行ってください。

再設定用URL
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uid token %}

テストです。
●subject.txt

パスワードの再登録

<その他に試したこと>
setting.pyで以下の通りコンソールモードにしてからパスワードリセットを実行

EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

結果:コンソールに以下のようにパスワードリセット用のURLが表示される(OK)

Message-ID: <152515770692.2608.2202147284301657819@<PC名>

xxxxx 様

下記URLよりサイトにアクセスの上、パスワードの再設定を行ってください。

再設定用URL
http://127.0.0.1:8000/accounts/reset/Mg/4vt-61b46d5e192e0d5ee144/

xxxxxx

上記URLにアクセスすると問題なくパスワード変更ができるので、問題個所は
WEBページから社内SMTPサーバを使ったスワードリセットをお知らせするメール送信部分に問題がありそう。
但し、python managep.py shell上でsend_mailメソッドを使って社内SMTPサーバを指定してメール送信した場合は問題なくメール送信できる。

上記状況から、何が原因として考えられますでしょうか。

以上、よろしくお願いいたします。

 補足情報(FW/ツールのバージョンなど)

django 2.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

以下と同じ原因でした。

https://teratail.com/questions/127706

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

USER,PASSWORDのパラメータはフリーメールのサービスのものを
指定し、シェルからフリーメールに送信できました。

イメージ説明

メールが送信できない原因としてほかにどのようなことが

USER,PASSWORDのパラメータは空
で指定

が気になります。
USER,PASSWORDのパラメータを今度は実際のメールのもので指定。これで試してみてください。

またはその送信時にポート25番を使うsmtpのプロセス、サービスが起動していなかった。
フィルタリング機能のある中継サーバ画置かれているとか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/01 16:41 編集

    回答ありがとうございます。
    その後再確認したところ、send_mailメソッドでは普通にメール送信ができました。(なぜメール送信できなかったかは謎ですが今は問題ありません)
    単体レベルで社内SMTPサーバを使ってメール送信できることが確認できましたので、別途、パスワードリセット用機能を実装してWEBからリセット用メールを送信しようとするとメールが配信されない問題が発生しました。
    パスワードリセットの実装内容と問題内容を整理して記事を更新しました。
    もし原因について情報がありましたらご回答いただけますと幸いです。

    以上、よろしくお願いいたします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Python

    9217questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Django

    1176questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

  • メール

    265questions

    メールは、コンピュータネットワークを利用し、 情報等を交換する手段のことです。

  • SMTP

    101questions

    SMTP(Simple Mail Transfer Protocol)はIPネットワークでemailを伝送する為のプロトコルです。