質問編集履歴

4

s-hara

s-hara score 40

2018/05/03 19:02  投稿

djangoでSMTPサーバを指定したメール送信がうまくいかない。
### 前提・実現したいこと
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
  • Django

    1613 questions

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

  • SMTP

    116 questions

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

  • メール

    311 questions

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

  • Python

    11751 questions

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

3 問題内容を修正

s-hara

s-hara score 40

2018/05/01 16:46  投稿

djangoでSMTPサーバを指定したメール送信がうまくいかない。
### 前提・実現したいこと
djangoにて社内のsmtpサーバを指定してメール送信したい。
djangoにて社内のsmtpサーバを指定してWEBからパスワードリセットメールが送信できない。
以下、長文となりますが、実装した機能の要点(コード)と、問題点をまとめました。
### 該当のソースコード
■djangoシェル上でメール送信テスト
```
python manage.py shell
from django.core.mail import send_mail
setting.pyの設定
send_mail(
   'Subject here',
   'Here is the message.',
   'from@example.com',
   ['to@example.com'],
   fail_silently=False,
)
```
### 試したこと
とりあえずコマンドレベルで動作を確認するために、上記のコードを実行したが
特にエラーは発生しないがtoで指定したアドレス宛にメールが送信されない。
setting.pyには以下の設定を実施済み。
```
# settings.py
EMAIL_HOST = '<社内のsmtpサーバ名を指定>'
EMAIL_PORT = 25
EMAIL_HOST = '<社内のSMTPサーバ名を指定>'
EMAIL_PORT = '25'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  
```
社内のsmtpサーバは認証なしで利用できるのでUSER,PASSWORDのパラメータは空  
で指定しています。  
普通のバッチファイルなどでメール送信する際は、smtpサーバ名とポート25番  
を指定するだけで利用できる環境になっています。  
ファイアウォール的に25ポートが遮断されているということもありません。  
メールが送信できない原因としてほかにどのようなことがか投あげられるでしょうか?  
■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
  • Django

    1613 questions

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

  • SMTP

    116 questions

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

  • メール

    311 questions

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

2 誤字修正

s-hara

s-hara score 40

2018/04/30 04:41  投稿

djangoでSMTPサーバを指定したメール送信がうまくいかない。
### 前提・実現したいこと
djangoにて社内のsmtpサーバを指定してメール送信したい。
### 該当のソースコード
```
python manage.py shell
from django.core.mail import send_mail
send_mail(
   'Subject here',
   'Here is the message.',
   'from@example.com',
   ['to@example.com'],
   fail_silently=False,
)
```
### 試したこと
とりあえずコマンドレベルで動作を確認するために、上記のコードを実行したが
特にエラーは発生しないがtoで指定したアドレス宛にメールが送信されない。
setting.pyには以下の設定を実施済み。
```
# settings.py
EMAIL_HOST = '<社内のsmtpサーバ名を指定>'
EMAIL_PORT = 25
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
```
社内のsmtpサーバは認証なしで利用できるのでUSER,PASSWORDのパラメータは空
で指定しています。
普通のバッチファイルなどでメール送信する際は、smtpサーバ名とポート25番
を指定するだけで利用できる環境になっています。
ファイアウォール的に25ポートが遮断されているということもありません。
### 補足情報(FW/ツールのバージョンなど)
django 2.0
  • Django

    1613 questions

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

  • SMTP

    116 questions

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

  • メール

    311 questions

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

1 説明追加

s-hara

s-hara score 40

2018/04/29 13:34  投稿

djangoでSMTPサーバを指定したメール送信がうまくいかない。
### 前提・実現したいこと
djangoにて社内のsmtpサーバを指定してメール送信したい。
### 該当のソースコード
```
python manage.py shell
from django.core.mail import send_mail
send_mail(
   'Subject here',
   'Here is the message.',
   'from@example.com',
   ['to@example.com'],
   fail_silently=False,
)
```
### 試したこと
とりあえずコマンドレベルで動作を確認するために、上記のコードを実行したが
特にエラーは発生しないがtoで指定したアドレス宛にメールが送信されない。
setting.pyには以下の設定を実施済み。
```
# settings.py
EMAIL_HOST = '<社内のsmtpサーバ名を指定>'
EMAIL_PORT = 25
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
```
社内のsmtpサーバは認証なしで利用できるのでUSER,PASSWORDのパラメータは空
で指定しています。
普通のバッチファイルなどでメール送信する際は、smtpサーバ名とポート25番
を指定するだけで利用できる環境になっています。
ファイアウォール的に25ポートが遮断されているということもありません。
メールが送信できない原因としてほかにどのようなことがか投げられるでしょうか?  
 
### 補足情報(FW/ツールのバージョンなど)
django 2.0
  • Django

    1613 questions

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

  • SMTP

    116 questions

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

  • メール

    311 questions

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

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る