⼀、圖形驗證碼
1 安裝django-simple-captcha庫
在網站開發的登錄頁面中,經常會需要使用到圖形驗證碼來驗證。在 Django中,django-simple-captcha庫包提供了圖形驗證碼的使用。
$ pip install django-simple-captcha
# 如果安裝有依賴庫問題,請執⾏下⾯的安裝
apt-get -y install libz-dev libjpeg-dev libfreetype6-dev python-dev
2 設置
圖1 安裝應用
圖2. 設置驗證碼樣式
圖3. 設置路由
最后要遷移數據庫:
python manage.py migrate
3 建立表單
# forms.py
from django import forms
from captcha.fields import CaptchaField
class LoginForm(forms.Form):
username = forms.CharField(max_length=20,min_length=3)
password =
forms.CharField(max_length=128,widget=forms.PasswordInput())
captcha = CaptchaField() # 驗證碼字段
4 實現
# 應⽤的urls.py
urlpatterns = [
.....
path('yzm/',views.user_login,name='yzm'),
]
# 前端⻚⾯
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<div>{{ msg }}</div>
<form action="{% url 'App03:yzm' %}" method="post">
{% csrf_token %}
⽤戶:{{ form.username }} <span>{{ form.username.errors.0 }}
</span> <br>
密碼:{{ form.password }} <span>{{ form.password.errors.0 }}
</span><br>
驗證碼:{{ form.captcha }} <span>{{ form.captcha.errors.0 }}
</span><br>
<input type="submit">
</form>
</body>
</html>
<script src="https://cdn.bootcss.com/jquery/1.12.3/jquery.min.js">
</script>
<script>
//點擊刷新驗證碼
$(function () {
$('.captcha').css({
'cursor': 'pointer'
});
// ajax刷新
$('.captcha').click(function () {
console.log('click');
$.get("/app3/refresh/",
function (result) {
$('.captcha').attr('src', result['image_url']);
$('#id_captcha_0').val(result['key'])
});
});
})
</script>
# views.py
import json
from captcha.helpers import captcha_image_url
from captcha.models import CaptchaStore
from django.contrib.auth import authenticate
import django.contrib.auth as auth
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
def user_login(request):
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user =
authenticate(request,username=username,password=password)
if user:
auth.login(request,user)
return redirect(reverse("App03:home"))
else:
form = LoginForm()
# 跳轉登錄⻚⾯
return render(request,'App03/login.html',context={'form':form})
⼆、發送郵件
1.setting配置
# smtp服務的郵箱服務器
EMAIL_HOST = 'smtp.163.com'
# smtp服務固定的端⼝是25
EMAIL_PORT = 25
#發送郵件的郵箱
EMAIL_HOST_USER = 'landmark_cheng@163.com'
#在郵箱中設置的客戶端授權密碼
EMAIL_HOST_PASSWORD = 'q123456'
#收件⼈看到的發件⼈ <此處要和發送郵件的郵箱相同>
EMAIL_FROM = 'python<landmark_cheng@163.com>'
2.發送郵件
#⼀封郵件
from django.core.mail import send_mail
from django.conf import settings
def sendone(request):
send_mail('標題', '內容', settings.EMAIL_FROM,
['313728420@qq.com'])
return HttpResponse("發⼀封郵件")
# 發多封郵件
def sendmany(request):
message1 = ('Subject here', '<b>Here is the message</b>',
settings.EMAIL_FROM, ['313728420@qq.com'])
message2 = ('Subject here', '<b>Here is the message</b>',
settings.EMAIL_FROM, ['313728420@qq.com'])
send_mass_mail((message1,message2), fail_silently=False)
return HttpResponse('發送多封郵件')
#渲染模板進⾏郵件發送
def send_mail(request):
subject, from_email, to = 'html', settings.EMAIL_FROM,
'313728420@qq.com'
html_content =
loader.get_template('active.html').render({'username': '⼩花貓'})
msg = EmailMultiAlternatives(subject, from_email=from_email, to=
[to])
msg.attach_alternative(html_content, "text/html")
msg.send()
return HttpResponse('發送html的⽂件內容')
三、富文本編輯器
一般用於寫文章編輯內容自帶樣式
- 安裝:pip install django-tinymce
- 配置
(1) 配置settings文件
在INSTALL_APPS 添加如下代碼
INSTALLED_APPS = [
...
'App',
'tinymce',
]
在settings.py下添加如下代碼
#富⽂本編輯器的配置
TINYMCE_DEFAULT_CONFIG = {
'theme':'advanced',
'width':600,
'height':400
}
(2) 添加視圖函數
def index(req):
if req.method == 'GET':
return render(req,'index.html')
if req.method == 'POST':
# print(req.POST)
Posts(title=req.POST.get('title'),content=req.POST.get('content')).sa
ve()
return HttpResponse('index')
(3) 前台模板的展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/tiny_mce/tiny_mce.js"></script>
<script>
tinyMCE.init({
'mode':'textareas',
'width':800,
'height':600,
})
</script>
</head>
<body>
<form action="/" method="POST">
{% csrf_token %}
<p>標題 <input type="text" name="title" placeholder="請輸⼊標題"
maxlength="20" required></p>
<textarea name="content" id="" cols="30" rows="10"></textarea>
<input type="submit">
</form>
</body>
</html>
四、文件上傳
使用request.FILES 獲取上傳文件
1.表單注意
- 表單的enctype的值需要設置為:enctype="multipart/form-data
- 表單提交類型為POST
2.存儲路徑
在settings.py文件下添加如下代碼
#設置上傳⽂件路徑
MEDIA_ROOT = os.path.join(BASE_DIR,'static/upload')
3. 文件上傳對象的屬性和方法
名稱 | 說明 |
---|---|
file.name | 獲取上傳的名稱 |
file.size | 獲取上傳大件的大小(字節) |
file.read() | 讀取全部(適用於小⽂件) |
file.chunks() | 按塊來返回文件 通過for循環進行迭代,可以將大⽂ 件按照塊來寫入到服務器 |
file.multiple_chunks() | 判斷文件 是否大於2.5M 返回True或者False |
4.創建上傳文件的表單
- 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/doUpload/" method="post" enctype="multipart/formdata">
{% csrf_token %}
<p>⽂件 <input type="file" name="file"></p>
<p><input type="submit" value=
"上傳"></p>
</form>
</body>
</html>
- views.py
from django.conf import settings
import os
#⽂件上傳處理
def doUpload(req):
file = req.FILES.get('file')
# print(file.name)
# print(file.size)
savePath = os.path.join(settings.MDEIA_ROOT,file.name)
# print(savePath)
with open(savePath,'wb') as f:
# f.write(file.read())
if file.multiple_chunks():
for myf in file.chunks():
f.write(myf)
print('⼤於2.5')
else:
print('⼩於2.5')
f.write(file.read())
return HttpResponse('⽂件上傳')
5.封裝文件上傳類
可以自定義⼀個類實現文件上傳,文件上傳類可以:
- 檢查文件類型
- 檢查文件大小
- 是否生成隨機文件名
import os
from datetime import datetime
from random import randint
class FileUpload:
def __init__(self,file,exts=['png','jpg','jpeg'],size=1024*1024,is_randomname=False):
"""
:param file: ⽂件上傳對象
:param exts: ⽂件類型
:param size: ⽂件⼤⼩,默認1M
:param is_randomname: 是否是隨機⽂件名,默認是否
"""
self.file = file
self.exts = exts
self.size = size
self.is_randomname = is_randomname
#⽂件上傳
def upload(self,dest):
"""
:param dest: ⽂件上傳的⽬標⽬錄
:return:
"""
#1 判斷⽂件類型是否匹配
if not self.check_type():
return -1
#2 判斷⽂件⼤⼩是否符合要求
if not self.check_size():
return -2
#3 如果是隨機⽂件名,要⽣成隨機⽂件名
if self.is_randomname:
self.file_name = self.random_filename()
else:
self.file_name = self.file.name
#4 拼接⽬標⽂件路徑
path = os.path.join(dest,self.file_name)
#5 保存⽂件
self.write_file(path)
return 1
def check_type(self):
ext = os.path.splitext(self.file.name)
if len(ext) > 1:
ext = ext[1].lstrip('.')
if ext in self.exts:
return True
return False
def check_size(self):
if self.size < 0:
return False
#如果⽂件⼤⼩於給定⼤⼩,返回True,否則返回False
return self.file.size <= self.size
def random_filename(self):
filename =
datetime.now().strftime("%Y%m%d%H%M%S")+str(randint(1,10000))
ext = os.path.splitext(self.file.name)
#獲取⽂件后綴
ext = ext[1] if len(ext)>1 else ''
filename += ext
return filename
def write_file(self,path):
with open(path,'wb') as fp:
if self.file.multiple_chunks():
for chunk in self.file.chunks():
fp.write(chunk)
else:
fp.write(self.file.read())
五、站點管理
(1) 配置admin應用
django.contrib.admin
(2) 創建管理員用戶
python3 manage.py createsuperuser
依次輸入用戶名->郵箱->密碼->確認密碼
(3) 漢化
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
(4) 在App/admin.py 里面注冊自己的模型類
from .models import Grade,Students
#注冊模型類 在后台展示
admin.site.register(Grade)
admin.site.register(Students)
(5) 配置后台頁面和添加數據的展示
#配置數據的展示
class GradeAdmin(admin.ModelAdmin):
#設置顯示哪些字段
list_display = ['pk','gname','gboynum','ggirlnum']
#添加搜索字段
search_fields = ['gname']
# 分⻚
list_per_page = 5
# 過濾字段‘
list_filter = ['gname']
class StudentsAdmin(admin.ModelAdmin):
list_display = ['pk','sname','ssex','sage','grade']
search_fields = ['sname']
#分⻚
list_per_page = 5
#過濾字段‘
list_filter = ['sname']
#更改添加 修改的字段屬性的位置
# fields = ['sage','ssex','sname','grade','info']
fieldsets = [
("基本信息",{"fields":['sname','sage','ssex']}),
("其它信息",{'fields':['info','grade']}),
]
#字段順序和字段分組不能同時使⽤
#注冊模型類 在后台展示
admin.site.register(Grade,GradeAdmin)
admin.site.register(Students,StudentsAdmin)
(6) 關聯對象
#TabularInline 橫着展示添加學⽣的布局
#StackedInline 豎着展示添加學⽣的布局
# class AddStudents(admin.TabularInline):
class AddStudents(admin.StackedInline):
class AddStudents(admin.TabularInline):
model = Students #關聯的模型名稱
extra = 2 #添加學⽣的個數
#配置數據的展示
class GradeAdmin(admin.ModelAdmin):
inlines = [AddStudents]
(7) bool值的顯示男女
def sex(self):
if self.ssex:
return '男'
else:
return '⼥'
sex.short_description =
'性別' # 給字段名稱添加簡介(字段的中⽂說明)
# list_display = ['pk','sname','ssex','sage','grade']
list_display = ['pk','sname',sex,'sage','grade']