擴展auth_user欄位、BBS需求分析、創建BBS資料庫、註冊頁面搭建與用戶頭像展示及Ajax提交數據
昨日內容回顧
1. SQL注入
2. xss攻擊
3. csrf跨站請求
4. 密碼加密(加鹽)
'''django中默認有一個中間件來驗證csrf'''
# 只針對post請求才驗證
# 如何解決csrf跨站請求?
1. form表單
{% csrf_token %} # input => name='' => value=''
2. ajax
data:{'csrftokenmiddlewaretoken':''}
data:{'csrftokenmiddlewaretoken':'{{ csrf_token }}'}
# 引入js文件 => 官網拷貝
'''
django的中間件默認驗證所有的方法,那麼如何做到只驗證某部分,不驗證某一部分
'''
# csrf驗證的相關裝飾器
csrf_protect: 需要驗證的時候加這個裝飾器
csrf_exempt: 不需要驗證的時候加這個裝飾器
1. 針對與FBV兩個都可以
2. 針對與CBV:
2.1 對於csrf_protect三種添加方式都可以
2.2 對於csrf_exempt前兩種方式不可以,第三種方式可以
# 1. B端: Auth模組較多 business
# 2. C端:一般不用Auth,幾乎不用 consumer
'''Auth模組要用就全部使用'''
from django.contrib import auth
# 登錄,註冊,驗證登錄,修改密碼,註銷登錄...
user_obj = auth.authenticated(request, username='', password='') # 拿著用戶名和密碼直接去auth_user表中查詢
# 如果查詢到數據,返回的是對象
# 如果查詢數據為空,則返回None
auth.login(request, user_obj) # 保存用戶資訊的,request.session['username']
'''
只要你真行了上述方法,就可以在全局通過request.user屬性拿到用戶資訊
'''
# 註冊
create() # 明文入庫
create_user() # 密文入庫
create_superuser() # 插入的超級管理員
'''
如何生成一個超級管理員:
python3 manage.py createsuperuser => auth_user表中
'''
在訪問admin/路徑的時候,就登錄到django提供的後台管理系統
# 驗證是否登錄
裝飾器:login_required
當你沒有登錄的時候,會自定跳轉登錄頁面,地址/accounts/login/
# 更改登錄的地址?
login_required(login_url='') # 局部修改
# 全局修改
在配置文件中:LOGIN_URL=''
'''局部和全局都存在,那麼就聽局部的'''
# 修改密碼:前提是必須登錄
1. 驗證老密碼是否正確
is_right=request.user.check_password(old_pwd)
2. 驗證兩次密碼是否一致
3. 在操作資料庫進行密碼更改
request.user.set_password(new_pwd) # 這個只是修改了屬性,並沒有操作資料庫
request.user.save() # 才操作資料庫
# 註銷功能:清除session
auth.logout(request)
今日內容概要
- 擴展auth_user表欄位
- 需求分析(仿照部落格園)
- 數據表的創建
內容詳細
1. 擴展auth_user表欄位
# 前提:一般情況,你執行了資料庫遷移命令,就不要在擴展了
要想擴展欄位,最後在遷移資料庫命令之前擴展
如果已經遷移過了,也是可以擴展的,只不過有點麻煩,還有可能容易出錯
# 擴展auth_user表,要繼承Abstractuser類
# 增加資料庫表欄位
1.寫入配置文件:
AUTH_USER_MODEL = 'app01.UserInfo' # 應用名點類名
2.在models.py文件中創建:
from django.contrib.auth .models import AbstractUser
# 如果擴展欄位的話 就不要再繼承models.Model
class UserInfo(AbstractUser):
"""
1.原來已有的欄位不要動
2.只寫自己需要擴展的新欄位
"""
phone = models.CharField(max_length=32)
# 可以上傳任意文件
avatar = models.FileField(upload_to='static/img/', default='static/img/default.png')
# 只能上傳圖片
# avatar = models.ImageField
creat_time = models.DateTimeField(auto_now_add=True)

