BBS - 預備知識

1、中介模型

四個項目:
苑昊

博客(BBS) (7-8)

CRM
    1.權限組件 (3)
    2.start組件 -- admin (5)
        1.使用
        2.源碼 django 源碼 (面向對象)
            以源碼爲導師
            使用python最頂頭的人寫出來的
        3.開發相似於源碼的組件
        4.面向對象。。。優勢。。。
    3.crm (4)

路飛學城
    1.vue (3)
    2.rest-framework (4)
    3.路飛學誠

爬蟲
linux
flask

-------------------------------------------------
Book():
    title =
    publish = models.ForeignKey(to='Publish',to_field='id')
    authors = models.manytomany(to='author')

Publish():
    name=
    email=

Author():
    name=

book author
    id  book_id  author_id
     1       1     1

class book2author():
    id=
    book=models.ForeignKey('Book')
    author=models.ForeignKey('Author')
    xxx=models...

book2author
    id  book_id  author_id
     1       1     1

     book_obj = Book.object.filter(pk=1).first()
     book_obj.authors.all()
     book_obj.authors.add(1,2)
     book_obj.authors.set([1,2]) 刷新在插入
                      remove  解除
                      clear   全解除

     若是沒有  // authors = models.manytomany(to='author')
        Book2author.object.create(book_id=1,author_id=2)
        意味着 跨表查詢沒有了  正向查詢按字段 反向查詢按表名
        那若是用字段authors = models.manytomany(to='author'),可是第三張表用本身的!
             authors = models.manytomany(to='author',through="Book2Author")...經過through
             之後跨表查詢就走的是本身建的表,(中介模型)本身建的表(Book2Author叫中介模型)可進行擴展

中介模型:第三張表 能夠create 可不能夠add? 不能夠!!
    Book2author.object.create(book_id=1,author_id=2)
    book_obj.authors.add(1,2) 這個方法就不能使用了!!不然就會報錯 add  set  remove  clear  都不能用了
筆記
中介模型:
只針對 多對多
authors = models.manytomany(to='author')
book_obj.authors.add(1,2)
authors = models.manytomany(to='author',through="Book2Author") # (好處,可擴展)
#(add set remove clear 都不能用了!!)
# 不能使用接口函數!
Book2author.object.create(book_id=1,author_id=2,... )
class Book2Author():
id = ...
book = models.Foreignkey()
author = models.ForeighKey()
xxx = ... # 有可能有多個字段。。擴展

2、簡介

博客系統(cnblog) https://www.cnblogs.com/
預備知識:
1.django ORM (object relation mapping 對象關係映射) 表 = 類 對象 = 記錄
跨表查詢 分組查詢 annotate() 聚合查詢 aggregate(*args, **kwargs)
2.bootstrap
3.Ajax (jquery javascript) --- javascript 去寫ajax 去寫寫
登陸註冊 點贊評論
用框架 底層要會!
4.用戶認證系統!
auth user session 考慮的太多 會報異常!!因此用auth user

實現功能:
1.基於Ajax和用戶認證明現登陸驗證!
--- 驗證碼 圖片 滑動(插件)
登陸 註冊 Ajax

2.基於Ajax和form組件實現註冊功能!

3.系統首頁的佈局
https://www.cnblogs.com/

表關係 第一步:
文章表: 表頭 內容,發佈時間
用戶表: 一對多

4.我的站點頁面設計
https://www.cnblogs.com/wupeiqi
https://www.cnblogs.com/linhaifeng

標籤 分類 歸檔(發佈日期 group by)
分類表:一對多 和文章表
標籤表:多對多 和文章表

5.文章詳細頁面
模板繼承
文章表 content內容很是多,分紅兩張表,不然會每次都查全部的字段;
Artical
id
title ...
desc ...
create_time ...
ad_id = models.OneToOne() 1 / 5
ArticalDetail:
id
content ...
一對一

6.基於Ajax實現文章點贊與踩滅
描述行爲的就是數據;
ArticalUpDown
id
user_id
artical_id
is_up true false
( user_id artical_id 聯合惟一 unqiue_together )
ArticalUpDown.object.create()

7.基於Ajax實現評論框
Comment:
id
user_id
artical_id
create_time
content

