私の Django アプリは記事を保存しており、ClearableFileInput ウィジェットを使用するアップロード ファイル フィールドが含まれています。公開する記事を設定すると、メールを送信するタスクが呼び出されます。
動作しているように見えますが、バグがあります。既存の記事を編集して「クリア」チェックボックスをマークすると、メール送信タスクが失敗します。エラーは IOError: [Errno 21] Is a directory: u'/path/to/my/static-dir' と言います
私の edit_article ビューで、私はこのロジックを試していました:
def edit_article(request, slug):
article = get_object_or_404(Article, slug=slug)
if request.method == 'POST':
form = ArticleForm(request.POST, request.FILES, instance=article)
if form.is_valid():
article = form.save()
msg = "Article updated successfully"
messages.success(request, msg, fail_silently=True)
if article.is_published and article.publish_date <= datetime.datetime.today():
subject = article.title
email_text = article.email_text
story_text = article.text
if article.docfile != None:
attachment = article.docfile
send_published_article.delay(request.user.email,
subject,
email_text,
story_text,
attachment)
else:
send_published_article.delay(request.user.email,
subject,
email_text,
story_text)
msg = "Article published successfully"
messages.success(request, msg, fail_silently=True)
return redirect(article)
else:
form = ArticleForm(instance=article)
return render_to_response('story/article_form.html',
{
'form': form,
'article': article,
},
context_instance=RequestContext(request))
問題のある行はおそらく
if article.docfile != None:
しかし、ファイルが消去されたかどうかを確認するにはどうすればよいですか? Django の ClearableFileInput ウィジェットは実際にファイル フィールドの値を何に設定するので、添付するファイルがあるかどうかをテストできますか?
これが私のtasks.pyです:
class EMail(object):
"""
A wrapper around Django's EmailMultiAlternatives
that renders txt and html templates.
Example Usage:
>>> email = Email(to='oz@example.com', subject='A great non-spammy email!')
>>> ctx = {'username': 'Oz Katz'}
>>> email.text('templates/email.txt', ctx)
>>> email.html('templates/email.html', ctx) # Optional
>>> email.send()
>>>
"""
def __init__(self, subject, to, cc, bcc):
self.subject = subject
self.to = to
self.cc = cc
self.bcc = bcc
self._html = None
self._text = None
self._attachment = None
def _render(self, template, context):
return render_to_string(template, context)
def html(self, template, context):
self._html = self._render(template, context)
def text(self, template, context):
self._text = self._render(template, context)
def add_attachment(self, attachment):
self._attachment = default_storage.open(attachment.name, 'r')
def send(self, from_addr=None, fail_silently=False):
if isinstance(self.to, basestring):
self.to = [self.to]
if not from_addr:
from_addr = getattr(settings, 'DEFAULT_FROM_EMAIL')
msg = EmailMultiAlternatives(
self.subject,
self._text,
from_addr,
to=self.to,
cc=self.cc,
bcc=self.bcc
)
if self._html:
msg.attach_alternative(self._html, 'text/html')
if self._attachment:
msg.attach(self._attachment.name, self._attachment.read())
msg.send()
@task(name='send-email')
def send_published_article(sender, subject, email_text, story_text, attachment=None):
"""
Task for emailing published articles.
Runs when an article is saved and is_published==True
"""
recipients = []
reporters = []
for profile in UserProfile.objects.all():
if profile.user_type == 'Client':
recipients.append(profile.user.email)
if profile.user_type == 'Reporter':
reporters.append(profile.user.email)
email = EMail(subject, to='nns.aroberts@gmail.com', cc=reporters, bcc=recipients)
ctx = {'story_text': story_text, 'email_text': email_text}
email.text('../templates/templated_email/emaila.txt', ctx)
email.html('../templates/templated_email/emaila.html', ctx) # Optional
if attachment != None:
email.add_attachment(attachment) # Optional
email.send()