2. BBS需求分析
# 運營部門,銷售部門 =》 業務部門
# 產品經理 => 原型圖 => 需求評審:測試人員,產品,開發,前端,後端,主管,技術經理
# 什麼時候完成,上線?
# 開發... 提測 => 交給測試人員 => 兩輪測試 => dev, test, release, master
# git
1. 用戶表(擴展auth_user表)
phone
avatar
create_time
# 一對一站點表
blog = OneToOne
2. 站點表
站點名稱
站點標題
站點樣式: css程式碼 => 路徑
3. 標籤表
標題
# 一對多站點表
4. 分類表
分類名稱 # 無限級分類
# 一對多站點表
5. 文章表
標題
簡介
內容
create_time
# 一對多站點表
blog = ForeignKey
# 多對多標籤表
tags = manytomany
# 一對多分類表
cate = ForeignKey
'''優化欄位'''
up_num # 點贊數
down_num # 點踩數
comment_num # 評論數
6. 點贊點踩表
# 哪個用戶點贊了還是點踩了那篇文章
user
article
is_up 0/1
7. 評論表comment
user
article
content
create_time
pid = ForeignKey(to='comment') # 自關聯
pid = ForeignKey(to='self')
'''
根評論和子評論
1. 洋哥很帥
1.1 確實很帥
1.2 男神
'''
id user article content pid(parent_id)
1 1 1 aa 0
2 2 1 bb 1
3 3 1 cc 1
3. 創建數據表
# 創建新的項目BBS, 資料庫bbs
# 修改配置文件settings.py:
寫入:AUTH_USER_MODEL = 'app01.UserInfo'
修改:
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbs',
'USER': 'root',
'PASSWORD': 123,
'HOST': "localhost",
'PORT': 3306,
'CHARSER': "utf8",
}
}
# 任意__init__.py文件寫入:
import pymysql
pymysql.install_as_MySQLdb()
# 在models.py中創建表:
from django.contrib.auth.models import AbstractUser
# 1. 用戶表
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32, verbose_name='手機號')
# 頭像
avatar = models.FileField(upload_to='static/img', default='static/img/default.png')
# 創建時間
create_time = models.DateTimeField(auto_now_add=True)
# 2. 站點表
class Blog(models.Model):
site_name = models.CharField(max_length=64, verbose_name='站點名稱')
site_title = models.CharField(max_length=64, verbose_name='站點標題')
site_style = models.CharField(max_length=64, verbose_name='站點樣式')
# 3. 標籤表
class Tag(models.Model):
title = models.CharField(max_length=64, verbose_name='標籤名稱')
# 4. 分類表
class Category(models.Model):
title = models.CharField(max_length=64, verbose_name='分類名稱')
# 5. 文章表
class Article(models.Model):
title = models.CharField(max_length=128, verbose_name='文章標題')
desc = models.CharField(max_length=512, verbose_name='文章簡介')
content = models.TextField(verbose_name='文章內容')
create_time = models.DateTimeField(auto_now_add=True)
# 外鍵關係
blog = models.ForeignKey(to='Blog')
category = models.ForeignKey(to='Category')
# 多對多
tags = models.ManyToManyField(to='Tag',
through='Article2Tag',
through_fields=('article', 'tag'))
# 優化欄位
up_num = models.IntegerField(verbose_name='點贊數')
down_num = models.IntegerField(verbose_name='點踩數')
comment_num = models.IntegerField(verbose_name='評論數')
class Article2Tag(models.Model):
article = models.ForeignKey(to='Article')
tag = models.ForeignKey(to='Tag')
# 6. 點贊點踩表
class UpAndDown(models.Model):
user = models.ForeignKey(to='UserInfo')
article = models.ForeignKey(to='Article')
# 布爾值:True/False => 資料庫中顯示為: 1/0
is_up = models.BooleanField()
# 7. 評論表
class Comment(models.Model):
user = models.ForeignKey(to='UserInfo')
article = models.ForeignKey(to='Article')
content = models.CharField(max_length=512, verbose_name='評論內容')
create_time = models.DateTimeField(auto_now_add=True)
# parent_id = models.ForeignKey(to='Comment')
parent = models.ForeignKey(to='self')

4. 註冊頁面搭建
# 創建項目下 static目錄
# 配置文件添加:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
# 添加路由:
url(r'^register/', views.register),
# 新建register.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<h1 class="text-center">註冊頁面</h1>
<div class="col-md-8 col-md-offset-2">
<form action="">
<div class="form-group">
<label for="username">用戶名</label>
<input type="text" id="username" class="form-control">
</div>
<div class="form-group">
<label for="username">密碼</label>
<input type="password" id="password" class="form-control">
</div>
<div class="form-group">
<label for="username">確認密碼</label>
<input type="password" id="re_password" class="form-control">
</div>
<div class="form-group">
<label for="email">郵箱</label>
<input type="text" id="email" class="form-control">
</div>
<div class="form-group">
<label for="myfile">
上傳頭像
<img src="/static/img/default.jpg" id="myimg" alt="" width="" style="width: 110px;
margin-left: 15px;">
</label>
<input type="file" id="myfile" style="display: none">
</div>
<input type="button" class="btn btn-success btn-block" value="註冊">
</form>
</div>
</div>
</body>
</html>
# 在views.py文件中搭建:
# 註冊功能
def register(request):
return render(request, 'register.html')


5. 用戶頭像展示事件
# 在body標籤內 添加script標籤:
<script>
$('#myfile').change(function () {
// 1. 藉助於前端的一些插件,文件閱讀器
var myFileRead = new FileReader();
// 2. 讀取文件數據
var myImgObj = $('#myfile')[0].files[0];
{#var myImgObj = $(this)[0].files[0];#}
// 3. 把讀取的圖片交給文件閱讀器
myFileRead.readAsDataURL(myImgObj) // 非同步操作
// 4. 讀取的文件數據地址放大img的src屬性裡面就可以
// attrbiute
myFileRead.onload = function () {
$('#myimg').attr('src', myFileRead.result)
}
})
6. 使用Ajax提交數據
// 提交數據
$('.btn').click(function () {
// 1. 藉助於formdata
var myFormData = new FormData()
// 2. 獲取普通數據
var username = $('#username').val()
var password = $('#password').val()
var re_password = $('#re_password').val()
var email = $('#email').val()
var img = $('#myfile')[0].files[0];
// 2.1 驗證數據
if (!username) {
alert('用戶名必須填寫')
return
}
if (!password) {
alert('密碼必須填寫')
return
}
// 3. 追加數據
myFormData.append('username', username);
myFormData.append('password', password);
myFormData.append('re_password', re_password);
myFormData.append('email', email);
myFormData.append('img', img);
// 提交ajax
$.ajax({
url:'',
type:'post',
data:myFormData,
success:function (res) {
console.log(res)
}
})
})
</script>
</body>
</html>