對文章的評論和對評論的評論
評論樹:
111
444
555
666
222
333
評論樓:
直接按時間下來的

user
id name
1 alex
2 egon

id user_id artical_id create_time content p_id(記錄父評論)
1 1 2 2012 111 None
2 2 2 2012 222 None
3 3 2 2012 333 None
4 4 2 2012 444 1
5 5 2 2012 555 4
6 6 2 2012 666 1

create Comment():
id = ...
user = models.ForeignKey('User')
artical = models.ForeignKey('Artical')
create_time =
content = ...
pid = models.ForeignKey("selef",null=true,default=None) # 表的自關聯

8.kindeditor 文本編輯器
防止跨域,安全攻擊!發文章 有些<js>惡意攻擊
思路:1.轉義,對文章過濾,<script></script>
beautitulSoup 模塊

表設計:
    Artical
        id
        title
        desc
        create_time
        ad_id = models.OneToOne('ArticalDetail')
        type_id = models.ForeignerKey('Type')
        tag_id = models.ManyToMany('Tag')

    ArticalDetail: 一對一
        id
        content

    User:
        id
        username
        password

    Type 分類表: 一對多
        id
        name

    Tag 標籤表: 多對多
        id
        name

    ArticalUpDown 點贊踩滅表: 聯合惟一  unique(user_id,artical_id)
        id
        user_id = models.ForeignKey('User')
        artical_id = models.ForeignKey('Artical')
        is_up    true/false

    Comment 評論表 注意:對文章的評論和對評論的評論:評論樹,評論樓, 表的自關聯(null=true)
        id
        user_id = models.ForeignKey('User')
        artical_id = models.ForeignKey('Artical')
        create_time
        content
        p_id = models.ForeignKey('self',null=true,default=None)
        #(記錄父評論) None / 1 / 4 / ...
表設計

3、cookie session

cookie session

request.session['key'] = 'value'
request.session.get('key')

必需要知道源碼流程,知其然還要知其因此然

用戶認證組件(基於session)(auth / User)
session:

1.使用
   def login(request):
        if request.method == 'POST':
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')

            user = models.UserInfo.objects.filter(name=user,pwd=pwd).first()
            if user:
                request.session['username'] = user.name
                request.session['user_id'] = user.pk
                return redirect('/index/')
            else:
                return render(request,'login.html')

        return render(request,'login.html')


    def index(request):
        username = request.session.get('username')
        if not username:
            return redirect('/login/',)
        return render(request,'index.html',{'username':username})

2.分析session

django 到了作了什麼,其餘框架沒有session組件!!

request.session['username'] = user.name
0.判斷session_id是否已經存在,存在就更新,不存在就建立
1.obj.set_cookie('session_id','hn9tyjh56msytq8j4tuyffpezb9vfg09')
2.django-session
session-key session-date expire-date
hn9tyj*** {'username':'alex','user_id':1} 2018-06-14 04:05:28.620101

