Django項目BBS博客論壇


BBS 項目開發邏輯梳理

第一步:先進行數據庫設計

數據庫設計規則是:
	1.先創建基表:用戶表、站點表、文章表、標簽表、分類表、文章2標簽第三張關系表、點贊點踩表、評論表
    2.書寫表中的基本含有的字段
    3.添加外鍵(一對一,一對多,多對多)
    4.第三張關系表
注意事項:創建外鍵關系的時候,to='表名',不要忘記引號,null=true,並不是所有的外鍵都加的

第二步settings配置

一定要進行settings的相關配置:
	1.數據庫配置
    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'bbszikao',
        'USER':'root',
        'PASSWORD': 'root',
        'HOST':'127.0.0.1',
        'PORT':3306,
        'CHARSET':'utf8'
    }
}
	
    2.靜態文件資源配置
    STATICFILES_DIRS=[
        os.path.join(BASE_DIR,'static')
    ]
    
    3.models.py文件中,用戶表繼承AbstractUser類,需要對其進行settings配置
    from django.contrib.auth.models import AbstractUser
    配置auth模塊的訪問:
    AUTH_USER_MODEL='app01.Userinfo'
    
    4.靜態圖片資源settings配置+urls路由訪問配置,暴露給用戶查看,用戶注冊可以訪問到默認頭像
    #settings文件配置:
    MEDIA_ROOT=os.path.join(BASE_DIR,'media')
    #urls文件訪問頭像路由配置
    url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),

第三步功能開發

注冊功能

后端開發邏輯:
分為:register函數+register.html+myform.py文件
后端開發邏輯:
# myform.py 文件
	1.建立myform.py文件,利用forms表單,提交注冊的數據信息
    創建class MyRegForm(forms.Form):類
        用戶名,密碼,確認密碼,郵箱
    建立局部鈎子函數校驗用戶名是否存在
    建立全局鈎子函數校驗密碼是否一致
# models.py 文件    
    2.把myform文件中的MyRegForm表單對象拿到,
    然后把form_obj對象發送給前端register.html頁面
    form_obj=myform.MyRegForm()
    return render(request,'register.html',locals())

后端開發邏輯如下:
    把myform文件中的MyRegForm表單對象拿到
    判斷前端發送過來的請求方式是不是post請求
    定義back_dic 字典
    對用戶在前端提交的post數據進行校驗,生成form_obj對象
    如果數據合法:
          獲取鍵值對
          pop掉確認密碼鍵值對
          獲取前端發送的文件請求(avatar),創建文件對象
          判斷用戶是否上傳文件:
              上傳文件了,把avatar添加到clean_data字典對象中
          用戶表創建用戶(create_user)
          back_dic字典添加msg信息,注冊成功
          back_dic字典添加url,login路徑
    
    數據不合法:
          字典添加code=2000  
          字典添加msg=form_obj.errors
    
    返回json數據到前端,[需要導入JsonResponse模塊(from django.http import JsonResponse)]
    
    然后把form_obj對象發送給前端register.html頁面

前端開發邏輯:

上傳頭像文件功能,注冊按鈕功能

