一:Django发送邮件
在setting中配置
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' # 如果是 163 改成 smtp.163.com EMAIL_PORT = 465 EMAIL_HOST_USER = '306334678@qq.com' # 帐号 EMAIL_HOST_PASSWORD = '***' # 密码 DEFAULT_FROM_EMAIL = EMAIL_HOST_USER #这样收到的邮件,收件人处就会这样显示 #DEFAULT_FROM_EMAIL = 'lqz<'306334678@qq.com>' EMAIL_USE_SSL = True #使用ssl #EMAIL_USE_TLS = False # 使用tls #EMAIL_USE_SSL 和 EMAIL_USE_TLS 是互斥的,即只能有一个为 True
view视图函数
from django.core.mail import send_mail import threading from mybbs import settings t = threading.Thread(target=send_mail, args=("您的文章%s新增了一条评论内容" , 'ddd', settings.EMAIL_HOST_USER, ["616564099@qq.com"]) ) t.start()
一次性发多封邮件
from django.core.mail import send_mass_mail message1 = ('第一封邮件标题', '这是邮件内容', 'from@example.com', ['first@example.com', 'other@example.com']) message2 = ('第二封邮件标题', '这是邮件内容', 'from@example.com', ['second@test.com']) ''' fail_silently: (可选)布尔值。为 False 时, send_mail 会抛出 smtplib.SMTPException 异常。smtplib 文档列出了所有可能的异常。 这些异常都是 SMTPException 的子类 ''' send_mass_mail((message1, message2), fail_silently=False) ''' send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。 '''
携带附件或发送html(需要接收方支持)
from django.core.mail import EmailMultiAlternatives # subject 主题 content 内容 to_addr 是一个列表,发送给哪些人 msg = EmailMultiAlternatives('邮件标题', '邮件内容', '发送方', ['接收方']) msg.content_subtype = "html" # 添加附件(可选) msg.attach_file('test.txt') # 发送 msg.send()
备注:send_mail 每次发邮件都会建立一个连接,发多封邮件时建立多个连接。而 send_mass_mail 是建立单个连接发送多封邮件,所以一次性发送多封邮件时 send_mass_mail 要优于 send_mail。
二: 修改文章
前端代码

{% extends 'back/back_base.html' %} {% block home %} <div> <p>修改文章</p> <form action="/add_article/" method="post"> {% csrf_token %} <p>标题</p> <p><input type="text" name="title" class="form-control" id="title" article_id="{{ article_id }}"></p> <p>内容(KindEdit编辑器,不支持拖放/粘贴上传图片)</p> <p> <textarea name="content" id="editor_id" cols="30" rows="10"> </textarea> </p> <input type="submit" class="btn btn-danger" value="提交"> </form> </div> <script charset="utf-8" src="/static/kindeditor/kindeditor-all.js"></script> <script> KindEditor.ready(function (K) { window.editor = K.create('#editor_id', { '100%', height: '500px', //item 控制要显示的控件 //控制控件不能拖动 resizeType: 0, //上传图片,uploadJson 指的是上传的路径,也就是咱们的路由 uploadJson: '/upload_img/', //添加一些额外的参数 extraFileUploadParams: { 'csrfmiddlewaretoken': '{{ csrf_token }}', 'article_id': '1' }, //修改默认上传文件的名字 filePostName: 'myfile' }) }); //当页面加载完成以后,发ajax请求,拿回文章数据 //jquery 的页面加载完成 $(function () { var id = $("#title").attr('article_id') $.ajax({ url: '/get_article/' + '{{ article_id }}', type: 'get', success: function (data) { console.log(data) $("#title").val(data.title) // 设置HTML内容 window.editor.html(data.content); } }) }) /* window.onload = function () { //拿到我隐藏的id var id = $("#title").attr('article_id') $.ajax({ url: '/get_article/' + '{{ article_id }}', type: 'get', success: function (data) { console.log(data) $("#title").val(data.title) // 设置HTML内容 window.editor.html(data.content); } }) } */ </script> {% endblock %}
后台逻辑

@login_required def update_head(request): if request.method=='GET': return render(request,'update_head.html') else: myfile = request.FILES.get('head') # 可以只删除数据库的地址,不删实际文件 user = request.user user.avatar = myfile user.save() # 如果直接这样更新,不会带avatar那个路径,所以不能用这种方式来更新 # ret=models.UserInfo.objects.filter(pk=request.user.pk).update(avatar=myfile) return redirect('/index/') # def update_article(request,pk): # if request.method=='GET': # article=models.Article.objects.get(pk=pk) # return render(request,'back/update_article.html',{'article':article}) def update_article(request,pk): if request.method=='GET': return render(request,'back/update_article2.html',{'article_id':pk}) def get_article(request,pk): article=models.Article.objects.get(pk=pk) return JsonResponse({'title':article.title,'content':article.content})