request.session.get('username'):
1.cookie{'session_id':'hn9tyj***'}
2.在django-session表中:
obj = django-session.object.filter(session-key='hn9tyj***'),first()
obj.session-data.get('username)

疑問:
同一個瀏覽器多個用戶登陸:session表裏不會多一個數據,除非換了瀏覽器;
第二次訪問,代碼發生了什麼事情!session表裏,一個瀏覽器一條記錄!
每一個瀏覽器都維持一個cookie !爲何這樣?源碼

第一次瀏覽器訪問,取不出來session_id 就建立,一條記錄 create
第二次瀏覽器訪問,能取出來session_id,就更新,不在是建立 update

3.查看源碼
from django.contrib.sessions.middleware import SessionMiddleware
def process_request(self, request):pass
def process_response(self, request, response):pass

注意:
1.def process_request(self, request):pass
django 有兩個settings
用戶級別 比 系統級別的高,可覆蓋!

from django.contrib.sessions.backends import db
class SessionStore(SessionBase):pass
request.session = self.SessionStore(session_key)

因此:request.session 是一個空對象
能這樣賦值使由於:request.session['username'] = 'alex'
def __getitem__(self, key):
return self._session[key]

def __setitem__(self, key, value):
self._session[key] = value
self.modified = True

結果:獲得一個request.session空對象{}
視圖函數裏賦值:
request.session['username'] = 'alex'

2.def process_response(self, request, response):pass
request.session.save()
obj.save(force_insert=must_create, force_update=not must_create, using=using)
瀏覽器的session_id 有,就更新,沒有,就建立;

總結:
session源碼:
請求:http://127.0.0.1:8080/login post name=alex&pwd=123
第一站:
中間件SessionMiddleWare的process_request

def process_request():
request.session = self.SessionStore(session_key)
_session = {}
_session_cache = {}

第二站:views:
def login(request):
user = request.POST.get('user')
pwd = request.POST.get('pwd')

user = models.UserInfo.objects.filter(name=user,pwd=pwd).first()
if user:
request.session['username'] = user.name
request.session['user_id'] = user.pk
return redirect('/index/')
else:
return render(request,'login.html')

操做:
執行 self.SessionStore(session_key)類下的__setitem__():
self._session_cache = {'username':'alex','user_id',1}

第三站:中間件 SessionMiddleware的process_response():
存儲記錄:
if self._session_key:
self._session_key = 'asdas23213123ssasda'
self.save(must_create=True)

self.save(must_create=False)
寫Cookie
response.set_cookie(
'session_id',
self._session_key,
)

看源碼:理解,學習,使用!!

4.django得流程
瀏覽器 (請求首行 請求頭 請求體) wsgi (http協議整理數據 解析數據) 中間件 url views orm
中間件 process_request process_response process_view process_exception process_template_response

wsgi 功能:1.解析請求的數據,request 以後隨便用
2.響應體 view 返回 字符串,返回瀏覽器 按響應格式返回,不然瀏覽器不識別(響應首行,響應頭)

4、用戶認證組件

python manage.py makemigrations
python manage.py migrate
也能夠:
Tools / Run manage.py Task
makemigrations
migrate

-------------------------

用戶認證組件:

from django.contrib import auth
from django.contrib.auth.models import User

auth
針對 auth_user 表
建立超級用戶:
python manage.py createsuperuser
root root1234
alex alex1234

1.user = auth.authenticate(username=user, password=pwd)
成功返回用戶對象 <class 'django.contrib.auth.models.User'>
失敗返回 None

2.auth.login(request,user)
request.session['user_id'] = user.pk
# request.user = user # 不能用這個 不然多我的 就串了!!
request.user = User.objects.filter(pk=user.pk).first()

就能夠 調用
request.user 匿名對象 / 該用戶對象

3.auth.logout(request)
request.session.flush()

4.from django.contrib.auth.models import User
User.objects.create_user(username=user,password=pwd)
User.objects.create_superuser(username=user,password=pwd,email='123@qq.com')
權限用戶 超級用戶 全部表的全部權限

示例:
from django.shortcuts import render,HttpResponse,redirect
from django.contrib import auth
from django.contrib.auth.models import User

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        user = auth.authenticate(username = user,password=pwd)
        if user:
            auth.login(request,user)
            return redirect('/index/')
    return render(request,'login.html')

def index(request):
    username = request.user.username
    if not request.user.is_authenticated:
    # if not username:
        return redirect('/login/')
    return render(request,'index.html',{'username':username})

def logout(request):
    auth.logout(request)
    return redirect('/login/')

def reg(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        user = User.objects.create_user(username=user,password=pwd)
        auth.login(request,user)
        return redirect('/index/')
    return render(request,'login.html')


?既想用 auth_user 表,還想擴展,表字段如何作呢?

models.py
from django.db import models
from django.contrib.auth.models import User,AbstractUser

# 用類繼承
# userinfo 和 auth_user 合成一張表
# 所以能夠用登陸認證的功能

class UserInfo(AbstractUser):
tel = models.CharField(max_length=32)


# settings配置 若沒有,報錯'UserInfo.groups';
AUTH_USER_MODEL = 'app01.UserInfo'

Tools / Run manage.py Task
makemigrations
migrate

新生成得表 app01_userinfo (能夠用登陸認證的功能)
字段就是 auth_user 和 UserInfo 得合成!!

相關文章
相關標籤/搜索