前端開發邏輯:register.html文件,前端只整理需要整理的
上傳頭像文件功能
<script>
    //上傳頭像文件相關的處理
    $('#mdd').on('change',function () {
        //利用內置對象filereader完成文件的讀取操作
        let MyFileReader=new FileReader();
        //獲取用戶上傳的文件對象
        let fileobj=$(this)[0].files[0];
        //讓文件閱讀器讀取文件,IO操作,異步
        MyFileReader.readAsDataURL(fileobj);
        //將讀取之后的內容替換到img標簽src屬性中
        MyFileReader.onload=function () {
            $('#img').attr('src',MyFileReader.result)
        }
    });
    
    

        // 注冊按鈕
    $('#submit').click(function () {
        // 將用戶輸入的數據全部發送給后端     普通的鍵值對   文件
        let MyFormData = new FormData();
        // 不停的朝里面添加鍵值對
        {#MyFormData.append('','')#}
        {#console.log($('#myform').serializeArray())#}
        // 普通鍵值對添加完畢 (利用form標簽內部有一個自動序列化普通鍵值對方法)
        $.each($('#myform').serializeArray(),function (index,obj) {
            MyFormData.append(obj.name,obj.value)
        });
        // 手動添加文件數據
        MyFormData.append('avatar',$('#mdd')[0].files[0]);
        // 發送ajax請求
        $.ajax({
            url:'',
            type:'post',
            data:MyFormData,
            // 發送文件一定要指定兩個參數
            processData:false,  // 不要讓瀏覽器處理你的數據
            contentType:false,  // 不要使用任何的編碼  django能夠識別對象自身

            success:function (data) {
                if (data.code == 1000){
                    // 跳轉到登錄頁面
                    window.location.href = data.url
                }else{
                    $.each(data.msg,function (index,obj) {
                        {#console.log(index,obj)#} // index就是報錯字段  obj就是錯誤信息 數組的形式
                        // 獲取報錯字段  手動拼接出該字段所對應的input框的id值
                        let targetId = '#id_' + index;
                        $(targetId).next().text(obj[0]).parent().addClass('has-error')
                    })
                }
            }
        })

    });
    // input框獲取焦點事件,---這個是鼠標放到input框上面后,錯誤信息消失
    $('input').focus(function () {
        $(this).next().text('').parent().removeClass('has-error')
    })

</script>


圖片驗證碼功能

后端開發邏輯

1.所需要的模塊
import random
from PIL import Image,ImageDraw,ImageFont
from io import BytesIO,StringIO
'''
內存管理器模塊:
BytesIO 保存數據,並且在獲取的時候,是以二進制的方式給你
StringIO 保存數據,並且在獲取的時候,是以字符串的方式給你

Image       生成圖片
ImageDraw   在圖片上寫字
ImageFont   控制字的字體樣式

'''
#io_obj=BytesIO()    #你就將該對象看成是文件句柄即可
    '''
 什么是文件句柄???
    在文件I/O中,要從一個文件讀取數據,應用程序首先
    要調用操作系統函數並傳送文件名,並選一個到該文件
    的路徑來打開文件。該函數取回一個順序號,即文件句柄
    (file handle),該文件句柄對於打開的文件是唯一的
    識別依據。要從文件中讀取一塊數據,應用程序需要調用
    函數ReadFile,並將文件句柄在內存中的地址和要拷貝的
    字節數傳送給操作系統。當完成任務后,再通過調用系統函數
    來關閉該文件。”
    '''
2.圖片驗證碼的開發分為兩步:
	隨機取色+圖片驗證碼
    2.1隨機取色
    def get_random():
    	return random.randint(0,255),random.randint(0,255),random.randint(0,255)
    
    2.2圖片驗證碼函數
    	圖片的寬高和隨機取色---生成畫板對象   Image.new
        將生成好的圖片對象交給ImageDraw---畫筆對象   ImageDraw.Draw
        字體樣式	---何種字體   ImageFont.truetype
        #隨機驗證碼	---何種要求(大小寫英文加數字,5位)
        定義code=''
        循環5次:
        	大寫字母		upper_str
            小寫字母		lower_str
            str(隨機數)	 random_int
            
            隨機選取一個,random.choice([大寫,小寫,str(隨機數)])
            往圖片上寫一個驗證碼		img_draw.text
            存儲寫的字				code+=tmp
        將code存到session中,供全局函數訪問			request.session['code']=code
        生成I/O文件句柄							io_obj=BytesIO()	
        圖片對象調用save方法保存io_obj文件對象,png的格式進行保存								img_obj.save(io_obj,'png')
        return HttpResponse(io_obj.getvalue())
        
 --------------------------------------------------------------------------------        
3.圖片驗證碼代碼如下:
def get_code(request):
    # 圖片的寬高和隨機取色        ----畫板
    img_obj=Image.new('RGB',(360,35),get_random())
    #將生成好的圖片對象交給ImageDraw   ---畫筆
    img_draw=ImageDraw.Draw(img_obj)
    #字體樣式                       ---何種字體
    img_font=ImageFont.truetype('static/font/111.ttf',30)
    #隨機驗證碼      ---何種要求(大小寫英文加數字,5位)
    code=''
    for i in range(5):
        upper_str=chr(random.randint(65,90))
        lower_str=chr(random.randint(97,122))
        random_int=str(random.randint(0,9))
        #隨機選取一個
        tmp=random.choice([upper_str,lower_str,random_int])
        #往圖片上寫一個驗證碼
        img_draw.text((i*60+60,0),tmp,get_random(),img_font)
        #存儲寫的字
        code+=tmp
    print(code)
    #這個驗證碼后面其他視圖函數可能要用到,
    #找個地方存一下,並且這個地方全局的視圖函數都能訪問
    request.session['code']=code
    io_obj=BytesIO()    #你就將該對象看成是文件句柄即可
    '''
    在文件I/O中,要從一個文件讀取數據,應用程序首先
    要調用操作系統函數並傳送文件名,並選一個到該文件
    的路徑來打開文件。該函數取回一個順序號,即文件句柄
    (file handle),該文件句柄對於打開的文件是唯一的
    識別依據。要從文件中讀取一塊數據,應用程序需要調用
    函數ReadFile,並將文件句柄在內存中的地址和要拷貝的
    字節數傳送給操作系統。當完成任務后,再通過調用系統函數
    來關閉該文件。”
    '''
    img_obj.save(io_obj,'png')
    return HttpResponse(io_obj.getvalue())

    



圖片驗證碼實時刷新功能

前端開發邏輯

圖片驗證碼隨機變化的邏輯其實很簡單,就是:
    首先為驗證碼綁定點擊事件,
        其次拿到img中的src屬性,
        最后為src設置新的值,使得圖片驗證碼不斷的更換


<div class="col-md-6">
	<img src="/get_code/" alt="" width="360" height="35" id="id_img">
</div>

<script>
    //拿到img中的src,
    //然后為src設置新的值,使得圖片驗證碼不斷的更換
    $('#id_img').click(function () {
        var oldPath = $(this).attr('src');
        $(this).attr('src',oldPath+='?')
    });

</script>

登錄功能

后端開發邏輯

urls.py文件中:
	# 登錄功能
    url(r'^login/',views.login,name='login'),

views.py文件中:
開發邏輯如下:

如果請求方式是post請求:
	定義back_dic
    獲取post請求的用戶名
    獲取post請求的密碼
    獲取post請求的驗證碼
    #先校驗驗證碼是否正確,忽略大小寫
    #再校驗用戶名和密碼是否正確
    如果用戶輸入的驗證碼和后端保存的驗證碼相等:
    	再用auth模塊校驗用戶名和密碼是否相等,生成用戶對象
        如果相等:
        	利用auth模塊保存用戶對象的登錄狀態
            #就可以在任意位置通過request.user獲取到當前登錄對象,並且request.user.is_authenticated()判斷當前用戶是否登錄
            back_dic字典添加msg登錄成功
            back_dic字典添加url,home主頁路徑
        
        如果用戶名和密碼不相等:
        	back_dic字典添加code=2000
            back_dic字典添加msg用戶名或密碼錯誤
    
    如果驗證碼不相等:
    	back_dic字典添加code=3000
        back_dic字典添加msg,驗證碼錯誤
    通過JsonResponse返回字典
 返回到登錄頁面



# 保存用戶登錄狀態,這個不太會,對該知識點模糊要多注意了,
# 通過auth模塊的login方法將用戶保存起來,就可以在任意位置通過request.user,
# 獲取到當前登錄對象,並且可以通過request.user.is_authenticated()判斷當前用戶是否登錄
auth.login(request, user_obj)
auth模塊很重要需要多復習復習

前端開發邏輯

為登錄按鈕綁定點擊事件,
	利用ajax請求,把數據發送到后端
	ajax的固定格式為:
		$.ajax({
			url:'',
			type:'post',
			data:{k,v鍵值對,'csrfmiddlewaretoken':'{{ csrf_token }}'},	
			success:function(data){
				//此處的data就是后端返回過來的back_dic字典對象
				如果code=1000:
					跳轉到對應頁面的url連接
				如果不等於1000:
					渲染錯誤數據信息
					信息錯誤后自動刷新驗證碼
		}

	})

提交post請求跳過csrf中間件攔截的兩種方式:
{% csrf_token %}	------- 在form表單中書寫
'csrfmiddlewaretoken':'{{ csrf_token }}'	------- 在ajax中的data字典中書寫


<div>
    <input type="button" class="btn btn-primary" value="登錄" id="id_submit">
    <span style="color: red;" id="id_error"></span>  //在此處渲染頁面的錯誤信息
</div>

<script>
$('#id_submit').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:{
                //$('#標簽名').val()是獲取當前標簽的值
                'username':$('#id_username').val(),
                'password':$('#id_password').val(),
                'code':$('#id_code').val(),
                'csrfmiddlewaretoken':'{{ csrf_token }}'
            },
            success:function (data) {
                if(data.code == 1000){
                    // 跳轉鏈接
                    window.location.href = data.url
                }else{
                    //渲染錯誤數據信息
                    $('#id_error').text(data.msg);
                    //數據填寫錯誤,提交后驗證碼再次刷新
                    var oldPath = $('#id_img').attr('src');
                    $('#id_img').attr('src',oldPath+='?')

                }
            }
        })
    
</script>

首頁搭建功能

后端開發邏輯

#home主頁
第一步:查詢所有文章,生成文章queryset對象,
第二步:把數據全部提交到home頁面

def home(request):
    #查詢所有文章,生成文章queryset對象,
    #把數據全部提交到home頁面
    article_queryset=models.Article.objects.all()
    return render(request,'home.html',locals())

前端開發邏輯

主頁搭建共分為四塊,
	第一塊,導航條
    第二塊,左側面板	2
    第三塊,中間面板	8
    第四塊,右側面板	2

退出登錄功能

后端開發邏輯

導入auth模塊,導入登錄認證裝飾器:
from django.contrib import auth
from django.shortcuts import reverse
from django.contrib.auth.decorators import login_required
給退出登錄函數添加@login_required裝飾器,裝飾器不要加括號
	利用auth模塊的退出登錄函數			---auth.logout(request)
    返回通過重定向反轉解析到home主頁	  ---redirect(reversed('home'))

    
代碼如下:
@login_required
def logout(request):
    auth.logout(request)
    return redirect(reverse('home'))		---退出登錄之后跳轉到home主頁
    注意事項,此處是reverse,可不要寫成reversed

前端開發邏輯

用戶登錄情況下:
	展示用戶名:
    	拿到用戶的用戶名,------超鏈接;通過auth模塊的is_authenticated判斷用戶是否已經登錄
        
    修改密碼
    修改頭像
    后台管理
    退出登錄
未登錄情況下:
	展示登錄	--超鏈接,反向解析login,{% url 'login' %}
    展示注冊	--超鏈接,反向解析register,{% url 'register' %}
 

部分邏輯代碼如下:
{% if request.user.is_authenticated %}
<li><a href='#'>  {{  request.user.username	}}	</a></li>
    <li><a data-target="#myModal" data-toggle="modal">修改密碼</a></li>
    <li><a href="#">修改頭像</a></li>
    <li><a href="#">后台管理</a></li>
    <li role="separator" class="divider"></li>
    <li><a href="{% url 'logout' %}">退出登錄</a></li>
{% else %}
    <li><a href="{% url 'login' %}">登錄</a></li>
    <li><a href="{% url 'register' %}">注冊</a></li>
{% endif %}

修改密碼功能

后端開發邏輯

urls.py文件中開設修改密碼的路由

url(r'^set_password/',views.set_password,name='set_pwd')

views.py文件
from django.shortcuts import reverse
from django.contrib import auth
from django.contrib.auth.decorators import login_required
首先給修改密碼函數添加裝飾器@login_required
如果前端請求方式是post請求:
	獲取前端發送過來的原密碼old_password
    獲取前端發送過來的新密碼new_password
    獲取前端發送過來的確認密碼confirm_password
    #利用auth模塊先判斷前端發送過來的原密碼是否正確,
    #check_password是auth模塊自帶的校驗密碼是否相等的功能
    request.user.check_password(old_password)
    如果原密碼正確:
    	如果新密碼和確認密碼相等:
            利用auth模塊中的set_password設置新的密碼
            然后利用auth模塊中的save方法進行保存
            返回重定向解析到登錄頁面
        
        如果新密碼和確認密碼不相等:
        	返回文本,兩次密碼不一致
    
    如果原密碼不正確:
    	返回文本,原密碼錯誤
    	

前端開發邏輯

利用form表單,發送post請求
    反向解析到set_pwd路徑下,{% url 'set_pwd' %}
    利用{% csrf_token	%}	跳過csrf中間件
    下面就是form表單中的5個div,分別是:
    	用戶名,使用disable屬性,默認展示用戶名不支持修改
        原密碼
        新密碼
        確認密碼
        取消,修改


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM