zoukankan      html  css  js  c++  java
  • (项目)在线教育平台(十二)

    十七、首页和全局404、500页面配置

    1、首页配置

      首页页面轮播课程需要在课程的model中添加is_banner字段,说明是否是轮播课程:

     1 class Course(models.Model):
     2     """课程"""
     3     DEGREE_CHOICES = (
     4         ('cj', '初级'),
     5         ('zj', '中级'),
     6         ('gj', '高级')
     7     )
     8 
     9     name = models.CharField('课程名', max_length=50)
    10     desc = models.CharField('课程描述', max_length=300)
    11     detail = models.TextField('课程详情')
    12     degree = models.CharField('课程难度', choices=DEGREE_CHOICES, max_length=2)
    13     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
    14     students = models.IntegerField('学习人数', default=0)
    15     fav_nums = models.IntegerField('收藏人数', default=0)
    16     click_nums = models.IntegerField('点击数', default=0)
    17     image = models.ImageField('封面图', upload_to='courses/%Y/%m', max_length=100)
    18     course_org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE, null=True, blank=True)
    19     category = models.CharField('课程类别', max_length=20, default='')
    20     tag = models.CharField('标签', max_length=10, default='')
    21     teacher = models.ForeignKey(Teacher, verbose_name='机构讲师', on_delete=models.CASCADE, null=True, blank=True)
    22     courseneed_know = models.CharField('课程须知', max_length=300, default='')
    23     teacher_tellyou = models.CharField('老师告诉你', max_length=300, default='')
    24     is_banner = models.BooleanField('是否轮播', default=False)
    25     add_time = models.DateTimeField('添加时间', default=datetime.now)
    26 
    27     class Meta:
    28         verbose_name = '课程'
    29         verbose_name_plural = verbose_name
    30 
    31     # 获取章节数
    32     def get_zj_nums(self):
    33         return self.lesson_set.all().count()
    34 
    35     # 获取学习用户
    36     def get_learn_users(self):
    37         return self.usercourse_set.all()[:5]
    38 
    39     # 获取章节
    40     def get_course_lesson(self):
    41         return self.lesson_set.all()
    42 
    43     def __str__(self):
    44         return self.name

      机构显示需要机构标签,在机构的model中添加tag字段:

     1 class CourseOrg(models.Model):
     2     """课程机构"""
     3     CATEGORY_CHOICES = (
     4         ('pxjg', '培训机构'),
     5         ('gx', '高校'),
     6         ('gr', '个人')
     7     )
     8     name = models.CharField('机构名称', max_length=50)
     9     category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
    10     desc = models.TextField('机构描述')
    11     students = models.IntegerField('学习人数', default=0)
    12     course_nums = models.IntegerField('课程数', default=0)
    13     click_nums = models.IntegerField('点击数', default=0)
    14     fav_nums = models.IntegerField('收藏数', default=0)
    15     image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
    16     address = models.CharField('地址', max_length=150)
    17     city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
    18     tag = models.CharField('机构标签', max_length=10, default='全国知名')
    19     add_time = models.DateTimeField('添加时间', default=datetime.now)
    20 
    21     class Meta:
    22         verbose_name = '课程机构'
    23         verbose_name_plural = verbose_name
    24 
    25     # 获取教师数量
    26     def get_teacher_nums(self):
    27         return self.teacher_set.all().count()
    28 
    29     def __str__(self):
    30         return self.name

      迁移数据库。

      首页的数据都是需要从后台获取的,先编写首页的接口:

     1 class IndexView(View):
     2     """首页"""
     3     def get(self, request):
     4         # 轮播图
     5         all_banners = Banner.objects.all().order_by('index')
     6 
     7         # 课程
     8         courses = Course.objects.filter(is_banner=False)[:6]
     9         # 轮播课程
    10         banner_courses = Course.objects.filter(is_banner=True)[:3]
    11 
    12         # 机构
    13         orgs = CourseOrg.objects.all()[:15]
    14         return render(request, 'index.html', {
    15             'all_banners': all_banners,
    16             'courses': courses,
    17             'banner_courses': banner_courses,
    18             'orgs': orgs
    19         })

      然后修改首页的url:

    1 urlpatterns = [
    2     path('', IndexView.as_view(), name='index'),  # 首页
    3 ]

      修改前端首页页面中显示数据的代码:

      1 {% extends 'base.html' %}
      2 
      3 {% load staticfiles %}
      4 
      5 {% block title %}
      6     知能网 - 首页
      7 {% endblock %}
      8 
      9 {% block content %}
     10     <div class="banner">
     11             <div class="wp">
     12                 <div class="fl">
     13                     <div class="imgslide">
     14                         <ul class="imgs">
     15 {#                        遍历显示轮播图#}
     16                             {% for banner in all_banners %}
     17                                 <li>
     18                                     <a href="{{ banner.url }}">
     19                                         <img width="1200" height="478" src="{{ MEDIA_URL }}{{ banner.image }}" />
     20                                     </a>
     21                                 </li>
     22                             {% endfor %}
     23                         </ul>
     24                     </div>
     25                     <div class="unslider-arrow prev"></div>
     26                     <div class="unslider-arrow next"></div>
     27                 </div>
     28 
     29                 </div>
     30 
     31 
     32             </div>
     33 <!--banner end-->
     34 <!--feature start-->
     35     <section>
     36         <div class="wp">
     37             <ul class="feature">
     38                 <li class="feature1">
     39                     <img class="pic" src="/static/images/feature1.png"/>
     40                     <p class="center">专业权威</p>
     41                 </li>
     42                 <li class="feature2">
     43                     <img class="pic" src="/static/images/feature2.png"/>
     44                     <p class="center">课程最新</p>
     45                 </li>
     46                 <li class="feature3">
     47                     <img class="pic" src="/static/images/feature3.png"/>
     48                     <p class="center">名师授课</p>
     49                 </li>
     50                 <li class="feature4">
     51                     <img class="pic" src="/static/images/feature4.png"/>
     52                     <p class="center">数据真实</p>
     53                 </li>
     54             </ul>
     55         </div>
     56     </section>
     57 <!--feature end-->
     58 <!--module1 start-->
     59     <section>
     60         <div class="module">
     61             <div class="wp">
     62                 <h1>公开课程</h1>
     63                 <div class="module1 eachmod">
     64                     <div class="module1_1 left">
     65                         <img width="228" height="614" src="/static/images/module1_1.jpg"/>
     66                         <p class="fisrt_word">名师授课<br/>专业权威</p>
     67                         <a class="more" href="{% url 'course:course_list' %}">查看更多课程 ></a>
     68                     </div>
     69                     <div class="right group_list">
     70                         <div class="module1_2 box">
     71                             <div class="imgslide2">
     72                                 <ul class="imgs">
     73 {#                                遍历显示轮播课程#}
     74                                     {% for banner_course in banner_courses %}
     75                                         <li>
     76                                         <a href="{% url 'course:course_detail' banner_course.id %}">
     77                                             <img width="470" height="300" src="{{ MEDIA_URL }}{{ banner_course.image }}" />
     78                                         </a>
     79                                     </li>
     80                                     {% endfor %}
     81                                 </ul>
     82                             </div>
     83                             <div class="unslider-arrow2 prev"></div>
     84                             <div class="unslider-arrow2 next"></div>
     85                         </div>
     86 {#                        遍历显示课程#}
     87                             {% for course in courses %}
     88                                 <div class="module1_{{ forloop.counter|add:2 }} box">
     89                                 <a href="{% url 'course:course_detail' course.id %}">
     90                                     <img width="233" height="190" src="{{ MEDIA_URL }}{{ course.image }}"/>
     91                                 </a>
     92                                 <div class="des">
     93                                     <a href="{% url 'course:course_detail' course.id %}">
     94                                         <h2 title="{{ course.name }}">{{ course.name }}</h2>
     95                                     </a>
     96                                     <span class="fl">难度:<i class="key">{{ course.get_degree_display }}</i></span>
     97                                     <span class="fr">学习人数:{{ course.students }}</span>
     98                                 </div>
     99                                 <div class="bottom">
    100                                     <span class="fl" title="慕课网">{{ course.course_org.name }}</span>
    101                                     <span class="star fr">{{ course.fav_nums }}</span>
    102                                 </div>
    103                             </div>
    104                             {% endfor %}
    105                     </div>
    106                 </div>
    107             </div>
    108         </div>
    109     </section>
    110     <section>
    111         <div class="module greybg">
    112             <div class="wp">
    113                 <h1>课程机构</h1>
    114                 <div class="module3 eachmod">
    115                     <div class="module3_1 left">
    116                         <img width="228" height="463" src="/static/images/module3_1.jpg"/>
    117                         <p class="fisrt_word">名校来袭<br/>权威认证</p>
    118                         <a class="more" href="{% url 'org:org_list' %}">查看更多机构 ></a>
    119                     </div>
    120                     <div class="right">
    121                         <ul>
    122 {#                        遍历显示机构#}
    123                             {% for org in orgs %}
    124                                 <li class="{% if forloop.counter|divisibleby:5 %}five{% endif %}">
    125                                     <a href="{% url 'org:org_home' org.id %}">
    126                                         <div class="company">
    127                                             <img width="184" height="100" src="{{ MEDIA_URL }}{{ org.image }}"/>
    128                                             <div class="score">
    129                                                 <div class="circle">
    130                                                     <h2>{{ org.tag }}</h2>
    131                                                 </div>
    132                                             </div>
    133                                         </div>
    134                                         <p><span class="key" title="{{ org.name }}">{{ org.name }}</span></p>
    135                                     </a>
    136                                 </li>
    137                             {% endfor %}
    138                         </ul>
    139                     </div>
    140                 </div>
    141             </div>
    142         </div>
    143     </section>
    144 {% endblock %}
    145 
    146 {% block custom_js %}
    147     <script type="text/javascript" src="/static/js/index.js"></script>
    148 {% endblock %}
    index.html

      我们在登出然后登陆之后发现轮播图的数据不见了,需要修改登录接口中render首页的代码:

     1 class LoginView(View):
     2     """登录"""
     3     def get(self, request):
     4         return render(request, 'login.html')
     5 
     6     def post(self, request):
     7         # form实例化
     8         login_form = LoginForm(request.POST)
     9         if login_form.is_valid():
    10             # form验证通过,获取用户提交的用户名和密码
    11             user_name = request.POST.get('username', None)
    12             pass_word = request.POST.get('password', None)
    13 
    14             # 通过django的authenticate方法获取user对象,也就是验证用户是否存在
    15             user = authenticate(username=user_name, password=pass_word)
    16 
    17             if user is not None:
    18                 if user.is_active:
    19                     # 只有激活用户才能登录
    20                     # 验证通过,通过django的login方法去登录,然后返回首页
    21                     login(request, user)
    22                     return HttpResponseRedirect(reverse('index'))
    23                 else:
    24                     # 验证不通过,返回登录页面,并将错误信息返回去显示
    25                     return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
    26             else:
    27                 # 验证不通过,返回登录页面,并将错误信息返回去显示
    28                 return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
    29         else:
    30             return render(request, 'login.html', {'login_form': login_form})

    2、404、500页面配置

      404、500页面,必须在setting.py中设置DEBUG = False:

    1 DEBUG = False
    2 
    3 ALLOWED_HOSTS = ['*']
    4 
    5 # 静态文件
    6 STATIC_URL = '/static/'
    7 STATIC_ROOT = os.path.join(BASE_DIR, 'static')

      在设置DEBUG = False后,django就不会代管你的静态文件,所以要在urls.py文件中设置url处理静态文件的url:

    1 urlpatterns = [
    2     re_path(r'^static/(?P<path>.*)', serve, {"document_root": STATIC_ROOT}),  # 静态文件显示
    3 ]

      然后将404、500页面的html文件放到templates下即可配置完成。

    十八、常见的web攻击与防护

    1、sql注入攻击与防护

    1.1 sql注入攻击的危害

    • 非法读取,篡改,删除数据库中的数据
    • 通过修改数据库来修改网页上的内容
    • 盗取用户的各类敏感信息
    • 注入木马等

    1.2 SQL注入攻击原理

      比如下面一段代码:

     1 class LoginUnsafeView(View):
     2     def get(self, request):
     3         return render(request, "login.html", {})
     4     def post(self, request):
     5         user_name = request.POST.get("username", "")
     6         pass_word = request.POST.get("password", "")
     7 
     8         import MySQLdb
     9         conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='root', db='mxonline', charset='utf8')
    10         cursor = conn.cursor()
    11         sql_select = "select * from users_userprofile where email='{0}' and password='{1}'".format(user_name, pass_word)
    12 
    13         result = cursor.execute(sql_select)
    14         for row in cursor.fetchall():
    15             # 查询到用户
    16             pass
    17         print 'test'

      用户在登录的时候用户名如果输入 ' OR 1=1, 密码随便输入,SQL语句就变成了这样:

      select * from users_userprofile where email='' OR 1=1' and password='123',email='' or 1=1这条件就直接为True了,不用去执行后面的and语句了,那么是不是直接就将用户的信息拿到了呢,所以这种写法是非常危险的。

      那么如何去防护呢?可以尽量不去使用SQL原生语句去获取数据,可以通过django的orm去查询数据,在登录的使用使用django的login函数,这个函数是安全的。

    2、xss攻击与防护

    2.1 xss跨站脚本攻击的危害

    • 控制受害者机器向其他网站发起攻击,注入木马
    • 盗取各类用户账号
    • 非法转账等

    2.2 xss攻击原理

      黑客将一段带有js代码的url发送给用户,用户点击这个url后发送请求到服务器,服务器返回数据给受害者,然后浏览器执行这段js脚本将用户的cookie信息发送给黑客,然后黑客拿着用户的cookie伪装成用户向服务器发送请求,这时黑客就可以进行任何攻击或者其他操作。

    2.3 xss防护

    • 对用户输入的地方和变量都检查长度和对<>;'等字符做一些过滤
    • 不要在cookie中泄露用户的隐私数据,如用户名和密码
    • 将cookie和系统ip绑定来降低cookie泄露后的危险
    • 尽量采用POST方法而非GET提交表单

    3、csrf攻击与防护

    2.1 csrf攻击的危害

    • 以用户的名义去发送邮件
    • 盗取账号
    • 购买商品
    • 虚拟货币转账

    2.2 csrf攻击的原理

      用户登录受信任的A服务器,服务器返回cookie,用户之后的每次请求都会带上cookie去访问A服务器,但是用户在同时的时候没有登出或者关闭A服务器的页面,直接去访问危险的B服务器,然后B服务器要求用户去访问A的一个url,这时信息就会泄露。

    2.3 csrf攻击的防护

      在每个form中加上{{ csrf_token }}即可

  • 相关阅读:
    UML图示与代码对照
    http连接
    http 连接失败重连机制
    httpclient失败重连机制
    mybatis <!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->
    30分钟学会如何使用Shiro(转)
    散列算法与加密算法
    存储过程的优缺点
    mybatis批量更新两种方式:1.修改值全部一样 2.修改每条记录值不一样
    xml解析工具mashaller javaee自带解析类
  • 原文地址:https://www.cnblogs.com/Sweltering/p/10004640.html
Copyright © 2011-2022 走看看