1. 程式人生 > >Django+xadmin打造線上教育平臺(九)

Django+xadmin打造線上教育平臺(九)

目錄

程式碼

十二、首頁和全域性404,500配置

12.1.首頁功能

Course新增一個欄位

is_banner = models.BooleanField('是否輪播',default=False)

CourseOrg新增一個欄位

tag = models.CharField('機構標籤',max_length=10,default='全國知名')

 (1)view

class IndexView(View):
    '''首頁'''
    def get(self,request):
        #輪播圖
        all_banners = Banner.objects.all().order_by('
index') #課程 courses = Course.objects.filter(is_banner=False)[:6] #輪播課程 banner_courses = Course.objects.filter(is_banner=True)[:3] #課程機構 course_orgs = Course.objects.all()[:15] return render(request,'index.html',{ 'all_banners
':all_banners, 'courses':courses, 'banner_courses':banner_courses, 'course_orgs':course_orgs, })

(2)index.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}課程機構列表{% endblock %}

{% block custom_bread %}
{% endblock %}

{% block content %}
    
<div class="banner"> <div class="wp"> <div class="fl"> <div class="imgslide"> <ul class="imgs"> {% for banner in all_banners %} <li> <a href="{{ banner.url }}"> <img width="1200" height="478" src="{{ MEDIA_URL }}{{ banner.image }}" /> </a> </li> {% endfor %} </ul> </div> <div class="unslider-arrow prev"></div> <div class="unslider-arrow next"></div> </div> </div> </div> <!--banner end--> <!--feature start--> <section> <div class="wp"> <ul class="feature"> <li class="feature1"> <img class="pic" src="/static/images/feature1.png"/> <p class="center">專業權威</p> </li> <li class="feature2"> <img class="pic" src="/static/images/feature2.png"/> <p class="center">課程最新</p> </li> <li class="feature3"> <img class="pic" src="/static/images/feature3.png"/> <p class="center">名師授課</p> </li> <li class="feature4"> <img class="pic" src="/static/images/feature4.png"/> <p class="center">資料真實</p> </li> </ul> </div> </section> <!--feature end--> <!--module1 start--> <section> <div class="module"> <div class="wp"> <h1>公開課程</h1> <div class="module1 eachmod"> <div class="module1_1 left"> <img width="228" height="614" src="/static/images/module1_1.jpg"/> <p class="fisrt_word">名師授課<br/>專業權威</p> <a class="more" href="{% url 'course:course_list' %}">檢視更多課程 ></a> </div> <div class="right group_list"> <div class="module1_2 box"> <div class="imgslide2"> <ul class="imgs"> {% for banner_course in banner_courses %} <li> <a href="{% url 'course:course_detail' banner_course.id %}"> <img width="470" height="300" src="{{ MEDIA_URL }}{{ banner_course.image }}" /> </a> </li> {% endfor %} </ul> </div> <div class="unslider-arrow2 prev"></div> <div class="unslider-arrow2 next"></div> </div> {% for course in courses %} <div class="module1_{{ forloop.counter|add:2 }} box"> <a href="{% url 'course:course_detail' course.id %}"> <img width="233" height="190" src="{{ MEDIA_URL }}{{ course.image }}"/> </a> <div class="des"> <a href="{% url 'course:course_detail' course.id %}"> <h2 title="django入門">{{ course.name }}</h2> </a> <span class="fl">難度:<i class="key">{{ course.get_degree_display }}</i></span> <span class="fr">學習人數:{{ course.students }}</span> </div> <div class="bottom"> <span class="fl" title="慕課網">{{ course.course_org.name }}</span> <span class="star fr">{{ course.fav_nums }}</span> </div> </div> {% endfor %} </div> </div> </div> </div> </section> <section> <div class="module greybg"> <div class="wp"> <h1>課程機構</h1> <div class="module3 eachmod"> <div class="module3_1 left"> <img width="228" height="463" src="/static/images/module3_1.jpg"/> <p class="fisrt_word">名校來襲<br/>權威認證</p> <a class="more" href="{% url 'org:org_list' %}">檢視更多機構 ></a> </div> <div class="right"> <ul> {% for org in course_orgs %} <li class="{% if forloop.counter|divisibleby:5 %}five{% endif %}"> <a href="{% url 'org:org_home' org.id %}"> <div class="company"> <img width="184" height="100" src="{{ MEDIA_URL }}{{ org.image }}"/> <div class="score"> <div class="circle"> <h2>{{ org.tag }}</h2> </div> </div> </div> <p><span class="key" title="{{ org.name }}">{{ org.name }}</span></p> </a> </li> {% endfor %} </ul> </div> </div> </div> </div> </section> {% endblock %} {% block custom_js %} <script type="text/javascript" src="{% static 'js/index.js' %}"></script> {% endblock %}

說明1:課程

  • 課程分is_banner=False和is_banner=True,兩種課程的class屬性不一樣
  • is_banner=True的class是  class="module1_2 box"
  • is_banner=True的class是  class="module1_3 box",所以這裡要class="module1_{{ forloop.counter|add:2 }}

