Django+xadmin打造在线教育平台(九)
目录
代码
教程
学习自慕课网-使用python3.x与Django2.0.1开发的在线教育平台
十二、首页和全局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})
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}}
皮豆设计(logo设计神器):http://pidou.cn