說明2:課程機構

  • 課程機構的class分為class=""和class="five"
  • 這裡要做個判斷,class="{% if forloop.counter|divisibleby:5 %}five{% endif %}
  • divisibleby過濾器:能不能整除

說明3:lolgin

  • 當登出在login的時候發現剛才的設定都沒生效,看不到圖片,要改一下login的view
  • 把之前的登入之後用render到‘index.html’改為return HttpResponseRedirect(reverse('index'))
class LoginView(View):
    '''使用者登入'''

    def get(self,request):
        return render(request, 'login.html')

    def post(self,request):
        # 例項化
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            # 獲取使用者提交的使用者名稱和密碼
            user_name = request.POST.get('username', None)
            pass_word = request.POST.get('password', None)
            # 成功返回user物件,失敗None
            user = authenticate(username=user_name, password=pass_word)
            # 如果不是null說明驗證成功
            if user is not None:
                if user.is_active:
                    # 只有註冊啟用才能登入
                    login(request, user)
                    return HttpResponseRedirect(reverse('index'))
                else:
                    return render(request, 'login.html', {'msg': '使用者名稱或密碼錯誤', 'login_form': login_form})
            # 只有當用戶名或密碼不存在時,才返回錯誤資訊到前端
            else:
                return render(request, 'login.html', {'msg': '使用者名稱或密碼錯誤','login_form':login_form})

        # form.is_valid()已經判斷不合法了,所以這裡不需要再返回錯誤資訊到前端了
        else:
            return render(request,'login.html',{'login_form':login_form})
LoginView

12.2.全域性配置404和500

(1)MxOnline/urls.py

from MxOnline.settings import STATIC_ROOT

urlpatterns = [
#靜態檔案
    re_path(r'^static/(?P<path>.*)', serve, {"document_root": STATIC_ROOT }),
]


# 全域性404頁面配置
handler404 = 'users.views.pag_not_found'
# 全域性500頁面配置
handler500 = 'users.views.page_error'

(2)MxOnline/settings.py

DEBUG = False

ALLOWED_HOSTS = ['*']


#靜態檔案
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

(3)users/views.py

from django.shortcuts import render_to_response
def pag_not_found(request):
    # 全域性404處理函式
    response = render_to_response('404.html', {})
    response.status_code = 404
    return response

def page_error(request):
    # 全域性500處理函式
    from django.shortcuts import render_to_response
    response = render_to_response('500.html', {})
    response.status_code = 500
    return response

說明:

  • 404和500,生成環境彙總,必須設定debug = False
  • 一旦debug改為false,django就不會代管你的靜態檔案,所以這裡要設定一個url處理靜態檔案

十三、常見web攻擊與防範

 13.1.sql注入攻擊與防範

sql注入的危害

  • 非法讀取、篡改、刪除資料庫中的資料
  • 盜取使用者的各類敏感資訊,獲取利益
  • 通過修改資料庫來修改網頁上的內容
  • 注入木馬等

sql注入測試程式碼

class LoginUnsafeView(View):
    def get(self, request):
        return render(request, "login.html", {})
    def post(self, request):
        user_name = request.POST.get("username", "")
        pass_word = request.POST.get("password", "")

        import MySQLdb
        conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='root', db='mxonline', charset='utf8')
        cursor = conn.cursor()
        sql_select = "select * from users_userprofile where email='{0}' and password='{1}'".format(user_name, pass_word)

        result = cursor.execute(sql_select)
        for row in cursor.fetchall():
            # 查詢到使用者
            pass
        print 'test'

urls.py
from users.views import LoginUnsafeView urlpatterns = [ url('^login/', LoginUnsafeView.as_view(), name='login'), ]

在login介面輸入使用者名稱:' OR 1=1#     密碼:123

發現可以獲取到我們資料庫裡面的使用者名稱和密碼。

13.2.xss攻擊

xss跨站指令碼攻擊(Cross Site Scripting)的危害

  • 盜取各類使用者賬號,如使用者網銀賬號、各類管理員賬號
  • 盜竊企業重要的具有商業價值的資料
  • 非法轉賬
  • 控制受害者機器向其他網站發起攻擊、注入木馬等等

xss攻擊流程

 

xss攻擊防護

  • 首先程式碼裡對使用者輸入的地方和變數都需要仔細檢查長度和對<>;'等字元做過濾
  • 避免直接在cookie中洩漏使用者隱私,例如email、密碼等
  • 通過使cookie和系統ip繫結來降低cookie洩漏後的危險
  • 儘量採用POST而非GET提交表單

13.3.csrf攻擊

 csrf跨站請求偽造(Cross-site request forgery)的危害

  • 以你的名義傳送郵件
  • 盜取你的賬號
  • 購買商品
  • 虛擬貨幣轉賬

 CSRF攻擊流程:

 CSRF攻擊防範:

  每個form裡面加上 {{csrf_token}}